Bounties API
Purpose and Scope
The Bounties API is the partner-program review surface for bounty submissions. In Dub terminology, a bounty is a reward mechanism inside a partner program, and a submission is the proof or completion record that may need program-owner review. The API family focuses on three moderation tasks: listing submissions for a bounty, approving a specific submission, and rejecting a specific submission. These operations sit in the broader Dub product area for affiliate programs, where program operators can reward partners for performance goals or submitted proof of work.
Sources: apps/web/lib/openapi/bounties/index.ts, packages/email/src/templates/bounty-new-submission.tsx
This page is written for developers integrating with Dub's public API or maintaining the API documentation layer. It does not describe bounty creation or partner onboarding in depth; instead, it defines the public submission-review contract exposed by the generated OpenAPI paths and connects that contract to the user-facing notifications that happen after review actions. The source mapping is intentionally narrow: the OpenAPI module identifies the route family, while the React Email templates show the operational consequences that users see after new submissions, approvals, and rejections.
Sources: apps/web/lib/openapi/bounties/index.ts, packages/email/src/templates/bounty-approved.tsx, packages/email/src/templates/bounty-rejected.tsx
Relevant Source Files
- apps/web/lib/openapi/bounties/index.ts — Registers the Bounties OpenAPI path family and maps each HTTP method to its operation module: list submissions, approve submission, and reject submission.
- packages/email/src/templates/bounty-approved.tsx — Defines the partner-facing email sent after a bounty submission is confirmed, including payout-oriented copy and a link to partner payouts.
- packages/email/src/templates/bounty-rejected.tsx — Defines the partner-facing email sent after a bounty submission is rejected, including rejection reason, optional rejection note, and a dashboard link.
- packages/email/src/templates/bounty-new-submission.tsx — Defines the workspace-facing email sent when a partner submits proof and the program owner needs to review it.
API Surface
The source-level OpenAPI index exposes exactly three Bounties paths. The collection endpoint, GET /bounties/{bountyId}/submissions, lists submissions for one bounty. Two member-action endpoints, POST /bounties/{bountyId}/submissions/{submissionId}/approve and POST /bounties/{bountyId}/submissions/{submissionId}/reject, perform review decisions on a single submission. This layout makes the bounty identifier the parent resource and the submission identifier the reviewed child resource, which keeps approval and rejection scoped to a specific bounty rather than treating submissions as global objects.
Sources: apps/web/lib/openapi/bounties/index.ts
| Operation | Method and path | Use when | Source mapping |
|---|---|---|---|
| List bounty submissions | GET /bounties/{bountyId}/submissions | A program owner or integration needs the queue or history for a bounty | listBountySubmissions in the bounties path index |
| Approve bounty submission | POST /bounties/{bountyId}/submissions/{submissionId}/approve | A submitted proof or performance result should be confirmed | approveBountySubmission in the bounties path index |
| Reject bounty submission | POST /bounties/{bountyId}/submissions/{submissionId}/reject | A submitted proof should not be accepted | rejectBountySubmission in the bounties path index |
The list operation is the read side of the review workflow. Official API documentation describes it as listing all submissions for a specific bounty in a partner program. The documented path parameter is bountyId, whose values are the unique Dub bounty IDs commonly shown with the bnty_ prefix. The documented query filters include status, groupId, and partnerId, letting consumers narrow results to states such as draft, submitted, approved, or rejected, or to a specific partner or group. The source index confirms this is a GET operation under the Bounties tag.
Sources: apps/web/lib/openapi/bounties/index.ts
The approve operation is a write action on a single submission. Official API documentation names the operation approveBountySubmission and documents the route as accepting both bountyId and submissionId path parameters. It can optionally receive a JSON body with rewardAmount, which is useful when the bounty reward amount is not predetermined or when a custom reward is allowed. The source index confirms that approval is represented as a POST action rather than a general update endpoint, which communicates that approval is a domain event with side effects.
Sources: apps/web/lib/openapi/bounties/index.ts
The reject operation mirrors approval as a member action on the same nested resource shape. Although the supplied OpenAPI index does not include the schema implementation, it establishes the public route and maps the POST /reject endpoint to rejectBountySubmission. The rejection email template shows the information that matters after this decision: a rejection reason is always present, and a rejection note may also be included. That makes rejection more than a boolean state change; it is a communicated decision that should give the partner enough context to understand why the proof was not accepted.
Sources: apps/web/lib/openapi/bounties/index.ts, packages/email/src/templates/bounty-rejected.tsx
Execution Flow
A typical submission-review flow begins when a partner submits proof for a bounty. The NewBountySubmission email template is addressed to the workspace context, not the partner, and says that a bounty has been submitted and requires approval. It renders the bounty name, partner identity, partner email, and a call-to-action that links directly into the Dub dashboard at a program bounty URL with submissionId as a query parameter. That URL shape shows the intended operator experience: the program owner is taken to the bounty page with the relevant submission selected for review.
Sources: packages/email/src/templates/bounty-new-submission.tsx
After the program owner reviews the submission, the API action should be either approval or rejection. Approval leads to a partner-facing message with the preview text Bounty confirmed and a heading that names the program. The approved email states that the commission from the bounty has been added to the upcoming payout and will be sent when the program processes its next payout. This is an important integration signal: approving a bounty is financially meaningful and should be treated carefully by API clients, internal tools, and audit workflows.
Sources: packages/email/src/templates/bounty-approved.tsx
Rejection leads to a different partner-facing message with the preview text Bounty rejected. The template tells the partner that the submitted proof for the named bounty was rejected, displays the rejection reason, optionally displays a rejection note, and says the partner will not be able to submit proof again for the bounty. It also links to the partner dashboard for the program. API clients should therefore present rejection as a final review decision in the user interface unless a later source explicitly introduces a retry or appeal mechanism.
Sources: packages/email/src/templates/bounty-rejected.tsx
Request and Response Reference
Use the Bounties API when an integration needs to operate on submissions, not when it needs to define bounty rules. The parent identifier is bountyId; the child identifier is submissionId for approval and rejection actions. The listing endpoint can be used to build review queues, reconciliation tools, or partner-support dashboards. Approval can optionally include rewardAmount according to the official API documentation, and rejection should provide enough reason information to support the email behavior shown in the template. Keep client-side wording aligned with the domain language: submissions are submitted, approved, rejected, or confirmed.
Sources: apps/web/lib/openapi/bounties/index.ts, packages/email/src/templates/bounty-rejected.tsx
| Field or parameter | Applies to | Meaning |
|---|---|---|
bountyId | All routes | Unique ID of the bounty whose submissions are being listed or reviewed |
submissionId | Approve and reject routes | Unique ID of the bounty submission being reviewed |
status | List route | Optional status filter, documented values include draft, submitted, approved, and rejected |
groupId | List route | Optional group filter for submissions |
partnerId | List route | Optional partner filter for submissions |
rewardAmount | Approve route | Optional custom reward amount for approval when applicable |
rejectionReason | Rejection notification context | Human-readable reason shown to the partner |
rejectionNote | Rejection notification context | Optional additional explanation shown below the reason |
Implementation Details
The OpenAPI module uses ZodOpenApiPathsObject and exports bountiesPaths, which is the composition point consumed by the larger OpenAPI assembly. Each path entry assigns the HTTP method to a separately imported operation object: listBountySubmissions, approveBountySubmission, and rejectBountySubmission. That separation keeps the route table compact while allowing each operation module to define its own parameters, request body, response schema, and documentation metadata. For maintainers, the index is the place to check whether a Bounties route is exposed at all.
Sources: apps/web/lib/openapi/bounties/index.ts
The email templates are implemented as React Email components using @react-email/components primitives such as Html, Head, Preview, Body, Container, Heading, Text, Section, Img, and Link. They import shared branding from @dub/utils, including DUB_WORDMARK, and share the common Footer component. This matters because bounty-review API behavior is coupled to product communications: when developers change route semantics or review state names, they should verify that the corresponding notification copy still describes the actual user outcome.
Sources: packages/email/src/templates/bounty-approved.tsx, packages/email/src/templates/bounty-rejected.tsx, packages/email/src/templates/bounty-new-submission.tsx
The approved template includes the bounty type as either performance or submission and renders a BountyThumbnailImage based on that type. The rejected template does not render a thumbnail but emphasizes the reason and optional note. The new-submission template renders partner identity and falls back to an avatar URL when the partner image is null. These details show that the review workflow has three audiences: the program owner who must review, the accepted partner who expects payout information, and the rejected partner who needs a clear explanation.
Sources: packages/email/src/templates/bounty-approved.tsx, packages/email/src/templates/bounty-rejected.tsx, packages/email/src/templates/bounty-new-submission.tsx
Operational Guidance
When building against these endpoints, start with the list route and filter to submitted submissions when constructing an approval queue. Fetch enough partner and bounty context to let reviewers make an informed decision, then call exactly one member action for the selected submission. Approval should be handled like a payout-affecting event because the partner-facing template says commission is added to the upcoming payout. Rejection should collect clear reason text, and if your workflow supports an additional note, use it to provide specific details rather than repeating the reason.
Sources: packages/email/src/templates/bounty-approved.tsx, packages/email/src/templates/bounty-rejected.tsx
For maintainers extending this API family, keep the route hierarchy consistent with the existing index: bounty-level collections belong under /bounties/{bountyId}, and submission decisions belong under /submissions/{submissionId} as explicit action endpoints. If a new decision state or review action is added, update the OpenAPI path module and audit the notification templates at the same time. The next pages to read are the broader partner-program and commissions documentation, because bounty approval flows into commission and payout expectations for partners.
Sources: apps/web/lib/openapi/bounties/index.ts, packages/email/src/templates/bounty-approved.tsx