Analytics API

Purpose and Scope

The Analytics API is the public retrieval surface for Dub reporting data. It lets an authenticated caller request analytics for a single link, a domain, or the authenticated workspace, then choose the response family with query parameters. In product terms, this is the API counterpart to the dashboard analytics experience: the same reporting concepts that users see for locations, devices, referrers, top links, and time-series trends are made available as structured JSON for automation, BI ingestion, customer-facing dashboards, or internal reporting workflows.

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

This page focuses on the generated OpenAPI contract that describes analytics retrieval and the utility module that supports analytics export and date/query handling inside the web app. It does not attempt to document the full click ingestion pipeline or Tinybird pipe definitions. Instead, it gives API consumers and maintainers a precise map of the public operation, the supported response categories, and the helper functions that indicate how the application formats and exports analytics data around that API surface.

Sources: apps/web/lib/openapi/analytics/index.ts, apps/web/lib/analytics/utils/index.ts

Dub’s first-party docs describe analytics as a core feature for understanding how audiences interact with links, with breakdowns by location, device, top links, UTM/referrer-style dimensions, and exportable CSV data. The OpenAPI module reflects that positioning by making analytics retrieval a single tagged operation rather than a scattered set of unrelated endpoints. Consumers should think of the API as a parameterized analytics read model: the query selects scope, event, and type, while the response schema changes to match the requested analytics family.

Relevant Source Files

  • apps/web/lib/openapi/analytics/index.ts — Defines the OpenAPI path object for GET /analytics, including operation metadata, query schema wiring, security requirements, response union, and the Analytics tag.
  • apps/web/lib/analytics/utils/index.ts — Re-exports analytics utility functions used by the web application for CSV conversion, query-string editing, export formatting, interval data, and plan-aware date-range validation.

API Operation

The Analytics API is registered as a single OpenAPI path: GET /analytics. The operation has operationId: "retrieveAnalytics" and a Speakeasy name override of retrieve, which is important for generated SDKs because SDK method names often come from these OpenAPI metadata fields. The summary and description both state the same core contract: analytics can be retrieved for a link, a domain, or the authenticated workspace, and the response type depends on the event and type query parameters.

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

Authentication is part of the operation contract. The OpenAPI object declares security: [{ token: [] }], so generated documentation and clients should treat a token as required for analytics retrieval. The path also spreads openApiErrorResponses into the operation responses, which means the success shape is documented locally while shared API error behavior is inherited from the common OpenAPI response module. For maintainers, this keeps the endpoint-specific file focused on analytics semantics while preserving consistent error documentation across API families.

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

The request query is delegated to analyticsQuerySchema, imported from the analytics Zod schema module. That detail matters because this OpenAPI file is not hand-authoring each query parameter; it is wiring an existing runtime/schema definition into OpenAPI generation. When changing valid analytics filters, scopes, date ranges, events, or type selectors, maintainers should update the underlying schema and then verify this operation still produces the intended generated API reference. The OpenAPI layer is therefore a contract assembly point, not the only source of validation behavior.

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

Response Families

The 200 response is declared as Analytics data with application/json content. Its schema is a union of possible analytics outputs, which is the key design detail for consumers. A count request returns a single count-shaped object, while most breakdowns return arrays of records. This matches the practical shape of analytics reporting: a total count is scalar, but time series, location breakdowns, device tables, referrer lists, and top-link leaderboards are naturally collections.

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

The OpenAPI schema names each response variant with an explicit metadata id. The visible response families are AnalyticsCount, AnalyticsTimeseries, AnalyticsContinents, AnalyticsCountries, AnalyticsRegions, AnalyticsCities, AnalyticsDevices, AnalyticsBrowsers, AnalyticsOS, AnalyticsTriggers, AnalyticsReferers, AnalyticsRefererUrls, AnalyticsTopLinks, and AnalyticsTopUrls. These names are especially useful for generated SDKs and reference documentation because they give stable labels to otherwise unioned response shapes.

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

Location analytics are represented by continent, country, region, and city response arrays. Device analytics are represented by device, browser, and operating-system arrays. Traffic-source analytics are represented by referer and referer URL arrays, while link-performance views are represented by top links and top URLs. Trigger analytics is also present, which aligns with dashboard concepts such as distinguishing how tracked events were initiated. When building a client, choose the query type that corresponds to the table or chart you want to render, then narrow the response to the documented family returned for that type.

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

The geolocation dimension has an operational caveat that is easy to miss: official help documentation explains that putting a proxy, such as a Cloudflare proxy, in front of Dub can cause country or city analytics to reflect the proxy’s public IP rather than the end user’s network. That behavior is not special to the OpenAPI schema, but it is important when interpreting AnalyticsCountries or AnalyticsCities results. If location data looks wrong, verify domain DNS/proxy configuration before assuming the retrieval API is returning malformed analytics.

Utility Layer and Export Workflows

The analytics utility barrel re-exports five helper areas: convert-to-csv, edit-query-string, format-analytics-export, get-interval-data, and valid-date-range-for-plan. Even though this file does not show their implementations, the export names reveal how the web app organizes analytics-adjacent behavior. There is a formatting/export path for turning analytics into downloadable CSVs, a query-string editing path for UI/API state, interval-data support for time-series displays, and plan-aware date-range validation for enforcing product limits.

Sources: apps/web/lib/analytics/utils/index.ts

These utilities are relevant to API consumers because they mirror common integration tasks. If you are retrieving analytics to populate your own dashboard, you will need a stable way to translate selected filters into query strings, normalize time intervals for charts, and export tables for spreadsheets or business-intelligence tools. Dub’s hosted dashboard exposes a CSV export flow in the product documentation; the code-level utility names show that CSV conversion and export formatting are first-class concerns in the application layer rather than ad hoc one-off behavior.

Sources: apps/web/lib/analytics/utils/index.ts

Plan-aware validation is also part of the analytics story. Official documentation describes analytics limits by plan and notes that the Analytics API is available on Pro plan and above. The utility export valid-date-range-for-plan indicates that date-window selection is treated as a product-rule concern in the web app. API users should design integrations to request bounded date ranges, handle shared API errors, and surface plan or range failures clearly to end users rather than retrying the same oversized analytics request indefinitely.

Sources: apps/web/lib/analytics/utils/index.ts, apps/web/lib/openapi/analytics/index.ts

System-to-Code Mapping

ConcernSource-level contractReader impact
EndpointGET /analyticsUse one retrieval endpoint for link, domain, or workspace analytics.
Operation nameretrieveAnalytics with SDK override retrieveGenerated clients may expose this as an analytics retrieve method.
Query validationanalyticsQuerySchemaScope, event, type, and filters are schema-driven.
Success responseUnion of analyticsResponse variantsClient code must branch by requested analytics type.
Error behavioropenApiErrorResponsesHandle shared API errors consistently with other Dub endpoints.
Authenticationsecurity: [{ token: [] }]Send a valid API token before requesting analytics.
App utilitiesCSV, query-string, export, interval, and plan-range helpersDashboard/export workflows share analytics support code.

Implementation Details for Maintainers

The OpenAPI module is intentionally small and declarative. It imports shared response definitions, analytics query schemas, analytics response schemas, and Zod OpenAPI types, then builds a retrieveAnalytics operation object. Finally, it exports analyticsPath with the /analytics route mapped to the GET operation. This pattern keeps the generated API reference close to the runtime schema system while avoiding duplicated response definitions inside the path module itself.

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

When adding a new analytics family, maintainers should think through three layers. First, the query schema must allow the selector that asks for the new family. Second, the analytics response schema must expose the new output shape. Third, the OpenAPI union in this file must include the new variant with a clear metadata id so generated documentation and SDKs can name it. If only one layer is updated, the feature may work internally but appear incomplete or ambiguous in the published API contract.

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

When changing export behavior, maintainers should look at the utility exports as the entry point for the app-side analytics workflow. The barrel file makes these helpers easy to import elsewhere in the web app, which is useful but also means changes can have broad UI effects. For example, changing CSV conversion may affect downloaded analytics files, while changing interval data may alter chart rendering expectations. Treat these helpers as part of the practical analytics developer experience, even when they are not themselves public HTTP endpoints.

Sources: apps/web/lib/analytics/utils/index.ts

Practical Usage Guidance

For API clients, start by deciding the scope of the report: link-level analytics for a campaign, domain-level analytics for a branded domain, or workspace-level analytics for an aggregate view. Next, choose the event and type selectors that correspond to the response family you need. A dashboard card showing total events should request the count shape, a chart should request time-series data, and a table should request the relevant breakdown such as countries, devices, browsers, referrers, top links, or top URLs.

Because the response schema is a union, client applications should not parse every analytics response as the same structure. Prefer a small wrapper that records the requested analytics type, calls GET /analytics, and then narrows the JSON result to the expected family. This is especially important for generated SDK users, where the SDK may expose a broad union type. Treat the query as the discriminator in your own application code, even if the raw JSON response does not include a separate discriminator field in the OpenAPI snippet.

When validating analytics results, separate data-quality issues from API-contract issues. A successful country or city response can still be misleading if the tracked domain routes traffic through a proxy before it reaches Dub. A successful export can still be too broad for a user’s plan or selected date range. The OpenAPI operation documents retrieval mechanics; product docs and app utilities explain why date limits, CSV export, and network configuration matter when turning analytics into operational decisions.

Next Steps

Read the broader Analytics Overview to understand how Dub positions analytics across clicks, links, and reporting dimensions. Then use the device, location, referrer, and UTM analytics pages to choose the response families that match your report. If you are implementing against the public API, pair this page with API Authentication and OpenAPI Specs so your client handles tokens, generated method names, response unions, and shared error responses correctly.