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

# Sign an x402 payment authorization (BETA)

> > **Beta** — early access.

Returns the `X-PAYMENT` header for a seller's 402 challenge, signed by the agent's Dakota-custodied wallet. The caller never holds a key.

**Supported asset: USDC only**, on Base (`base` / `eip155:8453`) and Base Sepolia (`base-sepolia` / `eip155:84532`). A seller pricing in any other token, or on any other network, is refused with a 403 naming the supported set; no signature is issued and no budget is held.

Issuing this signature IS spending money: it is an EIP-3009 `TransferWithAuthorization` that any holder can settle on-chain until `validBefore` passes, with no further approval from us. So both controls run here, before any signature exists: the seller's `payTo` is screened for sanctions and other high-risk activity, and the agent's x402 mandate is evaluated together with a hold recorded against its budget, atomically.

A refusal is a 403 naming the reason. If the payee cannot be screened the payment is refused with a 503, never signed unscreened; retry it.

Idempotent per X-Idempotency-Key: a retry with the same key and the same payment returns the SAME authorization (same nonce, same validity window), signed again - never a second one - so at most one can settle. The response is never cached: the signed header is a bearer instrument.




## OpenAPI

````yaml /openapi.yaml post /payment-agents/{payment_agent_id}/x402/signatures
openapi: 3.0.3
info:
  title: Dakota Platform API
  version: 1.0.0
  description: >-
    Combined API specification for Dakota Platform services:

    - Issuance API: Asset minting and burning operations

    - Onboarding API: Know Your Business/Customer verification

    - On/Off Ramp API: Managing on-ramp and off-ramp accounts

    - Recipients API: Managing destinations for KYB'd entities

    - Transactions API: Viewing transaction history across platform operations


    ## Authentication and API Headers


    All API endpoints require the following headers:


    - `X-Idempotency-Key`: Required for all POST endpoints to ensure request
    idempotency

    - `x-api-key`: Required for authentication across all endpoints


    Note: On /applications endpoints you need a token for authentication instead
    of a x-api-key

    - `x-application-token`: Required for authentication on public /applications
    endpoints (alternative to `x-api-key` where documented)



    ## Rate Limits


    Requests are rate limited per API key. Every response includes the following
    headers:


    | Header | Description |

    | --- | --- |

    | `X-RateLimit-Limit` | Maximum requests allowed in the current one-minute
    window. |

    | `X-RateLimit-Remaining` | Requests remaining in the current window. |

    | `X-RateLimit-Reset` | Absolute Unix timestamp (seconds since epoch) when
    the current rate-limit window resets. |


    When a request is throttled (`429`), responses also include `Retry-After`
    with seconds to wait before retrying.
servers:
  - url: https://api.platform.dakota.xyz
    description: Production environment
  - url: https://api.platform.sandbox.dakota.xyz
    description: Sandbox — safe for testing with simulated data
security:
  - ApiKeyAuth: []
tags:
  - name: Agentic Payments
    x-beta: true
    description: >-
      Beta — agent-driven payments: provision agents, draft and approve spending
      mandates, accept reviewed instructions, and manage scheduled payments.


      **Prerequisites:** Customer onboarded; signer groups attached for
      recognition.

      **Related:** Wallets, Signer Groups, Transactions
  - name: Mandates
    x-beta: true
    description: >-
      Beta — spending mandates: signed, signer-bound authorizations governing
      what may be spent, approved or cancelled by a second recognized signer (§8
      — the dual-control rule that every mandate mutation must be signed by a
      recognized signer OTHER than the bound one). Independent of agents and
      scheduled payments.


      **Prerequisites:** Signer groups attached for recognition.

      **Related:** Signer Groups, Transactions
  - name: Insights
    x-beta: true
    description: >-
      Beta — read-only insight: a deterministic report over a customer's agentic
      activity (funding balances, upcoming obligations, failures, mandate
      headroom and expiry), or — via `GET /insights` — over the whole client's
      book, with portfolio KPIs, daily series and a per-customer roll-up. Never
      moves money, never creates or changes anything.


      **Prerequisites:** Customer onboarded; insight is computed from the
      customer's scheduled payments, mandates, and wallets.

      **Related:** Agentic Payments, Mandates
  - name: Customers
    description: >-
      Manage customer entities representing businesses and organizations
      onboarded to Dakota.


      **Prerequisites:** Complete KYB via Onboarding endpoints before initiating
      money movement.

      **Related:** Onboarding, Recipients, Transactions, Accounts, Wallets
  - name: Wallets
    description: >-
      Manage wallets, balances, and wallet-to-signer-group relationships for
      custody and movement controls.


      **Prerequisites:** Customer must exist. Configure signer groups before
      policy-enforced workflows.

      **Related:** Signer Groups, Policies, Transactions, Customers
  - name: Transactions
    description: >-
      Create, cancel, and retrieve transaction records across account and wallet
      flows.


      **Prerequisites:** Accounts or destinations must be configured based on
      flow type.

      **Related:** Accounts, Recipients, Policies, Events
  - name: Recipients
    description: >-
      Manage recipient entities and destination rails used by customers for
      payouts and transfers.


      **Prerequisites:** Customer must be onboarded and active.

      **Related:** Customers, Transactions, Accounts, Onboarding
  - name: Accounts
    description: >-
      Manage account resources used for onramp, offramp, and swap operations.


      **Prerequisites:** Customer must be created and network/asset constraints
      must be known.

      **Related:** Customers, Transactions, Auto Transactions, Info
  - name: Auto Transactions
    description: >-
      Manage automated transaction configurations and execution history for
      account automation workflows.


      **Prerequisites:** Source account must exist and be configured for
      automation.

      **Related:** Accounts, Transactions, Events
  - name: Onboarding
    description: >-
      Manage KYB/KYC onboarding lifecycle, application documents, attestations,
      and verification steps.


      **Prerequisites:** Customer context and required entity/application
      metadata.

      **Related:** Customers, Exceptions, Recipients, Transactions
  - name: Policies
    description: >-
      Define and manage policy objects and rules used for transaction governance
      and risk controls.


      **Prerequisites:** Wallet and signer group resources should be configured
      for enforcement scenarios.

      **Related:** Wallets, Signer Groups, Transactions
  - name: Signer Groups
    description: >-
      Manage signer groups and signer assignments for multi-party authorization
      models.


      **Prerequisites:** Wallets should exist before linking signer groups.

      **Related:** Wallets, Policies, Transactions
  - name: Authentication
    description: >-
      Manage API authentication credentials and key lifecycle for platform
      access.


      **Prerequisites:** Client organization must be provisioned.

      **Related:** Users, Info
  - name: Users
    description: >-
      Manage client users, roles, and identity metadata for platform access
      control.


      **Prerequisites:** Auth credentials and client context must be
      established.

      **Related:** Authentication
  - name: Webhooks
    description: >-
      Manage outbound webhook targets and delivery configuration for event
      notifications.


      **Prerequisites:** Subscriber endpoint must be reachable and secured.

      **Related:** Events, Authentication
  - name: Payouts
    description: >-
      Manage where Dakota sends your accrued developer-fee payouts.


      **Prerequisites:** Auth credentials and client context must be
      established.

      **Related:** Events
  - name: RD Marketing Fee
    description: >-
      Everything behind your RD marketing fee: read what a month came to,
      declare the wallets you hold outside Dakota so the RD in them counts, and
      say where the fee should be sent.


      **Prerequisites:** Client must be in the RD marketing-fee programme. A
      month is readable once it has closed.

      **Related:** Wallets, Events
  - name: Self Serve
    description: >-
      Buy and track prepaid credits, and read the tiers and pricing they are
      sold at.


      **Prerequisites:** Auth credentials and client context must be
      established.

      **Related:** Billing
  - name: Events
    description: >-
      Retrieve event records emitted by platform operations for audit and
      troubleshooting.


      **Prerequisites:** Requesting client must have access to referenced
      resources.

      **Related:** Webhooks, Transactions, Onboarding
  - name: Info
    description: >-
      Read platform capability metadata, such as supported rails, networks, and
      assets.

      These operations are served under `/capabilities/*` - `GET
      /capabilities/countries`

      and `GET /capabilities/networks`. The tag name does not appear in the
      request paths.


      **Prerequisites:** Valid authentication headers.

      **Related:** Accounts, Transactions
  - name: Sandbox
    description: >-
      Trigger sandbox-only simulation endpoints for safe end-to-end integration
      testing with synthetic data. The sandbox host
      (`https://api.platform.sandbox.dakota.xyz`) also accepts a family of
      `X-Sandbox-*` request headers on most write endpoints (`Customers`,
      `Accounts`, `Transactions`, simulate endpoints) that let integrators drive
      deterministic failure modes — pick a preset via `X-Sandbox-Scenario`, or
      compose a custom one with
      `X-Sandbox-Error-Step`/`X-Sandbox-Error-Status`/`X-Sandbox-Error-Message`.
      `X-Sandbox-Instant-Completion` collapses async flows to a single
      synchronous step, and `X-Sandbox-Skip-Auto-Approval` keeps newly created
      KYB applications in `pending` for manual-review testing. All `X-Sandbox-*`
      headers are ignored in production.


      **Prerequisites:** Sandbox environment and test customer data.

      **Related:** Customers, Accounts, Transactions, Onboarding
  - name: Legal
    description: |-
      The legal documents customers accept — terms of service, privacy policy,
      e-sign notice, and partner agreements.

      Dakota publishes these here, and this is the authoritative source: the
      hosted onboarding flow, the dakota.xyz website, and your own integration
      all read the same revisions. Present the current revision to your customer
      before capturing their acceptance so the record reflects the text they
      actually saw.
paths:
  /payment-agents/{payment_agent_id}/x402/signatures:
    post:
      tags:
        - Agentic Payments
      summary: Sign an x402 payment authorization (BETA)
      description: >
        > **Beta** — early access.


        Returns the `X-PAYMENT` header for a seller's 402 challenge, signed by
        the agent's Dakota-custodied wallet. The caller never holds a key.


        **Supported asset: USDC only**, on Base (`base` / `eip155:8453`) and
        Base Sepolia (`base-sepolia` / `eip155:84532`). A seller pricing in any
        other token, or on any other network, is refused with a 403 naming the
        supported set; no signature is issued and no budget is held.


        Issuing this signature IS spending money: it is an EIP-3009
        `TransferWithAuthorization` that any holder can settle on-chain until
        `validBefore` passes, with no further approval from us. So both controls
        run here, before any signature exists: the seller's `payTo` is screened
        for sanctions and other high-risk activity, and the agent's x402 mandate
        is evaluated together with a hold recorded against its budget,
        atomically.


        A refusal is a 403 naming the reason. If the payee cannot be screened
        the payment is refused with a 503, never signed unscreened; retry it.


        Idempotent per X-Idempotency-Key: a retry with the same key and the same
        payment returns the SAME authorization (same nonce, same validity
        window), signed again - never a second one - so at most one can settle.
        The response is never cached: the signed header is a bearer instrument.
      operationId: createX402Signature
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
        - name: payment_agent_id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/X402SignatureRequest'
            example:
              resource_url: https://api.marketpulse.example/v1/reports/copper-spot
              payment_requirements:
                scheme: exact
                network: base-sepolia
                maxAmountRequired: '100000'
                resource: https://api.marketpulse.example/v1/reports/copper-spot
                payTo: '0x94aE0f8B9F3c2A1d5E6b7C8D9e0F1a2B3c4D5E6F'
                asset: '0x036CbD53842c5426634e7929541eC2318f3dCF7e'
                maxTimeoutSeconds: 120
                extra:
                  name: USDC
                  version: '2'
      responses:
        '200':
          description: The signed payment authorization
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/X402SignatureResponse'
              example:
                payment_header: >-
                  eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoiYmFzZS1zZXBvbGlhIn0
                payment_header_name: X-PAYMENT
                signature: >-
                  0x9f2b1c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b1c001c
                authorization_id: 2vWxX402Hold000000000000001
                mandate_id: 2vWxX402Mandate000000000001
                payer: '0x8f2A55949038A9610F50FB23B5883Af3B4ecB3a1'
                pay_to: '0x94aE0f8B9F3c2A1d5E6b7C8D9e0F1a2B3c4D5E6F'
                value: '100000'
                nonce: >-
                  0x3f1c8a5b2d7e4906c1a3f85b2e6d04971c8a5b3f2d7e4906c1a3f85b2e6d0497
                valid_before: '2026-09-08T00:02:00Z'
                window_committed: '100000'
        '400':
          description: >
            Malformed agent id or payment requirements, an unsupported scheme,
            network or x402 version, or the agent is not active
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '401':
          description: |
            Missing or invalid credentials
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '403':
          description: >
            The payment was refused - the caller lacks the permission this route
            requires, the customer is frozen, the seller's address failed
            screening, or the agent's x402 mandate refused it (over a limit,
            outside the payee policy, expired, or absent)
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '404':
          description: >
            Agentic payments are not enabled for the client, x402 is not enabled
            for the agent (enable it with POST
            /payment-agents/{payment_agent_id}/x402), or the agent was not found
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '409':
          description: >
            The X-Idempotency-Key was already used for a different payment, or
            the authorization issued under it has expired or was released —
            retry with a new key. A key whose payment already SETTLED is also
            refused here, and that one must not be retried: the detail names the
            transaction, and a new key would pay again.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '429':
          description: |
            Too many requests; back off and retry
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '500':
          description: |
            Internal error
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '501':
          description: |
            The wallet provider does not support this operation
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        '503':
          description: >
            The seller's address could not be screened. Nothing was signed and
            no budget was held; retry the payment.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
components:
  parameters:
    IdempotencyKeyHeader:
      name: x-idempotency-key
      in: header
      required: true
      description: >-
        Unique key to ensure request idempotency. If the same key is used within
        a certain time window, the original response will be returned instead of
        executing the request again.
      schema:
        type: string
        format: uuid
  schemas:
    X402SignatureRequest:
      type: object
      required:
        - payment_requirements
      properties:
        payment_requirements:
          $ref: '#/components/schemas/X402PaymentRequirements'
        resource_url:
          type: string
          description: >
            The 402-metered URL being paid for. Required when the mandate
            restricts payees by domain.
        x402_version:
          type: integer
          enum:
            - 1
            - 2
          description: >
            The x402 version the seller spoke — `x402Version` in its 402
            response. Decides how the signed payment is packaged: v1 as the
            `X-PAYMENT` header, v2 as `PAYMENT-SIGNATURE`. Defaults to 1.
    X402SignatureResponse:
      type: object
      required:
        - payment_header
        - payment_header_name
        - signature
        - authorization_id
        - mandate_id
        - payer
        - pay_to
        - value
        - nonce
        - valid_before
        - window_committed
      properties:
        payment_header:
          type: string
          description: >
            The payment header's value — base64 of the payment payload — to send
            in the header named by `payment_header_name`.
        payment_header_name:
          type: string
          enum:
            - X-PAYMENT
            - PAYMENT-SIGNATURE
          description: >
            The request header the seller expects the payment in: `X-PAYMENT`
            for x402 v1, `PAYMENT-SIGNATURE` for v2.
        signature:
          type: string
        authorization_id:
          type: string
          description: The hold this authorization is recorded against.
        mandate_id:
          type: string
        payer:
          type: string
        pay_to:
          type: string
        value:
          type: string
        nonce:
          type: string
        valid_before:
          type: string
          format: date-time
        window_committed:
          type: string
          description: Committed spend in the mandate's window after this authorization.
    ProblemDetails:
      type: object
      required:
        - type
        - title
        - status
      description: |
        Error response following RFC 9457 Problem Details.
        Public API error responses use this format.
      example:
        type: https://docs.dakota.xyz/api-reference/errors#not-found
        title: Customer Not Found
        status: 404
        detail: Customer cst_2abc123 was not found in your organization.
        instance: https://api.platform.dakota.xyz/customers/cst_2abc123
        request_id: req_7f3a8b2c
      properties:
        type:
          type: string
          format: uri
          description: |
            URI reference identifying the problem type.
            Resolves to human-readable documentation.
          example: https://docs.dakota.xyz/api-reference/errors#not-found
        title:
          type: string
          description: >-
            Short, human-readable summary of the problem type. Stable across
            occurrences.
          example: Customer Not Found
        status:
          type: integer
          description: HTTP status code for this occurrence.
          example: 404
        detail:
          type: string
          description: Human-readable explanation specific to this occurrence.
          example: Customer cst_2abc123 was not found in your organization.
        instance:
          type: string
          format: uri
          description: The request path that triggered this error.
          example: https://api.platform.dakota.xyz/customers/cst_2abc123
        request_id:
          type: string
          description: Unique request identifier. Include when contacting support.
          example: req_7f3a8b2c
        errors:
          type: array
          description: Field-level validation errors (present for validation failures).
          items:
            $ref: '#/components/schemas/ValidationError'
        resolution_url:
          type: string
          format: uri
          description: |
            A link the customer can follow to CLEAR this error, present only on
            problems with a concrete self-service remedy.

            Today this is returned by
            `#terms-not-accepted`, where it points at the hosted flow in which
            the outstanding agreement can be signed. The link is token-gated and
            usable as-is — send the customer to it directly rather than parsing
            it out of `detail`.
          example: >-
            https://onboarding.dakota.xyz/applications/2abc123?token=tok_7f3a8b2c
        user_message:
          type: string
          description: |
            A plain-language rendition of `detail` written for the end
            customer, present when one exists for this error. `detail` names
            request fields and actions so a machine caller (such as a payment
            agent drafting proposals) can self-correct; `user_message` says the
            same thing without API vocabulary. Clients that relay errors into a
            human surface (chat, email, UI) should show `user_message` when
            present and fall back to `detail`.
          example: >-
            ACH payments pay out USD, so a USDC payout isn't possible on this
            rail. Change the payout currency to USD and try again.
    X402PaymentRequirements:
      type: object
      description: >
        One payment option from a seller's 402 response, forwarded verbatim.
        Field names are the x402 protocol's own, not Dakota's. Both protocol
        versions are accepted: v1 terms carry `maxAmountRequired`, v2 terms
        carry `amount` and a CAIP-2 network.
      required:
        - scheme
        - network
        - payTo
        - asset
      properties:
        scheme:
          type: string
          description: Payment scheme. Only "exact" is supported.
        network:
          type: string
          description: >
            The seller's network, in either spelling: v1 (`base-sepolia`,
            `base`) or v2 CAIP-2 (`eip155:84532`, `eip155:8453`).
        maxAmountRequired:
          type: string
          description: Price in atomic units (x402 v1).
        amount:
          type: string
          description: Price in atomic units (x402 v2).
        resource:
          type: string
        description:
          type: string
        mimeType:
          type: string
        payTo:
          type: string
          description: The seller's receiving address.
        asset:
          type: string
          description: >
            Token contract address. Only USDC's contract on Base or Base Sepolia
            is payable; any other token is refused with a 403.
        maxTimeoutSeconds:
          type: integer
          description: How long the seller will accept this authorization.
        extra:
          $ref: '#/components/schemas/X402PaymentRequirementsExtra'
    ValidationError:
      type: object
      required:
        - field
        - message
      properties:
        field:
          type: string
          description: Field path using dot notation for nested fields.
          example: bank_account.routing_number
        message:
          type: string
          description: Human-readable description of the field error.
          example: Routing number must be exactly 9 digits
        code:
          type: string
          description: Machine-readable error code for this field.
          example: invalid_format
    X402PaymentRequirementsExtra:
      type: object
      description: >
        Token identity, which the EIP-712 domain is built from. A wrong name or
        version yields a signature that recovers to the wrong address.
      properties:
        name:
          type: string
        version:
          type: string
        assetTransferMethod:
          type: string
          description: >-
            x402 v2's transfer method, e.g. `eip3009`. Echoed back in the v2
            payload.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````