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

> ## Agent Instructions
> Sapiom Pay is for platforms whose agent shops for many end users. Each end user is a buyer with their own Sapiom key and saved cards.
> Use the buyer's key for every call made on that buyer's behalf. Never use one buyer's key for another user, and never give the agent the platform key.
> Agents call the hosted MCP tools at https://api.sapiom.ai/v1/mcp. Backends call the REST API at https://api.sapiom.ai/v1. Both take the key in an x-api-key header.
> Never ask a buyer for a card number, expiry date or CVV in chat. Buyers enter card details only on Sapiom's hosted pages.
> Follow the nextAction in each transaction result. Action links are secrets for the intended buyer only.
> Use one idempotencyKey per transaction. After a timeout, retry with the same key. Never start a new transaction to escape an uncertain outcome.
> Report an order as placed only when order.outcome is confirmed. If it is unknown, stop and hand off to a person.

# Create a transaction

> Creates a new transaction for the organization associated with the API key. Automatically handles authorization and payment if required. Supports an optional `x-idempotency-key` header (max 255 chars), unique per tenant: replaying a key returns the previously created transaction — whatever its state — instead of creating a new one. First-write-wins: the original transaction is returned even if the replayed request body differs, so use a fresh key for each genuinely new request. Requires a [buyer key](/api-reference/overview#authentication).

> [!NOTE]
>
> For a Sapiom Pay transaction, send `requestFacts` with `source: "ucp-checkout"`, `version: "v1"` and the merchant's origin in `request.merchantOrigin`, plus `funding.source: "external_card"`. Omit `funding.paymentCardId` to use the buyer's default card. Then open the merchant checkout with [Open the checkout](https://docs.sapiom.ai/api-reference/transactions/open-the-checkout.md).


## OpenAPI

````yaml /api-reference/openapi.json post /v1/transactions
openapi: 3.0.0
info:
  title: Sapiom Pay API
  version: '1.0'
  description: >-
    Create buyers, save their cards and authorize transactions. Send your
    platform key or a buyer key in the `x-api-key` header.
servers:
  - url: https://api.sapiom.ai
    description: Production
security:
  - api-key: []
tags:
  - name: Buyers
    description: One buyer per end user. Called tenants in the API.
  - name: Cards
    description: Hosted card setup links and the buyer's saved cards.
  - name: Spending limits
    description: Limits on what each card can spend.
  - name: Merchants
    description: Check whether Sapiom can buy from a merchant.
  - name: Transactions
    description: Create a transaction and drive its UCP checkout.
  - name: Browser checkout
    description: Placeholder cards and the relay Browser Pay uses.
paths:
  /v1/transactions:
    post:
      tags:
        - Transactions
      summary: Create a transaction
      description: >-
        Creates a new transaction for the organization associated with the API
        key. Automatically handles authorization and payment if required.
        Supports an optional `x-idempotency-key` header (max 255 chars), unique
        per tenant: replaying a key returns the previously created transaction —
        whatever its state — instead of creating a new one. First-write-wins:
        the original transaction is returned even if the replayed request body
        differs, so use a fresh key for each genuinely new request. Requires a
        [buyer key](/api-reference/overview#authentication).
      operationId: TransactionController_createTransaction
      parameters:
        - name: x-idempotency-key
          required: true
          in: header
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTransactionRequest'
            example:
              requestFacts:
                source: ucp-checkout
                version: v1
                sdk: {}
                request:
                  merchantOrigin: https://shop.example
                  estimate:
                    amount: '248.00'
                    currency: USD
              funding:
                source: external_card
                paymentCardId: 00000000-0000-4000-8000-000000000001
      responses:
        '201':
          description: Transaction created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionResponseDto'
        '400':
          description: >-
            Invalid request data. Card funding that names no card, for a tenant
            with no saved card that can pay, is refused with `code:
            "no_saved_card"`: send the cardholder a card setup link, then create
            the transaction again.
        '401':
          description: Unauthorized - invalid or missing API key
      security:
        - api-key: []
components:
  schemas:
    CreateTransactionRequest:
      type: object
      properties:
        requestFacts:
          allOf:
            - $ref: '#/components/schemas/TransactionRequestFacts'
          description: >-
            For a transaction: `source` is `ucp-checkout`, `version` is `v1`,
            and `request.merchantOrigin` is the merchant's origin.
            `request.estimate` is your optional expected total.
          example:
            source: ucp-checkout
            version: v1
            sdk: {}
            request:
              merchantOrigin: https://shop.example
              estimate:
                amount: '248.00'
                currency: USD
        funding:
          description: >-
            How a UCP checkout is paid. Each final merchant total is paid with
            this card, authorized together with governance; the authorized
            transaction's payment carries the placeholder card to submit. Only
            for `ucp-checkout` request facts, and never with paymentData.
          allOf:
            - $ref: '#/components/schemas/TransactionFundingDto'
        shipping:
          description: >-
            For one UCP checkout: the shipping address and contact the checkout
            driver fills into the merchant checkout wherever the agent's create
            or update leaves them out: the contact and the address's name as
            `buyer`, and the address as the destination of a shipping method
            that has none (or of a new shipping method, when the request has no
            fulfillment). Anything the agent sends wins. Only for `ucp-checkout`
            request facts.
          allOf:
            - $ref: '#/components/schemas/TransactionShippingDto'
        returnUrl:
          type: string
          maxLength: 2048
          description: >-
            Return destination after hosted approval and card confirmation. Must
            use an origin or app scheme registered by the organization.
        metadata:
          type: object
          description: Additional metadata for the transaction
    TransactionResponseDto:
      type: object
      properties:
        returnUrl:
          type: string
          nullable: true
          description: Integrator-provided return destination for hosted transaction steps
        nextAction:
          type: object
          description: >-
            Current approval or payment action; its navigation link is derived
            at read time
        approvals:
          type: object
          description: >-
            Approval obligations and linked successor attempts; inspect an
            approval for current authority
        id:
          type: string
          description: Transaction ID
          example: 123e4567-e89b-12d3-a456-426614174000
        tenantId:
          type: string
          description: Organization ID
          example: 123e4567-e89b-12d3-a456-426614174000
        serviceName:
          type: string
          description: Service identifier
          example: openai
        actionName:
          type: string
          description: Action being performed
          example: completion
        resourceName:
          type: string
          description: Resource being accessed
          example: gpt-4
        serviceId:
          type: string
          nullable: true
          description: Service entity ID (foreign key reference)
          example: 123e4567-e89b-12d3-a456-426614174000
        status:
          enum:
            - pending
            - preparing
            - waiting_approval
            - authorized
            - completed
            - denied
            - cancelled
            - needs_revision
          type: string
          description: Transaction status
          example: authorized
        requiresPayment:
          type: boolean
          description: Whether the transaction requires payment
          example: true
        qualifiers:
          type: object
          description: Additional qualifiers for the transaction
          example:
            model: gpt-4
            tokens: 1000
        metadata:
          type: object
          description: Additional metadata for the transaction
        createdAt:
          format: date-time
          type: string
          description: Creation timestamp
          example: '2024-01-01T00:00:00.000Z'
        updatedAt:
          format: date-time
          type: string
          description: Last update timestamp
          example: '2024-01-01T00:00:00.000Z'
        authorizedAt:
          format: date-time
          type: string
          description: Authorization timestamp
          example: '2024-01-01T00:00:00.000Z'
        completedAt:
          format: date-time
          type: string
          description: Completion timestamp
          example: '2024-01-01T00:00:00.000Z'
        outcome:
          enum:
            - success
            - error
          type: string
          description: Transaction outcome (set when completed)
          example: success
        currentPaymentTransactionId:
          type: string
          nullable: true
          description: Current payment transaction ID if transaction requires payment
          example: 123e4567-e89b-12d3-a456-426614174000
        payment:
          description: Payment transaction details when transaction requires payment
          allOf:
            - $ref: '#/components/schemas/PaymentTransactionResponseDto'
        trace:
          description: Trace information for workflow grouping
          allOf:
            - $ref: '#/components/schemas/TraceResponseDto'
        agentId:
          type: string
          nullable: true
          description: Agent ID if transaction is associated with an agent
          example: 123e4567-e89b-12d3-a456-426614174000
        agent:
          description: Agent information if transaction is associated with an agent
          allOf:
            - $ref: '#/components/schemas/AgentResponseDto'
      required:
        - id
        - tenantId
        - serviceName
        - actionName
        - resourceName
        - status
        - requiresPayment
        - createdAt
        - updatedAt
    TransactionRequestFacts:
      type: object
      properties:
        source:
          type: string
          description: For a transaction, `ucp-checkout`.
          example: ucp-checkout
        version:
          type: string
          description: For a transaction, `v1`.
          example: v1
        sdk:
          type: object
          properties:
            name:
              type: string
            version:
              type: string
            nodeVersion:
              type: string
            platform:
              type: string
            dependencies:
              type: object
          required:
            - name
            - version
          example: {}
        integration:
          type: object
          properties:
            name:
              type: string
            version:
              type: string
          required:
            - name
            - version
        request:
          type: object
          description: >-
            For a transaction, the merchant's origin as `merchantOrigin`, and
            optionally `estimate`, your expected total.
          example:
            merchantOrigin: https://shop.example
            estimate:
              amount: '248.00'
              currency: USD
      required:
        - source
        - version
        - sdk
        - request
    TransactionFundingDto:
      type: object
      properties:
        source:
          type: string
          enum:
            - external_card
          description: Pay with one of the tenant's own payment cards
        paymentCardId:
          type: string
          format: uuid
          description: >-
            The card fixed for this transaction. Omitted: resolve the tenant's
            default once at transaction creation.
      required:
        - source
    TransactionShippingDto:
      type: object
      properties:
        address:
          $ref: '#/components/schemas/TransactionShippingAddressDto'
        contact:
          $ref: '#/components/schemas/TransactionShippingContactDto'
    PaymentTransactionResponseDto:
      type: object
      properties:
        id:
          type: string
          description: Payment transaction ID
          example: 123e4567-e89b-12d3-a456-426614174000
        transactionId:
          type: string
          description: Transaction ID this payment belongs to
          example: 123e4567-e89b-12d3-a456-426614174000
        fiatAmount:
          type: string
          description: The payment amount in USD, as a decimal string.
        status:
          enum:
            - pending
            - preparing
            - authorized
            - settling
            - completed
            - failed
            - cancelled
          type: string
          description: Payment status
          example: authorized
        fundingSource:
          type: string
          description: '`external_card`: the buyer''s saved card pays.'
          enum:
            - external_card
        paymentCardId:
          type: string
          nullable: true
          description: The card paying a card-funded payment
          format: uuid
        credentialRoute:
          type: string
          description: >-
            `real_card_number`: the relay puts the real card into the merchant's
            payment request.
          enum:
            - real_card_number
          nullable: true
        placeholder:
          description: >-
            An authorized card payment's placeholder card, while it can still be
            relayed. Submit it in the merchant's card form; the relay swaps it
            for the real credential once.
          allOf:
            - $ref: '#/components/schemas/CardPlaceholderDto'
        reason:
          type: string
          nullable: true
          description: Reason for payment failure or cancellation
          example: Insufficient funds
        createdAt:
          format: date-time
          type: string
          description: Creation timestamp
          example: '2024-01-01T00:00:00.000Z'
        updatedAt:
          format: date-time
          type: string
          description: Last update timestamp
          example: '2024-01-01T00:00:00.000Z'
        authorizedAt:
          format: date-time
          type: string
          nullable: true
          description: Authorization timestamp
          example: '2024-01-01T00:00:00.000Z'
      required:
        - id
        - transactionId
        - fiatAmount
        - status
        - createdAt
        - updatedAt
    TraceResponseDto:
      type: object
      properties:
        id:
          type: string
          description: Trace ID
          example: 123e4567-e89b-12d3-a456-426614174000
        externalId:
          type: string
          nullable: true
          description: Optional user-supplied external ID for trace correlation
          example: checkout-session-abc123
      required:
        - id
    AgentResponseDto:
      type: object
      properties:
        id:
          type: string
        tenantId:
          type: string
        label:
          type: string
        name:
          type: string
        description:
          type: string
          nullable: true
        status:
          type: string
        createdAt:
          format: date-time
          type: string
        updatedAt:
          format: date-time
          type: string
      required:
        - id
        - tenantId
        - label
        - name
        - status
        - createdAt
        - updatedAt
    TransactionShippingAddressDto:
      type: object
      properties:
        first_name:
          type: string
          maxLength: 255
          example: Jane
        last_name:
          type: string
          maxLength: 255
          example: Buyer
        street_address:
          type: string
          maxLength: 255
          example: 1 Market St
        extended_address:
          type: string
          maxLength: 255
          description: Apartment, suite, unit
          example: Suite 300
        address_locality:
          type: string
          maxLength: 255
          description: City or locality
          example: San Francisco
        address_region:
          type: string
          maxLength: 255
          description: State, province or region
          example: CA
        postal_code:
          type: string
          maxLength: 32
          example: '94105'
        address_country:
          type: string
          pattern: /^[A-Z]{2}$/
          description: ISO 3166-1 alpha-2 country code
          example: US
      required:
        - street_address
        - address_locality
        - address_country
    TransactionShippingContactDto:
      type: object
      properties:
        email:
          type: string
          format: email
          example: jane@example.com
        phone_number:
          type: string
          maxLength: 32
          description: Some merchants require a phone number for delivery
          example: '+14155550100'
    CardPlaceholderDto:
      type: object
      properties:
        number:
          type: string
          description: Card number shaped like the real card's brand; not a real card
          example: '4000123412341234'
        expMonth:
          type: number
          example: 7
        expYear:
          type: number
          example: 2029
        cvc:
          type: string
          example: '123'
        brand:
          type: string
          example: visa
        expiresAt:
          type: string
          description: After this the placeholder no longer relays
          example: '2026-10-13T13:00:00.000Z'
        injectionRef:
          type: string
          description: The armed injection the relay looks the placeholder up by
        transactionId:
          type: string
          description: The transaction the placeholder is relayed through
      required:
        - number
        - expMonth
        - expYear
        - cvc
        - brand
        - expiresAt
        - injectionRef
        - transactionId
  securitySchemes:
    api-key:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Your platform key for buyer management, or a buyer key for everything
        else.

````

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