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

# Create a Sale

> Records a sale and pays out the resulting commission.

You must identify who the sale belongs to with one of `referralId`, `email` or `promoCode`. `referralId` is flexible: it accepts a referral UUID, an affiliate UUID, an affiliate link slug, or a numeric click ID. `email` matches an existing referral by email address.

`totalEarned` is required and must be non-zero. A customer `name` and `email` are also required — they are taken from the matched referral when you do not send them explicitly.

`commissionRate` overrides the affiliate's rate for this sale only. `tax` and `shipping` are deducted before commission is calculated, but only when your program has the matching deduction setting enabled.

When you pass `promoCode`, the code is validated for existence, active state, expiry and redemption limits, and its redemption counters are incremented on success.

Optional fields `tax` and `shipping` can be provided to exclude these amounts from the commission calculation. When the affiliate program has "Automatically deduct tax from commission calculation" or "Automatically deduct shipping from commission calculation" enabled, these amounts will be subtracted from the total before computing the affiliate's commission.


## OpenAPI

````yaml POST /sales
openapi: 3.0.1
info:
  title: Referly API
  description: >-
    REST API for managing affiliates, referrals, sales, affiliate links, coupons
    and promotional codes in your Referly affiliate program.


    Every request must send `Authorization: Bearer <YOUR_API_KEY>`. The token is
    scoped to a single affiliate program, so no program ID is ever required in
    the request — every read and write is automatically limited to that program.


    Requests are rate limited per token, per endpoint and per method.
  version: 1.0.0
servers:
  - url: https://www.referly.so/api/v1
security:
  - bearerAuth: []
paths:
  /sales:
    post:
      summary: Create a sale
      description: >-
        Records a sale and pays out the resulting commission.


        You must identify who the sale belongs to with one of `referralId`,
        `email` or `promoCode`. `referralId` is flexible: it accepts a referral
        UUID, an affiliate UUID, an affiliate link slug, or a numeric click ID.
        `email` matches an existing referral by email address.


        `totalEarned` is required and must be non-zero. A customer `name` and
        `email` are also required — they are taken from the matched referral
        when you do not send them explicitly.


        `commissionRate` overrides the affiliate's rate for this sale only.
        `tax` and `shipping` are deducted before commission is calculated, but
        only when your program has the matching deduction setting enabled.


        When you pass `promoCode`, the code is validated for existence, active
        state, expiry and redemption limits, and its redemption counters are
        incremented on success.
      requestBody:
        description: The sale to record
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/NewSale'
        required: true
      responses:
        '200':
          description: >-
            The recorded sale. Returns `null` when no affiliate could be
            resolved from the details supplied — check the response before
            assuming a commission was created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Sale'
        '400':
          description: >-
            None of `referralId` / `email` / `promoCode` was supplied;
            `totalEarned`, `name` or `email` is missing; the promo code was not
            found, is inactive, has expired, has hit its redemption limit, or
            has no affiliate attached; or the sale could not be created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/ProgramNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  schemas:
    NewSale:
      type: object
      required:
        - totalEarned
      properties:
        referralId:
          type: string
          description: >-
            Identifies who the sale belongs to. Accepts a referral UUID, an
            affiliate UUID, an affiliate link slug, or a numeric click ID.
            Required unless `email` or `promoCode` is supplied.
        email:
          type: string
          format: email
          description: >-
            Email of the customer. Also used to match an existing referral.
            Required unless `referralId` or `promoCode` is supplied.
        promoCode:
          type: string
          description: >-
            A promotional code belonging to the affiliate to credit. Required
            unless `referralId` or `email` is supplied. Validated for existence,
            active state, expiry and redemption limits; its redemption counters
            are incremented on success.
        name:
          type: string
          description: >-
            Name of the customer. Required unless it can be taken from the
            matched referral.
        totalEarned:
          type: number
          format: float
          description: Gross value of the sale. Must be non-zero.
        commissionRate:
          type: number
          format: float
          description: >-
            Overrides the affiliate's commission rate for this sale only.
            Defaults to the affiliate's own rate.
        externalId:
          type: string
          description: >-
            The ID of this sale in your own system. Must be unique within the
            program.
        externalInvoiceId:
          type: string
          description: >-
            The ID of the invoice in your own system. Must be unique within the
            program.
        product:
          description: A single product line for this sale
          allOf:
            - $ref: '#/components/schemas/Product'
        tax:
          type: number
          format: float
          description: >-
            Tax to deduct before commission is calculated. Only applied when
            your program has tax deduction enabled.
        shipping:
          type: number
          format: float
          description: >-
            Shipping to deduct before commission is calculated. Only applied
            when your program has shipping deduction enabled.
    Sale:
      type: object
      properties:
        id:
          type: integer
          format: int64
          description: The sale ID
        affiliateId:
          type: string
          format: uuid
          nullable: true
          description: The affiliate credited with this sale
        referralId:
          type: string
          format: uuid
          nullable: true
          description: The referral this sale belongs to
        affiliateProgramId:
          type: string
          format: uuid
          nullable: true
          description: The affiliate program this sale belongs to
        affiliateLinkId:
          type: string
          format: uuid
          nullable: true
          description: The affiliate link the sale was attributed to
        promotionalCodeId:
          type: string
          format: uuid
          nullable: true
          description: The promotional code used on this sale, if any
        externalId:
          type: string
          nullable: true
          description: The ID of this sale in your own system. Unique per program.
        externalInvoiceId:
          type: string
          nullable: true
          description: The ID of the invoice in your own system. Unique per program.
        name:
          type: string
          nullable: true
          description: Name of the customer
        email:
          type: string
          format: email
          nullable: true
          description: Email of the customer
        totalEarned:
          type: number
          format: float
          description: Gross value of the sale
        commissionRate:
          type: number
          format: float
          nullable: true
          description: Commission rate applied to this sale
        commissionEarned:
          type: number
          format: float
          nullable: true
          description: >-
            Commission recorded for the credited affiliate. Merged in by the API
            from the sale's commission record — it is not a column on the sale
            itself.
        taxAmount:
          type: number
          format: float
          description: Tax deducted before commission was calculated
        shippingAmount:
          type: number
          format: float
          description: Shipping deducted before commission was calculated
        productsBought:
          type: array
          items:
            type: string
          description: Product identifiers attached to this sale
        clicks:
          type: integer
          description: Clicks attributed to this sale
        status:
          type: string
          enum:
            - ACTIVE
            - REFUNDED
          description: Whether the sale is live or has been refunded
        refundedAt:
          type: string
          format: date-time
          nullable: true
          description: When the sale was marked refunded
        paymentTrigger:
          type: string
          enum:
            - SIGNUP
            - PURCHASE
            - BONUS
            - CONTENT_REWARD
          description: What triggered the commission for this sale
        source:
          type: string
          enum:
            - UNKNOWN
            - API
            - INTEGRATION
            - MANUAL
            - IMPORTED
            - AUTOMATED
          description: Where the sale came from. Sales created through this API have `API`.
        metadata:
          type: object
          nullable: true
          description: Arbitrary JSON you can attach to the sale
        createdAt:
          type: string
          format: date-time
          description: When the sale was recorded
    Error:
      type: object
      properties:
        error:
          type: string
          description: Human readable description of what went wrong
    Product:
      type: object
      properties:
        productId:
          type: string
          description: Product ID
        quantity:
          type: number
          description: Quantity purchased
        price:
          type: number
          format: float
          description: Unit price at time of sale
        name:
          type: string
          description: Product name
  responses:
    Unauthorized:
      description: >-
        The `Authorization` header is missing, is not a `Bearer` header, or the
        token is not valid.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: API access is not enabled for this account.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ProgramNotFound:
      description: The affiliate program this token belongs to no longer exists.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: Too many requests for this token on this endpoint. Please slow down.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer

````