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

# Request a firm quote

> Requests firm swap terms from the runtime.

The route accepts two equivalent request shapes:

- **Friendly** (preferred): `input_asset`, `output_asset`, and a
  decimal `amount` string. Asset identifiers are case-insensitive and
  accept the values listed in `/v1/assets[*].aliases`.
- **Legacy**: `input_mint`, `output_mint`, and `input_amount_raw`
  integer. Existing API consumers can keep using this shape.

The response always includes the legacy raw fields plus
display-friendly `pair`, `input`, `output`, and `next_action` fields
on accepted RFQs and a `message` plus `suggested_action` on rejected
RFQs.




## OpenAPI

````yaml /openapi.yaml post /v1/rfq
openapi: 3.1.0
info:
  title: Firmament Backend API
  version: 0.1.3
  summary: Public backend routes for Firmament swaps and runtime proof.
  description: >
    Firmament is a Solana RFQ maker backend for managed liquidity demos.

    This specification documents the public routes used by the swap app and
    runtime view.
servers:
  - url: https://api.firmament.shaikazeem.com
    description: Deployed Firmament API.
  - url: http://127.0.0.1:5050
    description: Local backend started with `cargo run`.
security: []
tags:
  - name: Health
    description: Runtime liveness.
  - name: Assets
    description: Supported Solana assets.
  - name: Pairs
    description: Configured directional pairs and constraints.
  - name: RFQ
    description: Firm quote requests.
  - name: Settlement
    description: Browser-wallet HTLC settlement.
  - name: Trades
    description: Trade status lookup.
  - name: Runtime
    description: Read-only runtime state, events, ledger, and trades.
paths:
  /v1/rfq:
    post:
      tags:
        - RFQ
      summary: Request a firm quote
      description: |
        Requests firm swap terms from the runtime.

        The route accepts two equivalent request shapes:

        - **Friendly** (preferred): `input_asset`, `output_asset`, and a
          decimal `amount` string. Asset identifiers are case-insensitive and
          accept the values listed in `/v1/assets[*].aliases`.
        - **Legacy**: `input_mint`, `output_mint`, and `input_amount_raw`
          integer. Existing API consumers can keep using this shape.

        The response always includes the legacy raw fields plus
        display-friendly `pair`, `input`, `output`, and `next_action` fields
        on accepted RFQs and a `message` plus `suggested_action` on rejected
        RFQs.
      operationId: postRfq
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RfqRequest'
            examples:
              friendlyUsdcToSol:
                summary: Friendly request
                value:
                  input_asset: USDC
                  output_asset: SOL
                  amount: '1.00'
                  taker_wallet: '11111111111111111111111111111111'
                  expiry_seconds: 30
              legacyUsdcToSol:
                summary: Legacy request (still supported)
                value:
                  input_mint: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
                  output_mint: So11111111111111111111111111111111111111112
                  input_amount_raw: 1000000
                  taker_wallet: '11111111111111111111111111111111'
                  expiry_seconds: 30
      responses:
        '200':
          description: Accepted quote terms or a risk rejection.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RfqResponse'
              examples:
                accepted:
                  value:
                    status: accepted
                    quote_id: 018f5a45-822c-7f42-9d18-9df9f88c5c7a
                    quoted_output_amount_raw: 7200000
                    spread_bps: 35
                    expires_at: '2026-05-08T12:00:30Z'
                    htlc_terms:
                      settlement_model: solana_htlc
                      escrow_mint: So11111111111111111111111111111111111111112
                      expires_at: '2026-05-08T12:00:30Z'
                      hashlock: null
                    risk_checks:
                      - max_notional_ok
                      - inventory_quoteable
                    integration_status: runtime_orchestrated
                    pair:
                      input_asset: USDC
                      output_asset: SOL
                    input:
                      asset: USDC
                      amount: '1.000000'
                      amount_raw: '1000000'
                      decimals: 6
                      mint: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
                    output:
                      asset: SOL
                      amount: '0.007200000'
                      amount_raw: '7200000'
                      decimals: 9
                      mint: So11111111111111111111111111111111111111112
                    next_action:
                      type: start_wallet_settlement
                      method: POST
                      path: >-
                        /v1/quotes/018f5a45-822c-7f42-9d18-9df9f88c5c7a/wallet-settlement
                rejected:
                  value:
                    status: rejected
                    reason: max_notional_exceeded
                    risk_check_details:
                      - quote notional exceeds configured max
                    integration_status: runtime_orchestrated
                    message: The amount exceeds a configured maximum.
                    suggested_action: Try a smaller amount.
        '400':
          $ref: '#/components/responses/BadRequest'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  schemas:
    RfqRequest:
      oneOf:
        - $ref: '#/components/schemas/FriendlyRfqRequest'
        - $ref: '#/components/schemas/LegacyRfqRequest'
    RfqResponse:
      oneOf:
        - $ref: '#/components/schemas/RfqAcceptedResponse'
        - $ref: '#/components/schemas/RfqRejectedResponse'
      discriminator:
        propertyName: status
    FriendlyRfqRequest:
      type: object
      required:
        - input_asset
        - output_asset
        - amount
        - taker_wallet
      properties:
        input_asset:
          type: string
          description: Case-insensitive asset id or symbol (e.g. `USDC`, `usdc`).
          example: USDC
        output_asset:
          type: string
          example: SOL
        amount:
          type: string
          description: Decimal amount in the input asset's display units, sent as a string.
          example: '1.00'
        taker_wallet:
          $ref: '#/components/schemas/WalletAddress'
        expiry_seconds:
          type: integer
          minimum: 1
          example: 30
    LegacyRfqRequest:
      type: object
      required:
        - input_mint
        - output_mint
        - input_amount_raw
        - taker_wallet
      properties:
        input_mint:
          $ref: '#/components/schemas/MintAddress'
        output_mint:
          $ref: '#/components/schemas/MintAddress'
        input_amount_raw:
          $ref: '#/components/schemas/AmountRaw'
        taker_wallet:
          $ref: '#/components/schemas/WalletAddress'
        expiry_seconds:
          type: integer
          minimum: 1
          example: 30
    RfqAcceptedResponse:
      type: object
      required:
        - status
        - quote_id
        - quoted_output_amount_raw
        - spread_bps
        - expires_at
        - htlc_terms
        - risk_checks
        - integration_status
        - pair
        - input
        - output
        - next_action
      properties:
        status:
          type: string
          const: accepted
        quote_id:
          type: string
          format: uuid
        quoted_output_amount_raw:
          $ref: '#/components/schemas/AmountRaw'
        spread_bps:
          type: integer
          minimum: 0
          maximum: 10000
          example: 35
        expires_at:
          type: string
          format: date-time
        htlc_terms:
          $ref: '#/components/schemas/HtlcAcceptanceTerms'
        risk_checks:
          type: array
          items:
            type: string
        integration_status:
          $ref: '#/components/schemas/IntegrationStatus'
        pair:
          $ref: '#/components/schemas/RfqPair'
        input:
          $ref: '#/components/schemas/AmountView'
        output:
          $ref: '#/components/schemas/AmountView'
        next_action:
          $ref: '#/components/schemas/NextAction'
    RfqRejectedResponse:
      type: object
      required:
        - status
        - reason
        - risk_check_details
        - integration_status
        - message
        - suggested_action
      properties:
        status:
          type: string
          const: rejected
        reason:
          $ref: '#/components/schemas/RejectionReason'
        risk_check_details:
          type: array
          items:
            type: string
        integration_status:
          $ref: '#/components/schemas/IntegrationStatus'
        message:
          type: string
          description: User-facing message describing the rejection.
          example: The amount exceeds a configured maximum.
        suggested_action:
          type: string
          description: Concrete suggestion the caller can act on.
          example: Try a smaller amount.
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
            - details
          properties:
            code:
              type: string
              example: invalid_json
            message:
              type: string
            details:
              type: array
              items:
                type: string
    WalletAddress:
      type: string
      description: Solana wallet address.
      example: '11111111111111111111111111111111'
    MintAddress:
      type: string
      description: Solana mint address.
      example: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
    AmountRaw:
      type: integer
      minimum: 0
      format: int64
      examples:
        - 1000
    HtlcAcceptanceTerms:
      type: object
      required:
        - settlement_model
        - escrow_mint
        - expires_at
        - hashlock
      properties:
        settlement_model:
          type: string
          example: solana_htlc
        escrow_mint:
          $ref: '#/components/schemas/MintAddress'
        expires_at:
          type: string
          format: date-time
        hashlock:
          type:
            - string
            - 'null'
          description: Hashlock commitment when available.
    IntegrationStatus:
      type: string
      enum:
        - runtime_orchestrated
    RfqPair:
      type: object
      required:
        - input_asset
        - output_asset
      properties:
        input_asset:
          type: string
          example: USDC
        output_asset:
          type: string
          example: SOL
    AmountView:
      type: object
      required:
        - asset
        - amount
        - amount_raw
        - decimals
      properties:
        asset:
          type: string
          example: USDC
        amount:
          type: string
          example: '1.000000'
        amount_raw:
          type: string
          example: '1000000'
        decimals:
          type: integer
          minimum: 0
          maximum: 18
        mint:
          $ref: '#/components/schemas/MintAddress'
    NextAction:
      type: object
      required:
        - type
        - method
        - path
      properties:
        type:
          type: string
          example: start_wallet_settlement
        method:
          type: string
          example: POST
        path:
          type: string
          example: /v1/quotes/018f5a45-822c-7f42-9d18-9df9f88c5c7a/wallet-settlement
    RejectionReason:
      type: string
      enum:
        - unsupported_pair
        - unsupported_asset
        - amount_too_small
        - max_notional_exceeded
        - below_asset_min_notional
        - above_asset_max_notional
        - below_asset_min_amount
        - above_asset_max_amount
        - cumulative_cap_exceeded
        - inventory_below_quoteable_threshold
        - exposure_limit_exceeded
        - stale_price
        - wallet_not_allowed
        - gateway_unavailable
        - external_service_unavailable
        - validation_failed
  responses:
    BadRequest:
      description: Request shape, path, or validation error.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
    ServiceUnavailable:
      description: Runtime service is not available for the requested action.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'

````