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

# Create and send an invoice

> Create an invoice for a customer and (by default) email the hosted
payment link to them. Returns the saved invoice along with the hosted
payment URL.

- Set `sendEmail` to `false` if you only want to create the invoice without
  delivering it. You can email it later via `POST /invoices/{invoiceId}/send`.
- All amounts are integer cents (`unitPriceCents`, `taxCents`,
  `discountCents`).
- `dueDate` must be an ISO 8601 date or date-time string.
- `allowedPaymentTypes` defaults to `["card"]`. See the schema for
  supported values.
- Card and Plaid-ACH payments are handled by the `card` and
  `us_bank_account` methods (Whop checkout). Use those for any flow
  that pulls funds from the customer's account.
- Including `bank_transfer` provisions a Stripe virtual bank account
  dedicated to **wire transfers**. The response will include
  `bankTransferInstructions` with a unique account number, routing
  number, and reference code (USD, EUR, GBP, JPY, or MXN). We never
  link out to a Stripe-hosted page — render the fields inline in
  your UI / email / PDF. The customer must include the `reference`
  string in the wire memo so Stripe can match the inbound payment
  to the correct invoice.
- **Wire fee:** invoices that include `bank_transfer` carry a 1%
  platform fee on top of `totalCents`. The customer wires
  `bankTransferAmountCents` (`totalCents + bankTransferFeeCents`);
  the merchant is credited only `totalCents`. Card and ACH rails
  do not include this fee.
- If Stripe Customer Balance is not yet enabled on the account when
  the invoice is created, `bankTransferInstructions` will be `null`
  on the create response. They self-heal — the next call to
  `GET /invoices/{invoiceId}` will lazily provision and persist the
  virtual receiving account.




## OpenAPI

````yaml /openapi/platform-apikey.yaml post /invoices
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:
    post:
      tags:
        - Invoices
      summary: Create and send an invoice
      description: >
        Create an invoice for a customer and (by default) email the hosted

        payment link to them. Returns the saved invoice along with the hosted

        payment URL.


        - Set `sendEmail` to `false` if you only want to create the invoice
        without
          delivering it. You can email it later via `POST /invoices/{invoiceId}/send`.
        - All amounts are integer cents (`unitPriceCents`, `taxCents`,
          `discountCents`).
        - `dueDate` must be an ISO 8601 date or date-time string.

        - `allowedPaymentTypes` defaults to `["card"]`. See the schema for
          supported values.
        - Card and Plaid-ACH payments are handled by the `card` and
          `us_bank_account` methods (Whop checkout). Use those for any flow
          that pulls funds from the customer's account.
        - Including `bank_transfer` provisions a Stripe virtual bank account
          dedicated to **wire transfers**. The response will include
          `bankTransferInstructions` with a unique account number, routing
          number, and reference code (USD, EUR, GBP, JPY, or MXN). We never
          link out to a Stripe-hosted page — render the fields inline in
          your UI / email / PDF. The customer must include the `reference`
          string in the wire memo so Stripe can match the inbound payment
          to the correct invoice.
        - **Wire fee:** invoices that include `bank_transfer` carry a 1%
          platform fee on top of `totalCents`. The customer wires
          `bankTransferAmountCents` (`totalCents + bankTransferFeeCents`);
          the merchant is credited only `totalCents`. Card and ACH rails
          do not include this fee.
        - If Stripe Customer Balance is not yet enabled on the account when
          the invoice is created, `bankTransferInstructions` will be `null`
          on the create response. They self-heal — the next call to
          `GET /invoices/{invoiceId}` will lazily provision and persist the
          virtual receiving account.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateInvoiceRequest'
            examples:
              basic:
                summary: Single line item invoice (card only)
                value:
                  customerName: Acme Co.
                  customerEmail: billing@acme.example
                  paymentType: one_time
                  currency: usd
                  dueDate: '2026-06-15'
                  collectCustomerFee: true
                  allowedPaymentTypes:
                    - card
                  lineItems:
                    - description: Q2 retainer
                      quantity: 1
                      unitPriceCents: 250000
              cardAchAndWire:
                summary: Accept card, ACH (Whop), and wire (Stripe)
                value:
                  customerName: Globex Industries
                  customerEmail: ap@globex.example
                  additionalEmails:
                    - accounting@globex.example
                  paymentType: one_time
                  currency: usd
                  dueDate: '2026-06-30'
                  collectCustomerFee: true
                  allowedPaymentTypes:
                    - card
                    - us_bank_account
                    - bank_transfer
                  description: Annual platform license
                  lineItems:
                    - description: Annual license
                      quantity: 1
                      unitPriceCents: 1200000
      responses:
        '201':
          description: Invoice created
          content:
            application/json:
              schema:
                type: object
                properties:
                  invoice:
                    $ref: '#/components/schemas/Invoice'
                  url:
                    type: string
                    description: Hosted payment URL for the customer
        '400':
          description: Invalid invoice payload
        '401':
          description: Invalid or missing API key
        '402':
          description: Active subscription required
        '503':
          description: Invoice creation is temporarily disabled
components:
  schemas:
    CreateInvoiceRequest:
      type: object
      required:
        - customerName
        - customerEmail
        - lineItems
        - dueDate
      properties:
        customerId:
          type: string
          nullable: true
          description: >-
            Optional existing customer ID. A new customer record is created if
            omitted.
        customerName:
          type: string
        customerEmail:
          type: string
          format: email
        additionalEmails:
          type: array
          items:
            type: string
            format: email
          description: Extra recipients copied on the invoice email.
        customerAddress:
          $ref: '#/components/schemas/InvoiceAddress'
        paymentType:
          type: string
          enum:
            - one_time
            - renewal
          default: one_time
        currency:
          type: string
          default: usd
          description: 3-letter ISO 4217 currency code (lowercase).
        lineItems:
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/InvoiceLineItem'
        taxCents:
          type: integer
          minimum: 0
          default: 0
        discountCents:
          type: integer
          minimum: 0
          default: 0
        collectCustomerFee:
          type: boolean
          default: true
          description: Whether processing fees are added on top of the customer's total.
        allowedPaymentTypes:
          type: array
          default:
            - card
          description: |
            Payment rails the invoice should accept. Order is non-significant.

            All values except `bank_transfer` are processed by Whop's hosted
            checkout (card / wallet / Plaid ACH / BNPL / crypto).

            `bank_transfer` is special: it provisions a Stripe Customer
            Balance virtual receiving account dedicated to **wire transfers**
            (USD, EUR, GBP, JPY, MXN). Customers wire `totalCents` plus a
            **1% platform fee**; the merchant is credited only `totalCents`.
            ACH pulls remain on the `us_bank_account` rail. We never link
            out to a Stripe-hosted page.
          items:
            type: string
            enum:
              - card
              - apple_pay
              - google_pay
              - link
              - us_bank_account
              - sepa_debit
              - bacs_debit
              - acss_debit
              - au_becs_debit
              - cashapp
              - paypal
              - venmo
              - klarna
              - affirm
              - afterpay_clearpay
              - crypto
              - bank_transfer
        dueDate:
          type: string
          description: ISO 8601 date (`YYYY-MM-DD`) or date-time string.
        description:
          type: string
          nullable: true
        notes:
          type: string
          nullable: true
        terms:
          type: string
          nullable: true
        sendReminders:
          type: boolean
          default: true
          description: Whether to send automatic past-due reminders.
        sendEmail:
          type: boolean
          default: true
          description: Send the hosted payment link by email immediately on create.
    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

````