Halliday Payments API

Core payment operations including quotes, confirmation, and status tracking

OpenAPI Specification

halliday-payments-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Halliday API V2 Assets Payments API
  description: 'API V2 for Halliday''s payment infrastructure, supporting onramps, swaps, and offramps.


    This API provides a unified interface for cryptocurrency payments, allowing developers to:

    - Quote payments across multiple providers

    - Execute payments with onramps, swaps, and offramps

    - Track payment status and history


    ## Authentication


    API key authentication is required for all endpoints.

    '
  version: 2.0.0
  contact:
    name: Contact Halliday
    url: https://halliday.xyz
    email: support@halliday.xyz
servers:
- url: https://v2.prod.halliday.xyz
  description: Base domain
security:
- ApiKeyAuth: []
tags:
- name: Payments
  description: Core payment operations including quotes, confirmation, and status tracking
paths:
  /payments:
    get:
      summary: Get payment status
      description: 'Get the current status of a payment, including progress through onramp/swap/offramp stages.

        '
      operationId: getPaymentStatus
      tags:
      - Payments
      parameters:
      - name: payment_id
        in: query
        required: true
        description: Payment identifier to check
        schema:
          type: string
      responses:
        '200':
          description: Payment status retrieved successfully!
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentStatus'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: 'Missing required parameter: payment_id'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Invalid API key
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: You do not have permission to view this payment
        '404':
          description: Payment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Payment with payment_id 'pay_abc123' not found
  /payments/history:
    get:
      summary: Get payment history
      description: 'Retrieve a paginated list of payment statuses filtered by owner.

        Returns an array of payment status objects and a pagination key for fetching the next page.

        '
      operationId: getPaymentHistory
      tags:
      - Payments
      parameters:
      - name: owner_address
        in: query
        required: false
        description: Owner address to filter payments by
        schema:
          type: string
      - name: pagination_key
        in: query
        required: false
        description: Pagination key from previous response to fetch next page
        schema:
          type: string
      - name: limit
        in: query
        required: false
        description: Maximum number of results to return
        schema:
          type: number
      - name: id_query
        in: query
        required: false
        description: Filter payments by ID
        schema:
          type: string
      - name: dest_address
        in: query
        required: false
        description: Filter payments by destination address
        schema:
          type: string
      - name: category
        in: query
        required: false
        description: Filter payments by category
        schema:
          type: string
          enum:
          - ALL
          - NEW_OR_FUNDED
          default: NEW_OR_FUNDED
      - name: label
        in: query
        required: false
        description: Filter payments by label
        schema:
          type: string
      responses:
        '200':
          description: Payment history retrieved successfully
          content:
            application/json:
              schema:
                type: object
                required:
                - payment_statuses
                - next_pagination_key
                properties:
                  payment_statuses:
                    type: array
                    items:
                      $ref: '#/components/schemas/PaymentStatus'
                    description: Array of payment status objects
                  next_pagination_key:
                    anyOf:
                    - type: string
                    - type: 'null'
                    description: Pagination key to fetch the next page of results
                    example: 42ff9b02-037f-4a90-87fb-a4d2ca128565_2025-11-12T22:08:52.517Z
              example:
                payment_statuses:
                - payment_id: <string>
                  status: COMPLETE
                  funded: true
                  created_at: '2025-11-12T20:15:30.000Z'
                  updated_at: '2025-11-12T20:25:45.000Z'
                  initiate_fund_by: '2025-11-12T21:15:30.000Z'
                  completed_at: '2025-11-12T20:25:45.000Z'
                  quoted:
                    output_amount:
                      asset: ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
                      amount: '100.00'
                    fees:
                      total_fees: '3.50'
                      conversion_fees: '2.00'
                      network_fees: '1.00'
                      business_fees: '0.50'
                      currency_symbol: USD
                    onramp: stripe
                    onramp_method: credit_card
                    route:
                    - type: ONRAMP
                      net_effect:
                        consume:
                        - account: USER
                          resource:
                            asset: usd
                            property: BALANCE
                          amount:
                            amount: '103.50'
                        produce:
                        - account: PROCESSING_ADDRESS
                          resource:
                            asset: ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
                            property: BALANCE
                          amount:
                            amount: '100.00'
                      pieces_info:
                      - type: onramp
                      step_index: 0
                  fulfilled:
                    output_amount:
                      asset: ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
                      amount: '100.00'
                    fees:
                      total_fees: '3.50'
                      conversion_fees: '2.00'
                      network_fees: '1.00'
                      business_fees: '0.50'
                      currency_symbol: USD
                    onramp: stripe
                    onramp_method: credit_card
                    route:
                    - status: COMPLETE
                      type: ONRAMP
                      net_effect:
                        consume:
                        - account: USER
                          resource:
                            asset: usd
                            property: BALANCE
                          amount:
                            amount: '103.50'
                        produce:
                        - account: PROCESSING_ADDRESS
                          resource:
                            asset: ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
                            property: BALANCE
                          amount:
                            amount: '100.00'
                      pieces_info:
                      - type: onramp
                      step_index: 0
                      transaction_hash: '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef'
                  current_prices:
                    USD: '1.00'
                    ethereum:0x: '4200.00'
                    ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48: '1.00'
                  price_currency: USD
                  processing_addresses:
                  - chain: ethereum
                    address: 0xaddress...
                  owner_address: 0xowner...
                  destination_address: 0xdest...
                next_pagination_key: 42ff9b02-037f-4a90-87fb-a4d2ca128565_2025-11-12T22:08:52.517Z
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: 'Missing required parameter: owner_address'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Invalid API key
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: You do not have permission to access payment history for this address
  /payments/quotes:
    post:
      summary: Get payment quotes
      description: 'Request quotes for payments, supporting both fixed input and fixed output scenarios.

        Returns multiple quote options with pricing, fees, and routing information.


        This endpoint can also be used to requote from an existing payment by providing a payment_id.

        When requoting, input amounts are automatically derived from

        the payment''s current state, but you can optionally override the output asset.

        '
      operationId: getPaymentQuotes
      tags:
      - Payments
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuoteRequest'
      responses:
        '200':
          description: Successful quote response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: amount
                  given: '5'
                  limits:
                    min: '10'
                    max: '10000'
                  source: moonpay
                  message: Amount too low. Minimum amount is $10 USD
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: API key missing or invalid
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Your API key does not have permission to create quotes
  /payments/confirm:
    post:
      summary: Confirm a payment
      description: 'Confirm a previously quoted payment and receive deposit instructions.

        Returns information on how to fund the payment (widget URL, contract address, etc.).


        If a payment output is >= $300 USD, the owner address will need to produce a EVM_OWNER

        signature. The response will include a USER_VERIFY next_instruction instead of funding

        details. In this case, prompt the user to sign the verification payloads via signTypedData,

        then submit a ContinueConfirmPaymentRequest to this same endpoint to complete confirmation.

        Once an owner address has produced an EVM_OWNER signature, subsequent payments with that

        owner address will not require the signature again.

        '
      operationId: confirmPayment
      tags:
      - Payments
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
              - title: ConfirmPaymentRequest
                description: Initial payment confirmation request.
                type: object
                required:
                - payment_id
                - state_token
                - owner_address
                - destination_address
                properties:
                  payment_id:
                    type: string
                    description: ID of the payment from the quote to confirm
                  state_token:
                    type: string
                    description: State token from the quote response
                  owner_address:
                    type: string
                    description: Owner address for the payment. This is the address that the payment will be sent from.
                  destination_address:
                    type: string
                    description: Destination address for the payment. This is the address that the payment will be sent to.
                  client_redirect_url:
                    type: string
                    format: uri
                    description: Optional URL to redirect users to after an onramp flow completes.
                  owner_chain:
                    type: string
                    description: Optional chain for the owner address, needed when the owner operates on a specific chain.
                  client_redirect_after:
                    type: string
                    enum:
                    - COMPLETED
                    - FUNDED
                    default: COMPLETED
                    description: When to redirect the user to the client_redirect_url. COMPLETED waits for the full payment to finish, FUNDED redirects after funding is confirmed.
              - title: ContinueConfirmPaymentRequest
                description: 'Continuation request after a USER_VERIFY instruction. Submit the signed verification

                  payloads to complete the confirmation process.

                  '
                type: object
                required:
                - verification_token
                - signatures
                properties:
                  verification_token:
                    type: string
                    description: Opaque HMAC-signed token from the USER_VERIFY instruction. Pass back unmodified.
                  signatures:
                    type: array
                    description: User-signed payloads, one per verification entry from the USER_VERIFY instruction.
                    items:
                      type: object
                      required:
                      - reason
                      - signature_type
                      - signature
                      properties:
                        reason:
                          type: string
                          enum:
                          - EVM_OWNER
                          - EVM_WITHDRAWAL
                          description: Must match the reason from the corresponding verification entry.
                        signature_type:
                          type: string
                          enum:
                          - EIP712
                          description: Must match the signature_type from the corresponding verification entry.
                        signature:
                          type: string
                          description: The user's signature over the verification payload.
      responses:
        '200':
          description: Payment confirmed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentStatus'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Invalid state_token. The quote may have expired.
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Authentication failed. Invalid API key.
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Access denied. This payment belongs to a different account.
        '404':
          description: Payment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Payment 'pay_xyz789' not found or has expired
  /payments/withdraw:
    post:
      summary: Return funds to owner or retry payment
      description: 'Request a withdrawal to return funds back to the owner or to a requoted processing address.

        This endpoint should be used when a payment cannot be completed and funds need to be returned.

        '
      operationId: withdrawPayment
      tags:
      - Payments
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WithdrawPaymentAuthorizationRequest'
      responses:
        '200':
          description: Withdrawal initiated successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WithdrawPaymentAuthorizationResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Missing field 'token_amounts'.
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Invalid or missing API key
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: You are not authorized to withdraw funds from this payment
        '404':
          description: Payment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Payment 'pay_def456' not found
  /payments/withdraw/confirm:
    post:
      summary: Confirm withdrawal request
      description: 'Submit and execute the signed withdrawal request to return funds back to the owner or to a requoted processing address.

        '
      operationId: withdrawPaymentConfirm
      tags:
      - Payments
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WithdrawPaymentRequest'
      responses:
        '200':
          description: Withdrawal executed successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WithdrawPaymentResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Invalid request body
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Invalid API key
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: You are not authorized to withdraw funds from this payment
  /payments/balances:
    post:
      summary: Get wallet balances
      description: 'Retrieve balances for the wallets associated with a payment. You can optionally supply additional

        wallet and token pairs to check alongside the payment''s primary wallet.

        '
      operationId: getPaymentBalances
      tags:
      - Payments
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RequestForPaymentBalances'
            example:
              payment_id: pay_abc123
              custom_queries:
              - address: '0xabc1234567890abcdef1234567890abcdef1234'
                token: ethereum:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
              - address: '0xdef1234567890abcdef1234567890abcdef5678'
                token: arbitrum:0xfffFFFFFfFFfffFFfFffffFffFFfFFfFFfFFf
      responses:
        '200':
          description: Wallet balances retrieved successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PaymentBalancesResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Invalid wallet address format
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Invalid API key
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: You do not have permission to query payment balances
        '404':
          description: Payment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                errors:
                - kind: other
                  message: Payment 'pay_abc123' not found
components:
  schemas:
    Token:
      type: string
      description: Token identifier in the format "chain:address"
      pattern: ^[a-z]+:0x[a-fA-F0-9]+$
      example: ethereum:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
    ProviderIssue:
      type: object
      required:
      - kind
      - message
      properties:
        kind:
          type: string
          enum:
          - provider
        message:
          type: string
    Fees:
      type: object
      required:
      - total_fees
      - conversion_fees
      - network_fees
      - business_fees
      - currency_symbol
      properties:
        total_fees:
          type: string
          description: Total fees amount
        conversion_fees:
          type: string
          description: Ramps + bridge + DEX fees
        network_fees:
          type: string
          description: Blockchain gas fees
        business_fees:
          type: string
          description: Developer integration fees
        currency_symbol:
          type: string
          pattern: ^[a-zA-Z]\w{1,7}$
          description: Fiat currency symbol that the fees are denominated in (e.g., "USD")
          example: USD
    Amount:
      type: string
      description: A decimal amount string.
    Limits:
      type: object
      properties:
        min:
          type: string
          description: Minimum amount as a decimal string.
        max:
          type: string
          description: Maximum amount as a decimal string.
    GeolocationIssue:
      type: object
      required:
      - kind
      - message
      properties:
        kind:
          type: string
          enum:
          - geolocation
        message:
          type: string
    AmountIssue:
      type: object
      required:
      - kind
      - asset
      - given
      - limits
      - source
      - message
      - reason
      properties:
        kind:
          type: string
          enum:
          - amount
        asset:
          $ref: '#/components/schemas/Asset'
        given:
          $ref: '#/components/schemas/Amount'
        limits:
          $ref: '#/components/schemas/Limits'
        downstream_limits:
          $ref: '#/components/schemas/Limits'
        source:
          type: string
        message:
          type: string
        reason:
          type: string
          enum:
          - TOO_LOW
          - TOO_HIGH
          - NO_VALID_AMOUNT
          - UNKNOWN
    QuotedEntry:
      type: object
      required:
      - fees
      - output_amount
      - route
      properties:
        output_amount:
          $ref: '#/components/schemas/AssetAmount'
        fees:
          $ref: '#/components/schemas/Fees'
        onramp:
          type: string
          description: Onramp provider name
        onramp_method:
          type: string
          enum:
          - CREDIT_CARD
          - DEBIT_CARD
          - ACH
          - FIAT_BALANCE
          - TOKEN_BALANCE
          - APPLE_PAY
          - PAYPAL
          - VENMO
          - REVOLUT
          - GOOGLE_PAY
          - SEPA
          - FASTER_PAYMENTS
          - PIX
          - UPI
          - WIRE
          description: Payment method
          example: CREDIT_CARD
        route:
          type: array
          items:
            $ref: '#/components/schemas/QuotedRouteItem'
          description: Quoted workflow steps and their effects
    PaymentStatus:
      type: object
      required:
      - payment_id
      - org_id
      - status
      - funded
      - created_at
      - updated_at
      - initiate_fund_by
      - quoted
      - fulfilled
      - current_prices
      - price_currency
      - processing_addresses
      - owner_chain
      - owner_address
      - destination_address
      - client_redirect_url
      - declaration
      properties:
        payment_id:
          type: string
        org_id:
          type: string
          description: Organization identifier
        status:
          type: string
          enum:
          - PENDING
          - COMPLETE
          - FAILED
          - EXPIRED
          - WITHDRAW_PENDING
          - WITHDRAWN
          - TAINTED
          - UNCONFIRMED
        funded:
          type: boolean
          description: Whether the payment has been funded
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        initiate_fund_by:
          type: string
          format: date-time
          description: Deadline for funding the payment.
        completed_at:
          type: string
          format: date-time
        quote_request:
          $ref: '#/components/schemas/QuoteRequest'
          description: The original quote request.
        quoted:
          $ref: '#/components/schemas/QuotedEntry'
        fulfilled:
          $ref: '#/components/schemas/FulfilledEntry'
        current_prices:
          type: object
          additionalProperties:
            type: string
          description: Mapping of asset symbols to their unit prices
          example:
            USD: '1.00'
            ethereum:0x: '4200'
            ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48: '1.00'
        price_currency:
          $ref: '#/components/schemas/Asset'
          description: Fiat asset used for pricing
        customer_id:
          type: string
          description: ID of the customer who created the payment
        label:
          type: string
          description: Optional payment label
          maxLength: 255
        processing_addresses:
          type: array
          items:
            type: object
            required:
            - chain
            - address
            - factory
            properties:
              chain:
                type: string
                description: Blockchain network
                example: ethereum
              address:
                type: string
                description: Payment processing contract address
              factory:
                type: string
                description: Factory contract address
        owner_chain:
          type: string
          description: Chain identifier for the owner
        owner_address:
          type: string
          description: Address of the owner of the payment
        destination_address:
          type: string
          description: Address of the destination of the payment
        next_instruction:
          $ref: '#/components/schemas/NextInstruction'
          nullable: true
        issues:
          type: array
          items:
            $ref: '#/components/schemas/Issue'
          description: Payment validation issues
        parent_payment_id:
          type: string
          format: uuid
          description: Parent payment reference
        client_redirect_url:
          type: string
          nullable: true
          description: Client redirect URL
        declaration:
          type: object
          nullable: true
          description: Declaration object
    Issue:
      oneOf:
      - $ref: '#/components/schemas/AmountIssue'
      - $ref: '#/components/schemas/AmountDownstreamIssue'
      - $ref: '#/components/schemas/FundingIssue'
      - $ref: '#/components/schemas/OwnerIssue'
      - $ref: '#/components/schemas/GeolocationIssue'
      - $ref: '#/components/schemas/ProviderIssue'
      - $ref: '#/components/schemas/PayinMethodIssue'
      - $ref: '#/components/schemas/OtherIssue'
      - $ref: '#/components/schemas/UnknownIssue'
      discriminator:
        propertyName: kind
    Asset:
      type: string
      description: Identifier in the token format ("chain:address") or fiat currency code ("USD")
      example: ethereum:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
    PaymentBalancesResult:
      type: object
      required:
      - address
      - token
      - account
      - value
      properties:
        address:
          type: string
          description: Wallet address that was queried.
          example: '0xabc1234567890abcdef1234567890abcdef1234'
        token:
          $ref: '#/components/schemas/Token'
          description: Token identifier that was queried.
          example: ethereum:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
        account:
          type: string
          description: Account type for the balance.
          enum:
          - INTENT
          - SPW
        value:
          oneOf:
          - type: object
            required:
            - kind
            - amount
            - withdrawal_fee
            properties:
              kind:
                type: string
     

# --- truncated at 32 KB (53 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/halliday/refs/heads/main/openapi/halliday-payments-api-openapi.yml