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

# Decode a QR code

> Decode an External QR without creating a Payment, reserving a priced quote, or changing Stableyard financial state. Returns the same nullable qrInfo fields for all supported routes, including PH/KE and VN. Existing payable, merchant, manualBankTransfer, providerReferenceId and destinationAmount fields remain available. QR amountUsd and fee are indicative provider decode metadata, not the binding payment quote or combined Stableyard fees; use POST /v2/payments for funding amounts and funding.totalFees. Missing decoded values are null, never assumed zero. A zero sentinel on a classified static/personal QR becomes null unless explicitly dynamic; actual Payments still require a positive amount. The request accepts only sender, country and qrPayload. QR rejection returns 400; invalid upstream responses return 502; transient provider failures return 503. payable describes destination classification, not approval to move funds. The sender UPA must already have an active account link for the selected provider route. QR contents and decoded account numbers are sensitive; do not log or persist raw decode responses.

Decode and classify an External QR before creating a Payment. This does not reserve a priced quote or move funds. Use Payment creation for binding funding amounts and fees. QR contents and decoded account numbers are sensitive; do not log or persist raw decode responses.


## OpenAPI

````yaml openapi.json POST /v2/payments/decode-qr
openapi: 3.1.0
info:
  title: Stableyard Partner API
  version: 2.0.0-staging
  x-stableyard-api-version: '2026-09-09'
  x-stableyard-supported-api-versions:
    - '2026-09-09'
  summary: Backend API for UPAs, Payments, activity, and optional financial products.
  description: >

    Use this API from a trusted partner backend with an app ID and app secret.


    ## Recommended integration


    1. Call `GET /v2/partners/config` to verify credentials and discover enabled
    capabilities.

    2. Create a UPA only when your product needs a persistent Stableyard
    account.

    3. Create a receive or send Payment with `POST /v2/payments`.

    4. Redirect a payer to the returned `paymentUrl` or pass the Payment
    credentials to an official Stableyard interface SDK.

    5. Process signed webhooks and fetch the Payment by ID for reconciliation.


    Checkout execution and account-bound browser endpoints are intentionally
    documented in the separate Interfaces & SDKs reference. Console endpoints
    are dashboard implementation details and are not part of the partner
    integration contract.
  x-stableyard-documentation-surface: partner
servers:
  - url: https://prod-api.stableyard.fi
    description: Production
  - url: https://staging-api-v2.stableyard.fi
    description: Staging
  - url: http://localhost:3001
    description: Local
security: []
tags:
  - name: Authentication
    x-displayName: API authentication
    description: Verify your app ID and app secret before calling UPA APIs.
  - name: Accounts
    x-displayName: UPA Accounts
    description: Create Universal Payment Accounts and manage account settings.
  - name: Deposit Addresses
    description: Create reusable receive addresses and verify inbound deposits.
  - name: Identity & KYC
    description: >-
      Verify the UPA email and run provider-neutral identity verification.
      Managed vaults and fiat payment rails use this same verified UPA identity.
  - name: Vaults
    description: >-
      Create Safe/Zodiac controlled stablecoin vaults and manage policy updates
      for accounts.
  - name: Payments
    description: >-
      Create escrow-first payments, issue partner-authenticated send
      instructions or executions, power public checkout, and reconcile
      collection through final account settlement.
  - name: Balances & Transactions
    description: >-
      Read Stableyard-posted financial activity. Balances are ledger projections
      of activity Stableyard processed; they are not live balances of externally
      controlled wallets.
paths:
  /v2/payments/decode-qr:
    post:
      tags:
        - Payments
      summary: Preview a QR code's decode and classification
      description: >-
        Decode an External QR without creating a Payment, reserving a priced
        quote, or changing Stableyard financial state. Returns the same nullable
        qrInfo fields for all supported routes, including PH/KE and VN. Existing
        payable, merchant, manualBankTransfer, providerReferenceId and
        destinationAmount fields remain available. QR amountUsd and fee are
        indicative provider decode metadata, not the binding payment quote or
        combined Stableyard fees; use POST /v2/payments for funding amounts and
        funding.totalFees. Missing decoded values are null, never assumed zero.
        A zero sentinel on a classified static/personal QR becomes null unless
        explicitly dynamic; actual Payments still require a positive amount. The
        request accepts only sender, country and qrPayload. QR rejection returns
        400; invalid upstream responses return 502; transient provider failures
        return 503. payable describes destination classification, not approval
        to move funds. The sender UPA must already have an active account link
        for the selected provider route. QR contents and decoded account numbers
        are sensitive; do not log or persist raw decode responses.
      operationId: decodeQr
      parameters:
        - name: Stableyard-Version
          in: header
          required: false
          schema:
            type: string
            enum:
              - '2026-09-09'
          description: >-
            Optional contract-version assertion. Omit it to use the app
            environment's pinned version. A different supported version is
            accepted only after that environment is explicitly migrated.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DecodeQrRequest'
            examples:
              personalQr:
                summary: Preview a Philippines QR code
                value:
                  sender:
                    accountId: acct_sender
                  country: PH
                  qrPayload: 00020101021127590012com.p2pqrpay...
      responses:
        '200':
          description: QR decode preview
          headers:
            Stableyard-Version:
              description: >-
                Effective date-based Stableyard API contract version for this
                response.
              schema:
                type: string
                enum:
                  - '2026-09-09'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecodeQrResponse'
              examples:
                personalQr:
                  summary: Personal QR -- not payable through this rail
                  description: >-
                    Fictional sample details for documentation only; do not use
                    for real transfers.
                  value:
                    payable: false
                    merchant:
                      displayName: Alex Sample
                      country: PH
                      business: false
                    accountNumber: '000000000001'
                    qrInfo:
                      country: PH
                      currency: PHP
                      amount: null
                      txId: scan_reference_123
                      merchant: Alex Sample
                      beneficiaryName: Alex Sample
                      bank:
                        code: EXAMPLE_BANK_PH
                        name: Example Bank
                      amountUsd: null
                      fee: null
                    manualBankTransfer:
                      accountNumber: '000000000001'
                      bankCode: EXAMPLE_BANK_PH
                      accountHolderName: Alex Sample
                businessQr:
                  summary: Business QR -- payable through this rail
                  value:
                    payable: true
                    merchant:
                      displayName: Corner Store PH
                      country: PH
                      business: true
                      dynamic: true
                    accountNumber: null
                    qrInfo:
                      country: PH
                      currency: PHP
                      amount: '52.00'
                      txId: scan_reference_456
                      merchant: Corner Store PH
                      beneficiaryName: null
                      bank: null
                      amountUsd: '0.912345'
                      fee: '0.02'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          $ref: '#/components/responses/Conflict'
        '424':
          $ref: '#/components/responses/FailedDependency'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '502':
          $ref: '#/components/responses/BadGateway'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
      security:
        - partnerBasicAuth: []
components:
  schemas:
    DecodeQrRequest:
      type: object
      additionalProperties: false
      required:
        - sender
        - country
        - qrPayload
      properties:
        sender:
          type: object
          additionalProperties: false
          required:
            - accountId
          properties:
            accountId:
              type: string
              example: acct_123
        country:
          type: string
          pattern: ^[A-Z]{2}$
          example: PH
        qrPayload:
          type: string
          minLength: 1
          maxLength: 4096
    DecodeQrResponse:
      type: object
      additionalProperties: false
      required:
        - payable
        - merchant
        - accountNumber
        - qrInfo
      properties:
        accountNumber:
          type:
            - string
            - 'null'
          maxLength: 64
          description: >-
            Decoded destination account number when returned; preserve leading
            zeros. Sensitive data, not a linked bank account or an authorization
            to pay.
        qrInfo:
          $ref: '#/components/schemas/DecodedQrInfo'
        payable:
          type: boolean
          description: >-
            False for a personal/peer-to-peer QR classification -- not payable
            through POST /v2/payments.
        merchant:
          type: object
          additionalProperties: false
          properties:
            displayName:
              type: string
            country:
              type: string
              pattern: ^[A-Z]{2}$
            rail:
              type: string
            dynamic:
              type: boolean
            business:
              type: boolean
        manualBankTransfer:
          type: object
          description: >-
            Present only when payable is false and the provider returned a
            manual bank-transfer destination.
          additionalProperties: false
          required:
            - accountNumber
          properties:
            accountNumber:
              type: string
            bankCode:
              type: string
            accountHolderName:
              type: string
        providerReferenceId:
          type: string
        destinationAmount:
          type: object
          description: >-
            Present only for a dynamic QR that embeds a fixed amount; absent for
            a static/amount-flexible QR.
          additionalProperties: false
          required:
            - amount
            - currency
          properties:
            amount:
              type: string
              minLength: 1
              maxLength: 100
              example: '50.00'
            currency:
              type: string
              example: PHP
    DecodedQrInfo:
      type: object
      additionalProperties: false
      required:
        - country
        - currency
        - amount
        - txId
        - merchant
        - beneficiaryName
        - bank
        - amountUsd
        - fee
      description: >-
        Normalized, allowlisted QR display metadata. Keys are always present;
        unknown values are null. Amounts are exact decimal strings. Decode
        metadata is not a locked Payment quote.
      properties:
        country:
          type:
            - string
            - 'null'
          pattern: ^[A-Z]{2}$
        currency:
          type:
            - string
            - 'null'
          pattern: ^[A-Z0-9]{2,12}$
        amount:
          type:
            - string
            - 'null'
          pattern: ^(0|[1-9][0-9]{0,17})(\.[0-9]{1,6})?$
          description: >-
            Fiat amount encoded in the QR, in currency. Null when no amount was
            returned, including a zero sentinel on a classified static/personal
            QR unless explicitly dynamic. The payer supplies a positive amount
            when creating the Payment.
        txId:
          type:
            - string
            - 'null'
          maxLength: 200
          description: >-
            Decode reference, if supplied. Never submit it as payout
            authorization; Payment creation revalidates the QR.
        merchant:
          type:
            - string
            - 'null'
          maxLength: 200
        beneficiaryName:
          type:
            - string
            - 'null'
          maxLength: 200
        bank:
          type:
            - object
            - 'null'
          additionalProperties: false
          required:
            - code
            - name
          properties:
            code:
              type:
                - string
                - 'null'
              maxLength: 64
            name:
              type:
                - string
                - 'null'
              maxLength: 200
        amountUsd:
          type:
            - string
            - 'null'
          pattern: ^(0|[1-9][0-9]{0,17})(\.[0-9]{1,6})?$
          description: >-
            Provider-reported indicative USD amount, when decoding supplies one.
            Not funding.required.
        fee:
          type:
            - string
            - 'null'
          pattern: ^(0|[1-9][0-9]{0,17})(\.[0-9]{1,6})?$
          description: >-
            Provider-reported decode fee. Not a locked fee and does not include
            Stableyard or app fees. Use the Payment funding quote for payable
            amounts and fee currency.
    ErrorResponse:
      type: object
      additionalProperties: false
      required:
        - error
      properties:
        error:
          type: object
          additionalProperties: false
          required:
            - code
            - message
          properties:
            code:
              type: string
              minLength: 1
              maxLength: 128
              example: bad_request
            message:
              type: string
              minLength: 1
              maxLength: 1000
              example: The request is invalid
            details: {}
  responses:
    BadRequest:
      description: Bad request
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: BadRequest response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    Unauthorized:
      description: Unauthorized
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: Unauthorized response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    Forbidden:
      description: The app secret does not include the required scope
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: Forbidden response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    NotFound:
      description: Not found
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: NotFound response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    Conflict:
      description: Conflict
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: Conflict response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    FailedDependency:
      description: Required chain, network, or provider configuration is missing
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: FailedDependency response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    TooManyRequests:
      description: >-
        Rate limit, payment-option limit, selection cooldown, or temporary abuse
        block
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
        Retry-After:
          description: Seconds until the caller should retry.
          schema:
            type: integer
            minimum: 1
        RateLimit-Limit:
          description: Quota for the most constrained policy.
          schema:
            type: integer
            minimum: 1
        RateLimit-Remaining:
          description: Requests remaining in that policy window.
          schema:
            type: integer
            minimum: 0
        RateLimit-Reset:
          description: Seconds until that policy window resets.
          schema:
            type: integer
            minimum: 0
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: TooManyRequests response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    BadGateway:
      description: Payment provider returned an error
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: BadGateway response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
    ServiceUnavailable:
      description: Payment provider or escrow provisioning is unavailable
      headers:
        Stableyard-Version:
          description: >-
            Effective date-based Stableyard API contract version for this
            response.
          schema:
            type: string
            enum:
              - '2026-09-09'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          examples:
            example:
              summary: ServiceUnavailable response
              value:
                error:
                  code: bad_request
                  message: The request is invalid
                  details: example
  securitySchemes:
    partnerBasicAuth:
      type: http
      scheme: basic
      description: >-
        HTTP Basic auth. Username is the Stableyard app ID. Password is the app
        secret. The optional Stableyard-Version request header must match the
        environment pin.

````

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