Links API Overview
Purpose and Scope
The Links API family is the central resource surface for Dub’s short-link product. A link represents the destination URL, short domain, key, metadata, and operational behavior that make a Dub short URL usable across attribution, analytics, and conversion workflows. This page orients API readers around the repository modules that assemble the Links OpenAPI routes and the server-side link utilities that back the implementation. It is intentionally an overview rather than a field-by-field schema reference: use it to understand which operations belong to the Links family, how they are grouped, and where to continue for create, update, bulk, and count details.
Sources: apps/web/lib/openapi/links/index.ts, apps/web/lib/api/links/index.ts, apps/web/lib/api/links/utils/index.ts
Dub’s public documentation describes the product as a modern open-source link attribution platform for short links, conversion tracking, and affiliate programs. In that product model, the link is not just a redirect shortcut. It is also the anchor for campaign analysis, link previews, tags, folders, webhook behavior, and the event data that later appears in analytics. The official analytics docs describe link data as a way to analyze individual links and link collections across a workspace. The source files here show the API side of that same model: one module registers the HTTP paths, while adjacent implementation modules export the link operations and lower-level utility functions.
Relevant Source Files
- apps/web/lib/openapi/links/index.ts — Registers the OpenAPI path object for the Links API family, mapping public HTTP paths such as
/links,/links/count,/links/info,/links/{linkId},/links/bulk, and/links/upsertto their operation definitions. - apps/web/lib/api/links/index.ts — Re-exports the server-side link API implementation modules, including create, archive, delete, bulk create, count, workspace listing, processing, update, and utilities.
- apps/web/lib/api/links/utils/index.ts — Re-exports shared link utility modules for tag checks, webhook checks, key validation, key processing, and link transformation.
Public Route Family
The OpenAPI registry exposes the Links family through a compact set of route groups rather than a separate top-level namespace for every action. The base /links path supports creation with POST and listing with GET, which matches the usual lifecycle entry points for a resource collection. A caller creates a link when it has a destination and optional short-link parameters, then lists links when it needs a workspace view for dashboards, automation, or synchronization. The registry also exposes /links/count, giving clients a count-oriented operation without forcing them to retrieve full link objects when they only need totals.
The same registry separates informational lookup and identifier-based mutation. /links/info is a GET operation mapped to the getLinkInfo OpenAPI definition, making it a read-only endpoint for resolving link details without using the collection listing shape. /links/{linkId} groups PATCH and DELETE for updating or deleting a specific existing link. This is a familiar REST pattern: the collection route handles creation and discovery, while the item route handles changes to an addressed resource. The route names also make clear that update and delete are distinct OpenAPI operations, even though they share the same parameterized path.
Bulk and idempotent workflows receive their own routes. /links/bulk supports POST, PATCH, and DELETE, corresponding to bulk create, bulk update, and bulk delete operations. Official API docs for bulk creation describe creating up to one hundred links for the authenticated workspace and warn that webhook events are not currently sent for bulk link creation. The OpenAPI registry confirms that bulk actions are collected under one route with separate methods, which helps SDK generators expose related bulk operations consistently. /links/upsert is registered with PUT, signaling a create-or-update workflow distinct from ordinary creation or patching.
System-to-Code Mapping
The Links API is assembled in two layers visible from the supplied source. The OpenAPI layer imports individual operation definitions and combines them into one linksPaths object typed as ZodOpenApiPathsObject. That object is the public documentation and schema assembly point: each key is an HTTP route, and each method points to a prebuilt operation definition such as createLink, getLinks, bulkUpdateLinks, or upsertLink. Because this file is declarative, it is the best place to answer the question, “Which Links endpoints exist in the generated API reference?”
The implementation barrel in the API directory answers a different question: “Which link behavior modules are part of the server-side link subsystem?” It re-exports modules for archive, bulk create, create, delete, count retrieval, workspace listing, processing, update, and utilities. A barrel export does not itself implement business logic, but it defines the public import surface used elsewhere in the application. That matters in a large Next.js monorepo because route handlers, jobs, dashboard code, and other services can import link behaviors from one stable package path instead of knowing every internal file location.
The utility barrel adds a third layer focused on reusable link rules. Its exports are named around tag checks, webhook checks, key checks, key processing, and link transformation. These names describe responsibilities that are orthogonal to any single route. For example, creating and updating links both need consistent key handling, and bulk workflows need the same validation principles as single-link workflows. Keeping these utilities under a dedicated module makes the link subsystem easier to evolve: public route definitions can stay stable while validation, transformation, and side-effect checks are shared beneath them.
Route Reference
| Route | Methods | Registered operation names | Intended use |
|---|---|---|---|
/links | POST, GET | createLink, getLinks | Create a new link or list links in the authenticated workspace context. |
/links/count | GET | getLinksCount | Retrieve a count of matching links without fetching a full list payload. |
/links/info | GET | getLinkInfo | Retrieve informational details for a link lookup flow. |
/links/{linkId} | PATCH, DELETE | updateLink, deleteLink | Modify or remove a specific link by identifier. |
/links/bulk | POST, PATCH, DELETE | bulkCreateLinks, bulkUpdateLinks, bulkDeleteLinks | Perform batch create, update, or delete workflows. |
/links/upsert | PUT | upsertLink | Create or update a link using an idempotent-style operation. |
Execution Flow
A typical generated API flow starts with the OpenAPI path map. The application-level OpenAPI assembly imports linksPaths and merges it with other API families, allowing documentation and SDK tooling to discover the full Links surface. A client then calls one of the documented routes, such as creating through the collection route or updating through the identifier route. The operation definition connected to that route supplies the method-level contract, including summary, parameters, request body, response shape, and validation metadata. Although the individual operation files are outside this page’s source evidence, the registry shows the complete set of operation entry points.
At runtime, the corresponding server implementation can use the exports from the link API barrel. Create flows are expected to pass through link processing and key-related utilities because a short link needs a valid domain and key combination before it can be stored or returned. Listing and count flows share filtering concepts but optimize for different response needs: a list returns link records, while a count returns an aggregate number. Update and delete flows act on an existing link identity, and bulk flows repeat similar validation and transformation concerns across multiple requested records.
The utility exports point to important edge cases for API consumers and maintainers. Key checks and key processing imply that caller-provided slugs are not treated as arbitrary strings; they must be normalized and validated so generated short URLs remain safe and unique in context. Tag checks imply that links may be associated with tagging metadata and that operations need to confirm those associations before applying changes. Webhook checks imply that some link actions can trigger integration side effects, while other actions, such as the documented bulk creation exception, may intentionally avoid webhook emission. Transform utilities imply a boundary between database-shaped records and API-shaped responses.
API Design Notes and Edge Cases
When integrating with the Links API, choose the narrowest route that matches the task. Use creation on the collection route when the caller is intentionally adding a new short link. Use the list route for dashboards, synchronization jobs, or administrative views that need many links. Use the count route when pagination controls or quota displays need a number but not full link data. Use the info route when the workflow is a lookup rather than a workspace list. Use the item route for ordinary edits and deletion, and reserve the bulk route for batch tools where the client can prepare multiple link inputs at once.
The difference between update and upsert is especially important for automation. A normal update is addressed to an existing link identifier and should be used when the caller has already resolved the target. An upsert route is modeled separately because automation often wants a desired final state: if a link already exists, align it with the requested fields; if it does not, create it. The registry’s use of PUT for /links/upsert reinforces that this is not merely another patch endpoint. It is a separate operation with a separate contract and should be documented, tested, and handled distinctly in SDKs.
Bulk routes should be treated as operational tools rather than replacements for every single-link request. They are valuable for imports, migrations, workspace cleanup, and campaign setup because they reduce repeated HTTP overhead and let clients submit grouped changes. However, bulk operations also concentrate validation failures, partial-state questions, and integration side-effect concerns. The official warning that bulk link creation currently does not send webhook events is a practical example: consumers that rely on webhooks for downstream synchronization may need to trigger their own follow-up reconciliation after a bulk create workflow. That behavior should influence integration design.
Related Pages and Next Steps
After reading this overview, continue with the operation-specific Links API pages when implementing a client. The create, retrieve, and list page should be the next stop for basic link management, because it expands the collection and lookup operations. The update, upsert, and delete page is the right follow-up for lifecycle changes and idempotent automation. The bulk links and counts page should be used for migration scripts, import tools, and dashboard pagination. For product context, pair this page with Links and Short URLs, Link Attribution, and Analytics Overview so API behavior is connected to how Dub reports performance by individual links, folders, and tags.
For maintainers, the main code navigation rule is simple: start at the OpenAPI registry to confirm the public route, then move to the API barrel to find the implementation family, then inspect the utility exports when behavior depends on keys, tags, webhooks, or response transformation. This path keeps documentation updates aligned with source changes. If a new link operation is added, it should appear in the OpenAPI path object for public documentation and in the implementation exports if other application modules need to call it. If a validation rule changes, the shared utility layer is the likely place to look first.