Commissions API

Purpose and Scope

The Commissions API is the API family for creating, retrieving, and changing partner-program earnings records in Dub. A commission is the record that connects an attributed activity to partner earnings: a click, lead, sale, referral, or custom adjustment can become a value that a partner sees in the partner portal and that a program later reconciles into payouts. Dub describes the broader product as an open-source link attribution platform for short links, conversion tracking, and affiliate programs, and commissions are the financial resource that sits at the affiliate-program end of that attribution chain.

This page focuses on the route-level contract exposed by the repository for commission creation, listing, single-record updates, and bulk updates. The OpenAPI source registers a compact path object rather than business logic, so it should be read as the documentation and schema assembly point for API consumers. The email template then supplies runtime semantics: commission records have a type, an event amount, partner earnings, a program, a group holding period, and optionally a short referral link. Together, those two sources show both the external API shape and the partner-facing meaning of the records. Sources: apps/web/lib/openapi/commissions/index.ts, packages/email/src/templates/new-commission-alert-partner.tsx

Relevant Source Files

  • apps/web/lib/openapi/commissions/index.ts — registers the OpenAPI path object for the commissions API family and maps collection, identifier, and bulk routes to imported operation definitions.
  • packages/email/src/templates/new-commission-alert-partner.tsx — renders the partner notification for newly earned commissions and exposes the commission payload concepts used in partner-facing messaging.

System-to-Code Mapping

The commission route registration is intentionally small and declarative. It imports four named operation definitions, then exports a commissionsPaths object typed as ZodOpenApiPathsObject. That tells maintainers where this file participates in the system: it is not a controller, database layer, or payout processor, but the OpenAPI assembly layer used to connect route strings with schema-bearing operations. When generated API documentation or SDK tooling needs to know which operations belong to the commission resource family, this path object is the source-level index for that family. Sources: apps/web/lib/openapi/commissions/index.ts

The path map establishes three API scopes. The collection route supports both creation and listing, so clients use POST /commissions when adding a commission and GET /commissions when retrieving commission history. The identifier route supports a patch operation, which makes it the correct target for changing one known commission. The bulk route also uses patch, but it is collection-scoped, signaling a workflow that applies an update to multiple commission records. This separation is important because finance and partner operations usually need clearer audit boundaries than ordinary content updates.

The email template maps those route-level records to the partner experience. Its props include an email, a program with name, slug, and logo, a group with holdingPeriodDays, a commission with type, amount, and earnings, and an optional shortLink. That shape explains why a commission record cannot be treated as an isolated number. It belongs to a program, may be governed by a partner group’s holding period, may be associated with a referral URL, and has both an event value and the final partner earnings shown in messaging. Sources: packages/email/src/templates/new-commission-alert-partner.tsx

API Reference

OperationMethod and routeSource operationPrimary use
Create commissionPOST /commissionscreateCommissionAdd a commission record for a partner program, including manual or programmatic commission workflows.
List commissionsGET /commissionslistCommissionsRetrieve a paginated commission history for a partner program.
Update commissionPATCH /commissions/{id}updateCommissionChange one commission identified by its id.
Bulk update commissionsPATCH /commissions/bulkbulkUpdateCommissionsApply an update operation across multiple commission records.
Partner alertNewCommissionAlertPartner(...)default email template exportNotify a partner that a commission has been earned and link them to partner earnings.

The official API documentation describes the list operation as a paginated retrieval endpoint for a partner program. It also documents common filters such as commission type, associated customer, associated payout, page, and page size. The commission type filter supports the same vocabulary visible in the template: click, lead, sale, referral, and custom. The documentation further describes advanced type filtering with one value, comma-separated values, or exclusion by prefix. That matches a practical reporting need: finance staff can inspect sales and leads together, isolate custom adjustments, or exclude low-value click commissions from a reconciliation view.

For write operations, the route split gives API clients a decision model before they send data. Use creation when a new attribution-backed earning or manual adjustment should exist. Use the identifier-scoped patch when correcting one known record after review. Use bulk patch only when the workflow is naturally batch-oriented, such as processing a selected set of commissions together. Because the supplied path file delegates details to imported operation modules, clients should still rely on the generated OpenAPI reference for the exact body fields and response schemas, but the repository-level contract makes the operational boundaries clear. Sources: apps/web/lib/openapi/commissions/index.ts

Execution Flow

A typical commission lifecycle begins when a partner drives an attributed action. That action might be a lead signup, a sale, a program referral, a paid click, or a custom award entered by an operator. Once the action is eligible to become partner earnings, a commission can be created through the API or through product workflows that use the same resource concept. The notification template’s conditional copy shows how Dub explains the underlying event: leads are signups, sales are purchases, referrals are joins through a partner referral link, while click and custom commissions receive more general congratulations copy. Sources: packages/email/src/templates/new-commission-alert-partner.tsx

After creation, listing is the main operational read path. Program operators use commission history to inspect date, customer, partner, group, type, sale amount, earnings, and payout context, while integrations use the API to reconcile data against external systems. Pagination matters because commission tables can grow continuously as tracking events arrive. Filtering by type helps separate event categories; filtering by customer or payout helps answer account-specific and finance-specific questions. A robust client should treat listing as a repeatable reconciliation operation rather than a one-time export, especially for programs with active affiliate traffic.

Updates happen after review, correction, or payout operations. A single update is best when a support investigation identifies one commission whose amount, status, or metadata needs correction. A bulk update is more appropriate when a program processes a cohort, such as a group of commissions that are ready for the next lifecycle state. Dub’s help material explains that commissions commonly move from pending to processed when added to a payout, and then to paid when the payout is paid. It also recognizes exceptional outcomes such as refunded, fraud, canceled, and duplicate, so API consumers should design for a lifecycle that can include reversals and disqualifications.

Partner notification is the visible end of the flow. The template builds a preview saying the partner earned a formatted commission amount, optionally mentioning the pretty version of the referral link. It also constructs an earnings URL using the program slug, directing the partner to the partner portal’s earnings page. That means commission writes may have downstream communication and reporting effects. Before an integration creates or updates commissions at scale, it should validate that program slugs, logos, short links, amounts, and earnings values are meaningful to a human partner who may receive email or inspect the same record in the portal. Sources: packages/email/src/templates/new-commission-alert-partner.tsx

Implementation Details and Edge Cases

The template distinguishes amount from earnings, and API clients should preserve that distinction in their own data model. The amount is the underlying event value, such as a purchase amount for a sale. Earnings are the commission value granted to the partner after applying program rules, and that is what the email headline emphasizes. For a sale, the message can mention the formatted purchase amount and separately state the commission earned. For custom commissions or clawbacks, the event amount may not carry the same meaning as a purchase, so clients should avoid assuming every commission is a sale-derived percentage.

Formatting and display are also part of the contract partners experience. The email imports shared utilities for currency formatting, a default Dub wordmark, and pretty URL rendering. Those utilities are not the commission API itself, but they show how raw API values become partner-facing communication. Amounts should be sent and stored as precise machine values, while the application handles display formatting. Logos may fall back when a program logo is unavailable. Referral links may be rendered in a friendlier form while still linking to the full URL. These details reduce surprises when an API response differs from the exact text partners see. Sources: packages/email/src/templates/new-commission-alert-partner.tsx

Holding periods are another edge case for client expectations. The template accepts group.holdingPeriodDays, and Dub’s user-facing help explains that commissions can remain pending for a program-defined period before they are processed into payouts. An integration should therefore avoid treating a newly created commission as immediately payable cash. Reporting views should distinguish earned, processed, and paid states when those fields are available in the detailed schemas. Operationally, this prevents a partner-facing dashboard, accounting export, or payout automation from overstating what is already settled.

Practical Usage Guidance

Start integrations with read-only listing before enabling writes. Listing commissions lets a client learn the program’s real type mix, payout cadence, and data volume without changing financial records. Once the consuming system can page through results and apply type, customer, or payout filters consistently, add create support for the narrow workflows that truly require external creation, such as manual bonuses, imported historical commissions, or corrections from another billing system. Keep logs of request bodies and returned identifiers so later single-record patches can be tied to the original operational reason.

For update workflows, prefer the narrowest route that solves the task. If one commission is wrong, patch that one identifier. If many records need the same transition, use the bulk route as an explicit batch operation and require stronger safeguards, such as a dry-run export, operator confirmation, and clear rollback procedures. Commissions are part of a financial workflow and can affect partner trust, payouts, emails, and program analytics. Treat them as ledger-adjacent resources even when the API ergonomics look like ordinary REST updates. Sources: apps/web/lib/openapi/commissions/index.ts

Next, read the broader commissions and payouts material to understand lifecycle status, then review the payouts API for settlement workflows and the partner-program pages for how partners, groups, links, and programs interact. If you are maintaining the OpenAPI surface, use the commissions path file to confirm route registration and operation naming, then inspect the imported operation modules for field-level schemas before changing generated documentation or SDK behavior.