> ## Documentation Index
> Fetch the complete documentation index at: https://docs.affixo.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Quote a commission

> What an affiliate would earn on a sale, without recording it. The quote runs the real commission engine on a simulated sale and then discards it, so it follows the affiliate's rate override, product and billing interval rules, the campaign default and holds. Nothing is written, emailed or paid. Requires `read` scope.

A quote that would be held says so in `hold_reason_label`. Reasons that come from your own settings are named (for example a pending affiliate or an amount threshold); any other reason reads "Would be held for review".

Limits: 60 quotes a minute per workspace, 500 a day per user, and 2,000 a day per workspace (dashboard and API together). Calls made with API keys count as one user per workspace. Going over any of them returns `429 rate_limited` with a message saying which limit you hit and when to try again.



## OpenAPI

````yaml /openapi.yaml post /v1/commissions/quote
openapi: 3.1.0
info:
  title: Affixo API
  version: 1.0.0
  description: |
    The Affixo REST API for affiliate program management and server-to-server
    conversion tracking.

    All requests authenticate with a workspace key (`sa_live_…`) as a Bearer
    token. Scopes: `read` / `write` / `track` / `*`.
servers:
  - url: https://go.affixo.dev
    description: Production
security: []
tags:
  - name: Affiliates
    description: Manage affiliates (workspace key)
  - name: Campaigns
    description: Create and configure campaigns + commission rules (workspace key)
  - name: Links
    description: Manage referral links (workspace key)
  - name: Risk
    description: AI risk assessments for fraud triage (workspace key)
  - name: Commissions
    description: Approve, deny, and manage commissions (workspace key)
  - name: Conversions
    description: Re-attribute and manage conversions (workspace key)
  - name: Webhooks
    description: Manage webhook endpoint subscriptions (workspace key)
  - name: Reports
    description: Aggregated reporting data (workspace key)
  - name: Resources
    description: Read campaigns, commissions, conversions, payouts (workspace key)
  - name: Referrals
    description: >-
      Move a referred customer to another affiliate, and send test referrals
      (workspace key)
  - name: Tracking
    description: >-
      Server-to-server click & conversion tracking (workspace key, scope
      "track")
  - name: Products
    description: >-
      Your Stripe product catalog and which products earn commission (workspace
      key)
paths:
  /v1/commissions/quote:
    post:
      tags:
        - Commissions
      summary: Quote a commission
      description: >-
        What an affiliate would earn on a sale, without recording it. The quote
        runs the real commission engine on a simulated sale and then discards
        it, so it follows the affiliate's rate override, product and billing
        interval rules, the campaign default and holds. Nothing is written,
        emailed or paid. Requires `read` scope.


        A quote that would be held says so in `hold_reason_label`. Reasons that
        come from your own settings are named (for example a pending affiliate
        or an amount threshold); any other reason reads "Would be held for
        review".


        Limits: 60 quotes a minute per workspace, 500 a day per user, and 2,000
        a day per workspace (dashboard and API together). Calls made with API
        keys count as one user per workspace. Going over any of them returns
        `429 rate_limited` with a message saying which limit you hit and when to
        try again.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - affiliate_id
                - amount
              properties:
                affiliate_id:
                  type: string
                  format: uuid
                amount:
                  type: number
                  description: Sale amount in major units (99 = $99).
                currency:
                  type: string
                  description: Three-letter code. Defaults to your workspace currency.
                product_id:
                  type: string
                  description: Stripe product id (prod_…) the sale is for.
                billing_interval:
                  type: string
                  enum:
                    - one_time
                    - month
                    - year
                customer_email:
                  type: string
                  description: The buyer, so self-referral and other holds are checked.
                occurred_at:
                  type: string
                  format: date-time
                  description: When the sale happened. Not in the future. Defaults to now.
      responses:
        '200':
          description: The quote
          content:
            application/json:
              schema:
                type: object
                properties:
                  object:
                    type: string
                    example: commission_quote
                  data:
                    type: object
                    properties:
                      earns:
                        type: boolean
                      amount:
                        type: number
                      currency:
                        type: string
                      status:
                        type:
                          - string
                          - 'null'
                      held:
                        type: boolean
                      hold_reason_code:
                        type:
                          - string
                          - 'null'
                      hold_reason_label:
                        type:
                          - string
                          - 'null'
                        example: Would be held for review
                      rate:
                        type:
                          - number
                          - 'null'
                      rate_is_flat:
                        type:
                          - boolean
                          - 'null'
                      rule:
                        type:
                          - string
                          - 'null'
                        enum:
                          - override
                          - product
                          - interval
                          - catch_all
                          - null
                      campaign_id:
                        type:
                          - string
                          - 'null'
                      campaign_name:
                        type:
                          - string
                          - 'null'
                      product_id:
                        type:
                          - string
                          - 'null'
                      billing_interval:
                        type:
                          - string
                          - 'null'
                      sale_amount:
                        type: number
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '402':
          $ref: '#/components/responses/DashboardLocked'
        '403':
          $ref: '#/components/responses/InsufficientScope'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
      security:
        - WorkspaceKey: []
components:
  responses:
    BadRequest:
      description: Invalid or missing parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: invalid_json
    Unauthorized:
      description: Missing or invalid bearer token
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: unauthorized
    DashboardLocked:
      description: >-
        Your plan's dashboard and management access is locked until you upgrade.
        Tracking keeps working.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: plan_restricted
    InsufficientScope:
      description: The key lacks the required scope
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: insufficient_scope
            need: write
    NotFound:
      description: Resource not found / not in workspace
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: link_not_found
    RateLimited:
      description: Too many requests of this kind for your workspace. Try again later.
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
                example: rate_limited
              message:
                type: string
  schemas:
    Error:
      type: object
      properties:
        error:
          type: string
        need:
          type: string
          description: Present on insufficient_scope.
        detail:
          type: string
  securitySchemes:
    WorkspaceKey:
      type: http
      scheme: bearer
      description: 'Workspace API key, e.g. `sa_live_…`. Scopes: read / write / track / *.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.