Links and Short URLs
Purpose and Scope
A link is Dub's central resource for turning a destination URL into a short, branded URL that can be shared, measured, and managed. In user-facing terms, a short link combines at least three ideas: the destination URL, the short domain, and the key or path segment that identifies the link on that domain. The official product documentation also frames links as analytics objects: teams retrieve performance by individual links and by collections such as folders and tags, which makes link identity important beyond redirect behavior.
Sources: apps/web/lib/openapi/links/index.ts, packages/cli/src/api/links.ts
This page focuses on the source-level surfaces that expose the link model across Dub's API and CLI. It does not attempt to document every schema field, because the supplied source evidence is concentrated around operation registration and exported implementation modules. Instead, it explains how the repository organizes link operations, which public routes exist, how the CLI creates a link through the generated SDK, and how utility modules support consistent link processing across web application workflows.
Sources: apps/web/lib/api/links/index.ts, apps/web/lib/api/links/utils/index.ts
Relevant Source Files
- apps/web/lib/openapi/links/index.ts - Registers the OpenAPI paths for link creation, listing, retrieval by info, counts, single-link mutation, bulk mutation, and upsert behavior.
- apps/web/lib/api/links/index.ts - Re-exports the web application link implementation modules so route handlers and other server-side code can consume a stable link API boundary.
- apps/web/lib/api/links/utils/index.ts - Re-exports link helper modules for tag checks, webhook checks, key validation, key processing, and response transformation.
- packages/cli/src/api/links.ts - Implements the CLI-facing link creation helper by loading local config, constructing the Dub SDK client, and calling
dub.links.create.
Core Link Model
The source evidence shows the link resource through the operations that Dub makes available, rather than through a single class or interface. The OpenAPI router maps /links to post and get, meaning link creation and link listing share the collection route. Additional routes expose counts, link information lookup, single-link update and deletion by linkId, bulk create/update/delete, and upsert. Together these operations define the public lifecycle of a short link: create it, find it, count it, modify it, remove it, or reconcile it idempotently.
Sources: apps/web/lib/openapi/links/index.ts
Short URL composition is visible most clearly in the CLI helper. The CLI's createLink function accepts a destination url and a short-link key, loads saved configuration, and then calls dub.links.create with domain, url, and key. That call shape captures the core model in practical terms: the configured domain chooses where the short link lives, the key chooses the path users will see, and the URL chooses where visitors are redirected after Dub records attribution data.
Sources: packages/cli/src/api/links.ts
The official docs add an important product-level constraint: links are not only redirect records. They are also reporting dimensions. Dub analytics can group results by top links, and the docs describe links data as a way to analyze how individual links and link collections perform across a workspace. That means implementation code has to preserve stable link identity and consistent transformations so the same resource can serve creation, management, redirect, and analytics use cases without becoming separate concepts in different areas of the product.
System-to-Code Mapping
The OpenAPI links module is the clearest public contract boundary. It imports operation definitions such as createLink, getLinks, getLinksCount, getLinkInfo, updateLink, deleteLink, bulkCreateLinks, bulkUpdateLinks, bulkDeleteLinks, and upsertLink, then assigns them to HTTP methods and paths. A reader looking for the canonical route family should start there, because it shows exactly which URL paths are part of the Links API family and which operations share a route.
Sources: apps/web/lib/openapi/links/index.ts
The web application API barrel provides the implementation boundary for non-OpenAPI code. It re-exports modules named archive-link, bulk-create-links, create-link, delete-link, get-links-count, get-links-for-workspace, process-link, update-link, and utils. This shape matters because dashboard code, route handlers, background jobs, or internal services can import link behavior from one place instead of reaching into individual implementation files. The barrel file also shows that processing and archiving are internal concepts alongside user-visible create, update, delete, and count operations.
Sources: apps/web/lib/api/links/index.ts
The utilities barrel narrows the reusable helper layer to link-specific concerns. The exported helpers include tag checks, webhook checks, key checks, key processing, and link transformation. Those names align with Dub's product model: links can be grouped or labeled with tags, can trigger webhooks, need safe and unique keys for their short paths, and often need transformation before being returned to callers. This utility boundary keeps validation and normalization close to the link domain rather than scattering those rules across API endpoints.
Sources: apps/web/lib/api/links/utils/index.ts
API Components
| Component | Source-backed contract | Why it matters |
|---|---|---|
linksPaths | Maps /links, /links/count, /links/info, /links/{linkId}, /links/bulk, and /links/upsert to OpenAPI operations. | Defines the public Links API route family. |
createLink API module | Re-exported by the web link API barrel. | Gives server-side code a stable creation implementation entry point. |
updateLink and deleteLink API modules | Re-exported by the web link API barrel and wired to /links/{linkId} in OpenAPI. | Represent single-link mutation by identifier. |
bulkCreateLinks, bulkUpdateLinks, bulkDeleteLinks | Wired to /links/bulk. | Supports batch workflows where many short links are managed together. |
upsertLink | Wired to PUT /links/upsert. | Supports create-or-update workflows when callers want reconciliation behavior. |
packages/cli/src/api/links.ts:createLink | Calls dub.links.create with domain, url, and key. | Bridges local CLI configuration to the public link creation API. |
The route table also clarifies how to choose an operation. Use POST /links when the caller is creating a new short link, GET /links when listing links, GET /links/count when only an aggregate count is needed, and GET /links/info when resolving information about a link without using the single-link mutation route. Use PATCH /links/{linkId} and DELETE /links/{linkId} when the caller already has a specific link identifier. For large administrative operations, use /links/bulk; for idempotent create-or-update flows, use /links/upsert.
Sources: apps/web/lib/openapi/links/index.ts
Execution Flow
A typical dashboard or API workflow begins with a caller choosing the destination URL and deciding which domain and key should represent the short URL. In the hosted product this may happen through the dashboard, while automation usually reaches the Links API directly. The OpenAPI path registration indicates that creation enters through the /links collection route, where the createLink operation handles the request. Internal implementation modules exported from apps/web/lib/api/links/index.ts then provide reusable create and process steps for the web application boundary.
Sources: apps/web/lib/openapi/links/index.ts, apps/web/lib/api/links/index.ts
The CLI workflow is intentionally thinner. Its helper loads the saved CLI configuration with getConfig, constructs a Dub SDK client using config.access_token, and passes config.domain together with the user-provided url and key to dub.links.create. This means the CLI does not duplicate link validation, persistence, or API route logic. It delegates those responsibilities to the same public API family used by other SDK consumers, while local configuration supplies the workspace-specific domain and authentication context.
Sources: packages/cli/src/api/links.ts
After creation, downstream link behavior depends on the same resource identity. A short link can be listed, counted, updated, deleted, included in bulk operations, or used as an analytics grouping dimension. Official docs about parameter passing also explain that query parameters attached to a short link can be forwarded to the destination URL, with duplicate parameters on the short link overriding destination parameters. That reader-facing behavior depends on stable link processing and transformation inside the link domain, which is why key processing and transform utilities are part of the exported helper layer.
Sources: apps/web/lib/api/links/utils/index.ts
Implementation Details and Constraints
The code organization separates public contract, application implementation, and client convenience. apps/web/lib/openapi/links/index.ts is declarative: it does not implement link behavior, but it assembles the path object consumed by the OpenAPI system. apps/web/lib/api/links/index.ts is an implementation barrel: it collects server-side modules that perform link operations. packages/cli/src/api/links.ts is a client-side convenience wrapper: it turns CLI config plus command input into a SDK call. Keeping these layers separate lets Dub evolve internals without changing every consumer at once.
Sources: apps/web/lib/openapi/links/index.ts, apps/web/lib/api/links/index.ts, packages/cli/src/api/links.ts
Key handling deserves special attention because the key is the visible path portion of a short URL. The utilities export key-checks and process-key, which indicates that Dub treats key validation and normalization as reusable link-domain behavior. Custom domains also matter because official docs encourage teams to choose branded domains for better recognition and click-through rates. The CLI helper reflects this product decision by reading the domain from saved configuration rather than requiring every create call to pass the domain manually.
Sources: apps/web/lib/api/links/utils/index.ts, packages/cli/src/api/links.ts
When extending link behavior, prefer adding or updating implementation modules under the web link API boundary and then exposing new public operations through the OpenAPI path module only when they are intended to become part of the external API. When adding CLI behavior, keep the CLI wrapper small and let the SDK and API enforce the authoritative rules. For adjacent concepts, read the pages on create and manage links, bulk link operations, custom domains, analytics overview, and track events next.