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

# Get invoice

> Retrieve a single invoice by ID. Returns 404 if it does not belong
to the authenticated company.

- This endpoint **lazily provisions** wire-transfer funding details
  for invoices that opted into `bank_transfer` but didn't have
  `bankTransferInstructions` populated at create time (eg. Stripe
  Customer Balance was not yet enabled on the account). Polling
  this endpoint after creation is the recommended way to surface
  wire details to your end user once the merchant fixes their
  Stripe configuration.
- The hosted invoice page (`hostedInvoiceUrl`) and PDF (`pdfUrl`)
  are stable URLs — safe to cache or share.




## OpenAPI

````yaml /openapi/platform-apikey.yaml get /invoices/{invoiceId}
openapi: 3.0.4
info:
  title: Sideshift Public API
  version: 1.0.0
  description: >
    REST API for Sideshift platform. Authenticate using your API key in the
    `x-api-key` header.


    This document covers the **public, API-key-authenticated** surface. The

    restricted endpoints (Jobs, Applicants, payout execution/Quick Pay) are
    gated

    to an explicit partner allowlist and are documented in the **Full Access**

    spec (`sideshift-api-private.yaml`); a non-allowlisted key calling them

    receives `403`. API-key *management* (creating/rotating keys, digest

    automations) is performed in the dashboard with a Firebase session and is
    not

    part of this API-key contract.


    ## Requirements

    - **Active Subscription Required**: API access requires an active Sideshift
      subscription. Requests from a company without one return
      `402 { "error": "Active subscription required" }`.
    - API key from Settings → Integrations


    ## Rate Limits

    - Default: **100 requests per minute** per API key.

    - Allowlisted partner accounts: **400 requests per minute**.

    - Every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining`, and
      `X-RateLimit-Reset` headers; exceeding the limit returns `429`.

    ## Errors

    - Errors are returned as `{ "error": "<message>" }` with the appropriate
    HTTP
      status (`400` invalid request, `401` invalid/missing key, `402` no active
      subscription, `403` restricted endpoint / cross-company, `404` not found,
      `429` rate limited). Some endpoints add a `code` (e.g. `LEAD_NOT_FOUND`).

    ## Timestamps

    - All timestamps are Unix timestamps in milliseconds

    - Example: `1634567890000`


    ## Pagination

    - Most list endpoints support `page` (default: 1) and `limit` (default: 25,
      max: 100) parameters and return `{ data, page, total }`. Some additionally
      return `limit` and/or `totalPages`.
    - Agency (parent) accounts can pass `scope=agency` on analytics/posts
      endpoints to aggregate across the parent agency and every subaccount.

    ## Base URL

    - Production: `https://app.sideshift.app/api/v1`
servers:
  - url: https://app.sideshift.app/api/v1
    description: Production server
security:
  - apiKeyAuth: []
tags:
  - name: Programs
    description: Campaign and program management
  - name: Posts
    description: Social media posts and content
  - name: Analytics
    description: Performance metrics and KPIs
  - name: Payouts
    description: Payout management including pending payouts and execution
  - name: Contracts
    description: Creator contracts and agreements
  - name: Creators
    description: Creator profiles and statistics
  - name: Invoices
    description: Create, list, and send invoices to customers
  - name: Discover
    description: Read Discover leads (brand inquiries) submitted to your agency
paths:
  /invoices/{invoiceId}:
    get:
      tags:
        - Invoices
      summary: Get invoice
      description: |
        Retrieve a single invoice by ID. Returns 404 if it does not belong
        to the authenticated company.

        - This endpoint **lazily provisions** wire-transfer funding details
          for invoices that opted into `bank_transfer` but didn't have
          `bankTransferInstructions` populated at create time (eg. Stripe
          Customer Balance was not yet enabled on the account). Polling
          this endpoint after creation is the recommended way to surface
          wire details to your end user once the merchant fixes their
          Stripe configuration.
        - The hosted invoice page (`hostedInvoiceUrl`) and PDF (`pdfUrl`)
          are stable URLs — safe to cache or share.
      parameters:
        - in: path
          name: invoiceId
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Invoice retrieved
          content:
            application/json:
              schema:
                type: object
                properties:
                  invoice:
                    $ref: '#/components/schemas/Invoice'
        '403':
          description: Invoice belongs to a different company
        '404':
          description: Invoice not found
components:
  schemas:
    Invoice:
      type: object
      properties:
        id:
          type: string
        invoiceNumber:
          type: string
        status:
          type: string
          enum:
            - open
            - pending
            - paid
            - void
            - overdue
            - refunded
            - partially_refunded
        customerId:
          type: string
          nullable: true
        customerName:
          type: string
        customerEmail:
          type: string
          format: email
        additionalEmails:
          type: array
          items:
            type: string
            format: email
        customerAddress:
          allOf:
            - $ref: '#/components/schemas/InvoiceAddress'
          nullable: true
        paymentType:
          type: string
          enum:
            - one_time
            - renewal
        currency:
          type: string
        lineItems:
          type: array
          items:
            $ref: '#/components/schemas/InvoiceLineItem'
        subtotalCents:
          type: integer
        taxCents:
          type: integer
        discountCents:
          type: integer
        totalCents:
          type: integer
        allowedPaymentTypes:
          type: array
          items:
            type: string
        collectCustomerFee:
          type: boolean
        issueDate:
          type: string
          format: date-time
        dueDate:
          type: string
          format: date-time
        paidAt:
          type: string
          format: date-time
          nullable: true
        voidedAt:
          type: string
          format: date-time
          nullable: true
        description:
          type: string
          nullable: true
        notes:
          type: string
          nullable: true
        terms:
          type: string
          nullable: true
        sendReminders:
          type: boolean
        remindersSentCount:
          type: integer
        lastReminderSentAt:
          type: string
          format: date-time
          nullable: true
        hostedInvoiceUrl:
          type: string
          description: Customer-facing payment URL.
        pdfUrl:
          type: string
          description: PDF download URL.
        bankTransferInstructions:
          allOf:
            - $ref: '#/components/schemas/BankTransferInstructions'
          nullable: true
          description: |
            Present when the invoice was created with `bank_transfer` in
            `allowedPaymentTypes` and Stripe successfully provisioned a
            virtual bank account. Render account/routing/reference to the
            customer. Currently supports USD only (`us_bank_transfer`).
        bankTransferFeeCents:
          type: integer
          nullable: true
          description: |
            Platform fee (in cents) added on top of `totalCents` when paying
            by wire. SideShift charges **1%** on inbound wires; this fee is
            already baked into `bankTransferAmountCents`. Other payment rails
            (card / ACH via Whop) do not include this fee. `null` when the
            invoice does not use the wire rail.
        bankTransferAmountCents:
          type: integer
          nullable: true
          description: |
            Exact amount (in cents) the customer should wire. Equals
            `totalCents + bankTransferFeeCents`. `null` when the invoice
            does not use the wire rail. The merchant is credited only
            `totalCents`; the wire fee accrues to SideShift.
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    InvoiceAddress:
      type: object
      properties:
        line1:
          type: string
        line2:
          type: string
        city:
          type: string
        state:
          type: string
        postalCode:
          type: string
        country:
          type: string
    InvoiceLineItem:
      type: object
      required:
        - description
        - quantity
        - unitPriceCents
      properties:
        id:
          type: string
          description: Server-assigned ID. Omit when creating an invoice.
          readOnly: true
        description:
          type: string
        quantity:
          type: integer
          minimum: 1
        unitPriceCents:
          type: integer
          minimum: 1
          description: Per-unit price in integer cents.
        amountCents:
          type: integer
          description: '`quantity * unitPriceCents`. Server-computed.'
          readOnly: true
    BankTransferInstructions:
      type: object
      description: |
        Per-invoice virtual bank account dedicated to wire transfers,
        issued by Stripe Customer Balance. The `reference` field MUST be
        included in the wire memo so the payment can be reconciled to the
        correct invoice. ACH payments are handled separately via Whop —
        keep the wire details rendered inline; do not redirect customers
        to any Stripe-hosted page.
      properties:
        type:
          type: string
          description: Funding instruction region (e.g. `us_bank_transfer`).
          enum:
            - us_bank_transfer
            - eu_bank_transfer
            - gb_bank_transfer
            - jp_bank_transfer
            - mx_bank_transfer
        currency:
          type: string
          description: Lowercase 3-letter ISO 4217 code.
        reference:
          type: string
          description: Memo / reference code customers must include on the wire.
        hostedInstructionsUrl:
          type: string
          nullable: true
          description: |
            Always returned as `null` on the public API. We deliberately
            do not surface the Stripe-hosted instructions URL to API
            consumers — render the structured fields below in your own UI.
        financialAddresses:
          type: array
          items:
            $ref: '#/components/schemas/BankTransferFinancialAddress'
        generatedAt:
          type: string
          format: date-time
    BankTransferFinancialAddress:
      type: object
      description: A receiving bank account customers can wire / ACH-credit funds to.
      properties:
        bankName:
          type: string
          nullable: true
        accountNumber:
          type: string
          nullable: true
        routingNumber:
          type: string
          nullable: true
          description: ABA routing number for US transfers; six-digit sort code for GB.
        accountHolderName:
          type: string
          nullable: true
        accountHolderAddress:
          type: string
          nullable: true
        accountType:
          type: string
          nullable: true
        iban:
          type: string
          nullable: true
          description: Returned for `eu_bank_transfer` and `gb_bank_transfer`.
        swiftCode:
          type: string
          nullable: true
          description: SWIFT/BIC for international wires.
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: API key for authentication. Get yours from Settings → Integrations

````