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

# Get payment status

> Poll a payment's current status by payment_id: pending, completed, or failed.



## OpenAPI

````yaml GET /v1/payments/{paymentId}/status
openapi: 3.0.3
info:
  title: Atum Payment Gateway API
  description: >
    The Atum Payment Gateway API enables secure, cross-chain payments with
    built-in escrow protection 

    and settlement verification. This API facilitates decentralized payment
    routing across multiple blockchain 

    networks while ensuring transaction atomicity and settlement guarantees.


    ## Supported Blockchains

    - Ethereum and EVM-compatible chains (Arbitrum, Optimism, Base, etc.)

    - Solana

    - Tron


    ## Authentication


    No API key, token, or authorization header is required on any operation.

    A payment carries its own authorization: the `sender_auth` signed messages
    prove

    control of the funding account, and are verified on every submission.
  version: 1.0.0
servers:
  - url: https://payment-gw.production-mainnet.atum.xyz
    description: Mainnet
  - url: https://payment-gw.production-testnet.atum.xyz
    description: Testnet
security: []
tags:
  - name: Payments
    description: >-
      Submit a payment and follow it to settlement, by payment id, by your own
      request id, or step by step.
  - name: Authorizations
    description: Counterparty authorization requested while a payment is being accepted.
  - name: Quote Requests
    description: >-
      The two-phase quote flow - open a quote-request batch, poll it, then award
      one quote.
  - name: Chain Defaults
    description: >-
      The per-chain corridor addresses a client needs before it can build and
      sign a payment.
  - name: Health
    description: Liveness probe for the gateway.
paths:
  /v1/payments/{paymentId}/status:
    get:
      tags:
        - Payments
      summary: Get payment status
      description: Retrieve the status of a payment by its ID
      operationId: getPaymentStatus
      parameters:
        - name: paymentId
          in: path
          required: true
          description: The ID of the payment to query
          schema:
            type: string
      responses:
        '200':
          description: Payment status retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetPaymentStatusResponse'
        '404':
          description: Payment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    GetPaymentStatusResponse:
      type: object
      properties:
        payment_id:
          type: string
          description: |
            The payment ID you're checking status for.
          example: '0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f'
        status:
          $ref: '#/components/schemas/PaymentStatus'
        transactions:
          $ref: '#/components/schemas/PaymentTransactions'
        updated_at:
          type: string
          format: date-time
          description: When the status was last updated
        quote_id:
          type: string
          description: >
            The winning quote's ID. Present once a quote has been awarded for
            this payment;

            absent while the payment is still collecting or awarding.
            Cross-references the

            `quote_id` returned by GET
            /v1/payments/quote-requests/{quoteRequestId}.
          example: 0x9a3b...e8d4
        fulfillment_quote:
          type: object
          description: >
            The settler-signed FulfillmentQuote for the winning quote, returned
            verbatim as an

            opaque signed document (structurally the canonical
            FulfillmentQuote/v1 declaration at

            https://schemas.atum.xyz/declarations/FulfillmentQuote/v1). Present
            once a quote has

            been awarded — including after the payment completes and
            `fulfillment_confirmation` is

            populated, since that is precisely when a consumer verifies.


            This is the PREIMAGE of the `quote_hash` committed on-chain in the
            escrow deposit and

            reserve witnesses. On-chain we commit only the hash, so a
            quote-selector consumer

            recomputes quote_hash over these bytes and compares it against the
            on-chain commitment

            to confirm the payment settled against the quote it selected ("trust
            but verify"), and

            verifies the settler signature over the same bytes.


            quote_hash is canonicalization-based (URDNA2015), so it is stable
            across JSON

            key-order/whitespace normalization and across JSON string-escaping
            differences. The

            returned bytes are hash-equivalent to, but not necessarily
            byte-identical with, what

            the settler emitted (quotes are stored as JSONB, which normalizes on
            write). The

            gateway still never re-serializes the quote through a typed struct
            (that renormalizes

            timestamp values and WOULD change quote_hash), so the Go binding
            exposes it as a raw

            JSON passthrough.
        fulfillment_confirmation:
          $ref: '#/components/schemas/FulfillmentConfirmation'
        error:
          $ref: '#/components/schemas/PaymentFailure'
        requested_count:
          type: integer
          description: >
            How many settler agents this payment's auction was broadcast to.
            Absent means

            unknown, never zero.
          example: 8
        decline_summary:
          type: array
          description: >
            Why the payment drew few or no quotes. Read from the same settler
            reports as the

            quote-request endpoints, keyed by this payment, so a payment that
            failed on an expired

            quote deadline can say WHY nobody funded it instead of only that
            nobody did.


            Every declining agent is counted exactly once under its most recent
            reason. Empty means

            no agent declined against this payment, absent means the breakdown
            could not be read. A

            payment awarded out of a quote-request batch was bid on at quote
            time, so its declines

            are keyed to that batch and are read from the batch's status
            endpoint rather than here.

            As on the quote-request endpoints, the free-form decline detail is
            never relayed.
          items:
            $ref: '#/components/schemas/DeclineSummaryEntry'
    ErrorResponse:
      type: object
      description: >-
        Safe, outward-facing error. Derived from an internal error through the
        shared error catalog. The public code identifies the category and the
        message is a curated, safe description.


        A panic is caught by shared middleware that responds `{"error":
        "Internal server error occurred"}` instead, so a 500 is not guaranteed
        to carry this shape.
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Public, machine-readable error category in SCREAMING_SNAKE_CASE.
          pattern: ^[A-Z][A-Z0-9_]*$
          example: INVALID_SOURCE_ASSET
        message:
          type: string
          description: Curated, safe, human-readable message.
          maxLength: 500
          example: The source asset identifier is not a valid CAIP-19 asset.
        request_id:
          type: string
          description: >-
            Correlation id to quote to support to locate the internal error
            record.
          example: req_123456789
        payment_id:
          type: string
          description: >-
            The payment this error was raised against. Absent when the error is
            not about a specific payment.
          example: '0xc7108e200d11580e7e75185991084b42a535af588ba8267cd0d1e7df089e5c9c'
        docs_url:
          type: string
          format: uri
          description: Link to the documentation page for this public code.
        domain:
          type: string
          description: Originating service domain.
          example: PAYMENT_GATEWAY
        retry_classification:
          type: string
          description: >-
            What the caller should do next. Absent means the condition has not
            been classified, which is not the same as safe to retry.

            Re-sending the same `request_id` is an idempotent replay and always
            safe. This value is about submitting a new one, which starts a new
            operation. See https://docs.atum.xyz/errors for the value set.
          example: RECONCILE_THEN_DECIDE
        request_id_reusable:
          type: boolean
          description: >-
            Whether the caller may re-send this same request_id. True means no
            payment was created for it, so the id is still free. False means a
            payment exists for it, so the id is spent and re-sending only
            replays this outcome. Absent means undetermined, which a caller
            should read as false. Separate from retry_classification, which
            answers what the caller must change rather than whether the id
            survived.
          example: false
    PaymentStatus:
      type: string
      description: >
        Where your payment is in its lifecycle. One payment reads the same
        however you ask

        about it.


        - `pending`: accepted and in progress. Nothing has reached the recipient
        yet.

        - `finalizing`: the transaction paying your recipient is on chain and is
        accruing
          the confirmations its chain requires. NOT FINAL, see below.
        - `completed`: delivered, with the required confirmations behind it.

        - `failed`: did not complete. Any funds held in escrow are returned, and
        `error`
          describes what went wrong.

        `completed` and `failed` are final and will not change afterwards.
        `pending` and

        `finalizing` will.


        **Do not treat `finalizing` as delivered.** It says the payment has been
        made on

        chain but is not yet irreversible, much as a card authorization is not
        yet a

        settlement. It normally becomes `completed`, and it can still become
        `failed` if

        the transaction never reaches the confirmation depth its chain requires.
        Acting on

        `finalizing` — releasing goods, crediting an account — means accepting
        that risk

        deliberately, at whatever threshold suits you rather than the one we
        wait for.


        `finalizing` is about paying the recipient. While your own funds are
        still being

        committed on the source chain the payment is `pending`, because nothing
        has reached

        the recipient yet.
      enum:
        - pending
        - finalizing
        - completed
        - failed
      example: pending
    PaymentTransactions:
      type: object
      description: >
        The transactions a payment has produced, one entry per stage, added as
        each becomes

        known. A stage absent here has produced no transaction yet.


        These are the two movements that decide whether your payment happened:
        your funds

        being committed, and your recipient being paid. Present on every
        outcome, so a

        payment that did not complete can still be traced on chain.

        `fulfillment_confirmation` is not a substitute: it is written only once
        a payment

        completes, and describes the finished delivery rather than progress
        towards it.


        Where a stage is attempted more than once, the entry describes the
        attempt that

        counts — the one that succeeded, or the last one if none did.
      properties:
        deposit:
          allOf:
            - $ref: '#/components/schemas/PaymentTransaction'
          description: Committing your funds on the source chain.
        fulfillment:
          allOf:
            - $ref: '#/components/schemas/PaymentTransaction'
          description: Paying your recipient on the destination chain.
    FulfillmentConfirmation:
      type: object
      description: >
        Confirmation details after a payment has been successfully delivered.

        Contains proof of delivery and transaction details for both source and
        destination chains.
      required:
        - payment_id
        - request_id
        - source_chain_id
        - destination_chain_id
        - source_tx_hash
        - destination_tx_hash
      properties:
        payment_id:
          type: string
          description: |
            Unique identifier for this payment transaction.
            Use this to track the payment across all systems.
          example: '0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f'
        request_id:
          type: string
          description: >
            Your original request ID that was provided when creating the
            payment.

            Helps match confirmations to your internal systems.
          example: req_123456789
        fulfillment_timestamp:
          type: string
          format: date-time
          description: Timestamp when the fulfillment was completed
        source_chain_id:
          type: string
          description: >
            The blockchain where funds were locked in escrow, using CAIP-2
            format.

            CAIP-2 is a standard way to identify blockchains:
            {namespace}:{reference}

            Examples:

            - "eip155:1" for Ethereum mainnet

            - "eip155:42161" for Arbitrum

            - "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" for Solana

            - "tron:mainnet" for Tron
          example: eip155:1
        destination_chain_id:
          type: string
          description: >
            The blockchain where the payment was delivered, using CAIP-2 format.

            CAIP-2 is a standard way to identify blockchains:
            {namespace}:{reference}

            Examples:

            - "eip155:1" for Ethereum mainnet

            - "eip155:42161" for Arbitrum

            - "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp" for Solana

            - "tron:mainnet" for Tron
          example: eip155:42161
        source_tx_hash:
          type: string
          description: Transaction hash of the escrow reservation on the source chain
          example: '0xa1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456'
        destination_tx_hash:
          type: string
          description: Transaction hash of the fulfillment on the destination chain
          example: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
        source_block_number:
          type: integer
          description: Block number where the source transaction was confirmed
        destination_block_number:
          type: integer
          description: Block number where the destination transaction was confirmed
    PaymentFailure:
      type: object
      description: >
        Why a payment failed. Present only when `status` is `failed`, and
        identical

        however you ask about the payment.


        `code` is the stable, machine-readable identity of the failure — branch
        on it

        rather than on `message`, which is written for a person and may be
        reworded.

        `docs_url` points at the page describing that code.
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: |
            Public error category in SCREAMING_SNAKE_CASE. Common codes:
            - `SETTLEMENT_FAILED`: the settlement could not be completed
            - `NO_QUOTES_RECEIVED`: no quotes arrived within the auction window
            - `INTERNAL_ERROR`: an unexpected error occurred
          example: SETTLEMENT_FAILED
        message:
          type: string
          description: >
            Human-readable description of the failure, for a person reading it.
            Do not

            branch on this text.
          example: No quotes received within the auction window
        domain:
          type: string
          description: |
            Which part of the system reported the failure.
          enum:
            - PAYMENT_GATEWAY
            - SETTLER_GATEWAY
            - SETTLER_AGENT
            - WALLET_ORCHESTRATION
            - VERIFICATION_SERVICE
            - BLOCKCHAIN
            - EXTERNAL_SERVICE
          example: PAYMENT_GATEWAY
        docs_url:
          type: string
          format: uri
          description: Link to the documentation page for this public code.
        retry_classification:
          type: string
          description: >-
            What the caller should do next. Absent means the condition has not
            been classified, which is not the same as safe to retry.

            Re-sending the same `request_id` is an idempotent replay and always
            safe. This value is about submitting a new one, which starts a new
            payment. See https://docs.atum.xyz/errors for the value set.
          example: RECONCILE_THEN_DECIDE
        request_id_reusable:
          type: boolean
          description: >-
            Whether the caller may re-send the `request_id` this payment was
            created under. On this shape it is almost always false, because a
            payment exists by definition, but it is carried rather than assumed
            so a caller reads the same field here as on a synchronous error.
            Absent means undetermined, which a caller should read as false.
          example: false
        blockchain_context:
          $ref: '#/components/schemas/PaymentBlockchainContext'
    DeclineSummaryEntry:
      type: object
      required:
        - reason
        - count
      properties:
        reason:
          $ref: '#/components/schemas/DeclineReason'
        count:
          type: integer
          description: >
            Agents whose most recent decline reason was this one. Counts agents,
            never rows, and an

            agent appears under one reason only.
          example: 4
        retry_classification:
          type: string
          description: >
            What would have to change for a settler giving this reason to submit
            a price quote,

            drawn from the same closed set as the `retry_classification` on an
            error response so

            a caller reads one vocabulary.


            It describes the decline only. The authoritative instruction for the
            payment is the

            `retry_classification` on its own error response: a payment can fail
            for a reason no

            settler named, and it can succeed while some settlers declined.


            Optional, and a pattern-constrained string for the same reason
            `DeclineReason` is.
          pattern: ^[A-Z][A-Z0-9_]*$
          example: RETRY_AFTER_DELAY
        docs_url:
          type: string
          format: uri
          description: >
            Link to the documentation for this reason. Absent rather than empty
            when no page is

            published, so a reader never follows a link to the site root.
          example: https://docs.atum.xyz/decline-reasons#insufficient-liquidity
    PaymentTransaction:
      type: object
      description: >
        One on-chain transaction belonging to a payment: which chain, which
        transaction, and

        which block it landed in.


        Whether the payment has actually happened is answered by `status`, not
        here. Read this

        to look the transaction up on chain and to verify it yourself.
      required:
        - transaction_hash
        - chain_id
      properties:
        transaction_hash:
          type: string
          description: >
            The transaction's hash on its chain. Hex hashes carry the `0x`
            prefix, including on

            Tron, whose own tooling omits it.
          pattern: ^(0x[a-fA-F0-9]{64}|[1-9A-HJ-NP-Za-km-z]{32,88})$
          example: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
        chain_id:
          type: string
          description: CAIP-2 identifier of the chain the transaction is on.
          pattern: ^[a-z0-9]+:[a-zA-Z0-9_-]+$
          example: eip155:42161
        block_number:
          type: integer
          description: >
            The block the transaction landed in. Absent until it has been mined.


            Provisional while `status` is `finalizing`: on a chain that settles
            against another,

            a reorganization there can move the transaction to a different
            block. Settled once

            `status` is `completed` — keep it as a final record only from then.
          example: 61234567
    PaymentBlockchainContext:
      type: object
      description: >-
        Where on chain a failed payment failed. Present only when the failure
        happened

        on chain — an escrow revert, or a fulfillment that could not be
        delivered — so a

        payment that failed before any transaction was sent carries no context
        here.
      properties:
        chain_id:
          type: string
          description: CAIP-2 chain identifier
          pattern: ^[a-z0-9]+:[a-zA-Z0-9_-]+$
        transaction_hash:
          type: string
          description: Failed transaction hash
          pattern: ^(0x[a-fA-F0-9]{64}|[1-9A-HJ-NP-Za-km-z]{32,88})$
        block_number:
          type: integer
          description: Block number where error occurred
        contract_address:
          type: string
          description: Contract that caused the error
          pattern: ^(0x[a-fA-F0-9]{40}|[1-9A-HJ-NP-Za-km-z]{32,44})$
        revert_reason:
          type: string
          description: Smart contract revert reason
        gas_used:
          type: string
          description: Gas consumed before failure
        estimated_gas_needed:
          type: string
          description: Estimated gas needed for success
    DeclineReason:
      type: string
      description: >
        A settler's reason for not bidding, projected from its internal reason
        code through

        the shared decline catalog (`apis/decline/v1/catalog.json`), which is
        the single

        source of truth for the reason set. Several internal codes may map to
        one public

        reason.


        Deliberately a pattern-constrained string rather than a closed enum. The
        set grows

        whenever a settler gains a cause worth naming, and a consumer whose
        generated client

        closes the set rejects the whole response on a value it has not seen.
        Treat an

        unrecognised value as `OTHER`.


        `OTHER` covers a reason whose detail is settler-authored free text, and
        any reason

        this gateway does not recognise. Both are counted so the summary stays
        exhaustive,

        without relaying text we neither author nor validate.
      pattern: ^[A-Z][A-Z0-9_]*$
      example: INSUFFICIENT_LIQUIDITY

````