Track Leads, Sales, and Opens

Purpose and Scope

Use this page when you need to send conversion or mobile deep-link activity into Dub and then understand how those events appear in the API surface. In Dub terminology, a tracked event connects a user action back to the short-link and attribution context that brought the user there. The Track API is the write side for conversion-style activity: lead events, sale events, and deep-link open events are registered as POST endpoints in the OpenAPI path map. The Events API is the read side for inspecting tracked activity in an authenticated workspace.

Sources: apps/web/lib/openapi/track/index.ts, apps/web/lib/openapi/events/index.ts

Dub’s first-party product framing treats conversion tracking as a core part of the link attribution platform: clicks are the entry point, while leads and sales represent downstream outcomes. A lead indicates meaningful interest, such as a signup, demo booking, or another qualified action. A sale indicates a purchase or revenue event. A deep-link open is distinct: it records that a user opened an iOS or Android app via a Dub-powered deep link, including deferred deep-linking cases where Dub may associate the open with a previous click.

The repository evidence for this page sits at the OpenAPI assembly layer rather than at the endpoint implementation layer. That is still important for integrators because it shows the public contract families exposed to generated API documentation and SDK tooling. trackPaths declares the three write endpoints under the Track API family, and eventsPath declares the paginated event listing endpoint under the Events API family. Together, these modules define the external shape that developers see when wiring server-side tracking, mobile deep-link tracking, or reporting workflows.

Relevant Source Files

  • apps/web/lib/openapi/track/index.ts — Defines the Track OpenAPI path object and maps POST /track/lead, POST /track/sale, and POST /track/open to their operation definitions.
  • apps/web/lib/openapi/events/index.ts — Defines GET /events as the authenticated event listing operation and describes its response as a discriminated union of click, lead, and sale event response schemas.

Core Tracking Primitives

The first primitive is the lead event. In product terms, a lead is an action that indicates interest in a product or service. The official conversion docs call out ordinary examples such as account signup, demo booking, or mailing-list subscription, and also more qualified examples such as completing a first meeting, making a first query, or reaching a usage milestone. The OpenAPI map exposes this write path as POST /track/lead, which means lead creation belongs to the Track family rather than the general Events listing family.

The second primitive is the sale event. A sale represents a purchase or revenue-producing action, such as subscribing to a paid plan, upgrading usage, or purchasing a product. Dub’s official docs distinguish direct sale tracking from funnels that also track leads: direct sale tracking attributes a sale directly to a click without requiring a prior lead event. In the repository OpenAPI map, sale tracking is exposed as POST /track/sale, alongside lead and open tracking, making it part of the same conversion ingestion surface.

The third primitive is the deep-link open event. Official API docs describe POST /track/open as the endpoint used when a user opens an app through a Dub-powered deep link on iOS or Android. The documented request can include deepLink, the deep link that brought the user to the app, and dubDomain, the deep-link custom domain used for probabilistic tracking when deepLink is absent. This is a mobile attribution primitive rather than a revenue primitive, but it still belongs in Track because it records an externally observed user action.

Sources: apps/web/lib/openapi/track/index.ts

System-to-Code Mapping

The Track API module is intentionally small and compositional. It imports trackLead, trackSale, and trackOpen from sibling operation modules, then exports a ZodOpenApiPathsObject named trackPaths. That object maps each public route string to an HTTP method object. The structure is direct: "/track/lead" has a post operation, "/track/sale" has a post operation, and "/track/open" has a post operation. This pattern lets the broader OpenAPI generator assemble endpoint families without each endpoint needing to know about the whole specification.

The Events API module serves a different role. It exports listEvents, a ZodOpenApiOperationObject with operationId: "listEvents", a Speakeasy SDK naming override of "list", the summary "List all events", and a description that the operation retrieves a paginated list of events for the authenticated workspace. It accepts query parameters through eventsQuerySchema and returns an array whose items are discriminated by the event field across click, lead, and sale response schemas. That gives reporting consumers one endpoint for reading mixed event streams.

A useful distinction for implementers is that tracking endpoints record events, while the events endpoint lists already-recorded activity. The Track path map does not show authentication requirements in the supplied snippet, and the official deep-link open OpenAPI excerpt explicitly has no security requirement for POST /track/open. By contrast, GET /events includes security: [{ token: [] }], so event listing is part of the authenticated workspace API. Treat writes and reads as separate integration concerns: send tracking payloads from the correct runtime, then use authenticated API access for inspection and reconciliation.

Sources: apps/web/lib/openapi/track/index.ts, apps/web/lib/openapi/events/index.ts

Execution Flow

A typical lead-tracking flow starts when your application decides that a user has crossed the threshold for a meaningful lead. That threshold is product-specific: it may be signup for a simple funnel or a later sales-qualified milestone for a more selective affiliate program. At that point, your backend sends a request to POST /track/lead. Dub then has enough information, according to the operation definition imported by the OpenAPI path map, to treat the request as a Track-family conversion write rather than as an analytics query or dashboard-only action.

A sale-tracking flow is similar but should be tied to durable purchase state. Send the sale event when your payment system confirms a transaction, subscription, upgrade, or other revenue event. Official guidance for direct sale tracking emphasizes the case where no prior lead is needed, which is useful for one-time purchases or funnels where the purchase itself is the first meaningful conversion. If your funnel uses both leads and sales, keep the semantics consistent: lead for qualified interest, sale for revenue, and list events later to verify what was attributed.

A deep-link open flow usually runs from a mobile app or mobile-aware backend path. When the app opens through a Dub-powered deep link, call POST /track/open. If the concrete deep link is available, include it as deepLink. If not, the official docs describe using dubDomain so Dub can attempt probabilistic tracking against a prior click from the same user context. This endpoint is especially relevant to deferred deep linking, where the user may click before installation and open the app later.

After writes are flowing, use GET /events for operational validation and reporting. The OpenAPI operation describes a paginated authenticated workspace listing, not a tracking write endpoint. Its response schema explicitly covers click, lead, and sale event variants through a discriminated union, which is useful for consumers building dashboards, exports, or reconciliation jobs. Deep-link opens are represented in the Track family, while the supplied Events response evidence shows the listing contract for click, lead, and sale event records.

Sources: apps/web/lib/openapi/events/index.ts

Compact API Reference

API familyRouteMethodPurposeSource mapping
Track/track/leadPOSTRecord a lead conversion event.trackPaths["/track/lead"].post = trackLead
Track/track/salePOSTRecord a sale conversion event.trackPaths["/track/sale"].post = trackSale
Track/track/openPOSTRecord an app open from a Dub-powered deep link.trackPaths["/track/open"].post = trackOpen
Events/eventsGETList paginated events for an authenticated workspace.eventsPath["/events"].get = listEvents

For generated clients and API reference pages, the operation names and tags matter. listEvents carries operationId: "listEvents", x-speakeasy-name-override: "list", and the tag Events, which helps SDK generators expose a concise event-listing method. The Track index does not define the operation metadata inline; instead, it composes imported operation objects for lead, sale, and open. When changing any tracking endpoint, update the operation module and confirm the index still maps the public route to the correct method.

Practical Integration Guidance

For server-side lead and sale tracking, prefer sending events from trusted backend code after your application has confirmed the user action. This avoids firing duplicate conversions from page reloads or untrusted clients and lets you align event timing with business rules such as qualification, payment confirmation, or refund handling. For mobile deep-link opens, call the open endpoint at app-open time and include the deepest available attribution signal. The official docs indicate that deepLink is preferred when known, while dubDomain supports probabilistic fallback for deferred deep linking.

When validating an integration, do not treat event ingestion and event listing as the same contract. The Track endpoints are designed around recording specific actions. The Events endpoint is designed around authenticated retrieval and returns a mixed event stream containing click, lead, and sale records. A good test plan sends one event from each integration path, checks idempotency or duplicate handling in the endpoint-specific docs, and then uses GET /events to confirm that the expected lead and sale records appear in the workspace event stream.

Next, read the Track API reference for exact request payloads and error shapes, then pair it with conversion-tracking concept docs so your product events match Dub’s attribution model. If you are implementing reporting, continue to the Analytics API and Events-related pages rather than calling Track endpoints for read behavior. If you are implementing affiliate programs, coordinate lead and sale semantics with commission and payout workflows so partner rewards follow the same conversion definitions your application sends to Dub.