> ## 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.

# Refund Sale

> Marks a sale as refunded and reverses the commission attached to it.

If the sale was already refunded the request still succeeds, with `alreadyRefunded` set to `true`. A sale cannot be refunded once it has passed your program's refund window, has been added to a payout batch, has already been paid out, or has been marked as manually paid — each of those returns a 400 with a `reason` you can branch on.



## OpenAPI

````yaml PATCH /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:
    patch:
      summary: Mark a sale as refunded
      description: >-
        Marks a sale as refunded and reverses the commission attached to it.


        If the sale was already refunded the request still succeeds, with
        `alreadyRefunded` set to `true`. A sale cannot be refunded once it has
        passed your program's refund window, has been added to a payout batch,
        has already been paid out, or has been marked as manually paid — each of
        those returns a 400 with a `reason` you can branch on.
      requestBody:
        description: The sale to refund
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SaleRefund'
        required: true
      responses:
        '200':
          description: The refund was processed, or the sale was already refunded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SaleRefundResponse'
        '400':
          description: >-
            The sale is not eligible to be refunded. `reason` is one of
            `outside_refund_window`, `included_in_payout_batch`, `already_paid`
            or `manually_paid`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SaleRefundError'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: No sale with that ID exists in this program.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SaleRefundError'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  schemas:
    SaleRefund:
      type: object
      required:
        - saleId
      properties:
        saleId:
          type: integer
          description: The sale ID to mark as refunded
    SaleRefundResponse:
      type: object
      properties:
        success:
          type: boolean
          description: Whether the refund request was handled successfully
        alreadyRefunded:
          type: boolean
          description: >-
            Whether the sale had already been marked as refunded before this
            request
        reason:
          type: string
          description: >-
            Why the request resolved the way it did — for example `refunded` or
            `already_refunded`.
    SaleRefundError:
      type: object
      properties:
        error:
          type: string
          description: Human readable description of why the sale could not be refunded
        reason:
          type: string
          description: >-
            Machine readable reason: `outside_refund_window`,
            `included_in_payout_batch`, `already_paid`, `manually_paid` or
            `sale_not_found`
    Error:
      type: object
      properties:
        error:
          type: string
          description: Human readable description of what went wrong
  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'
    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

````