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

# The live buy rate for an amount

> One provider fetch per request, never cached. Only the buy side is priced. `cryptoCurrency` must name the configured asset. Authentication only, no permission.

<Note>**Provider sandbox on this deployment.** Our backend targets the card provider's sandbox: no card is charged and no real transfer settles. Known limits: a purchase never reaches `completed` (it stops at `processing`), the settlement asset is the sandbox's, not production's (read `cryptoCurrency` from GET /v1/config), and the EUR window is unpublished (GET /v1/card/limits says `window: unpublished`). Every response says which environment answered in its `environment` field.</Note>


## OpenAPI

````yaml https://backend.rheon.io/openapi.json get /v1/card/rate
openapi: 3.1.0
info:
  title: Rheon partner API
  version: 1.0.0
  description: >-
    The /v1 surface a partner's backend calls with an API key.


    **Authentication.** Every route takes `Authorization: Bearer <key>`. One
    kind of key: it carries its permissions and limits, and works from your
    server, a page, or this playground alike - where it is called from is not
    checked. Treat it as a secret all the same: anyone holding it acts under its
    permissions until it is rotated.


    **Rate limit.** Counted per key, at the requests-per-second rate configured
    on the key - never per IP, so your users do not throttle each other. Over
    it: `429 rate_limited`.


    **Amounts.** Token amounts are decimal strings in the token's smallest unit;
    fiat amounts are decimal strings in major units. Never JSON numbers.


    **Errors.** One envelope everywhere: `{ error: { code, message } }`, with
    `fields` added on bank refusals that named a field. A body that is not valid
    JSON answers `400 invalid_request`; an endpoint that does not exist answers
    `404 not_found`; a deployment with no partner keys configured answers `404
    not_configured` for all of /v1.


    **Environment.** Every response carries `environment` as its first field:
    `sandbox` or `production`, derived from the upstreams this deployment is
    configured against (never a flag). Read it off any response you paste into a
    ticket. In `sandbox` no real money moves and the card corridor is the
    provider's sandbox asset, which differs from production - read it from GET
    /v1/config, not from these docs.


    **Card corridor.** The asset and chain a card purchase settles as are fixed
    per deployment, not chosen per request. GET /v1/config reports the one
    actually configured.
servers:
  - url: https://api.rheon.io
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Configuration
  - name: Crypto deposits
  - name: Orders
  - name: Cards
  - name: Bank transfers
  - name: Virtual accounts
  - name: Reference
  - name: Sandbox only
paths:
  /v1/card/rate:
    get:
      tags:
        - Cards
      summary: The live buy rate for an amount
      description: >-
        One provider fetch per request, never cached. Only the buy side is
        priced. `cryptoCurrency` must name the configured asset. Authentication
        only, no permission.
      operationId: cardRate
      parameters:
        - in: query
          name: side
          schema:
            description: Only "buy" is priced. Omitted means buy.
            example: buy
            type: string
            const: buy
          description: Only "buy" is priced. Omitted means buy.
        - in: query
          name: fiatCurrency
          schema:
            $ref: '#/components/schemas/IsoCurrency'
            description: >-
              ISO 4217 code to charge in. Must be one of the deployment's
              supported fiat currencies (see GET /v1/card/currencies); others
              are refused.
          required: true
          description: >-
            ISO 4217 code to charge in. Must be one of the deployment's
            supported fiat currencies (see GET /v1/card/currencies); others are
            refused.
        - in: query
          name: cryptoCurrency
          schema:
            type: string
            description: >-
              Must equal the deployment's configured settlement asset
              (case-insensitive). Anything else is refused with a message naming
              what is configured and which environment this is. Read GET
              /v1/config or GET /v1/card/currencies to learn it - on the sandbox
              it is the provider's sandbox asset (ETH), not USDC.
            example: USDC
          required: true
          description: >-
            Must equal the deployment's configured settlement asset
            (case-insensitive). Anything else is refused with a message naming
            what is configured and which environment this is. Read GET
            /v1/config or GET /v1/card/currencies to learn it - on the sandbox
            it is the provider's sandbox asset (ETH), not USDC.
        - in: query
          name: amount
          schema:
            $ref: '#/components/schemas/DecimalMajorUnits'
            type: string
            pattern: ^\d+(\.\d+)?$
            description: >-
              Fiat amount to price, decimal string in major units, greater than
              zero. This parameter is named `amount` (not `fiatAmount`); a
              missing or malformed value is refused with 400 invalid_request
              naming it, before the provider is asked.
            example: '100'
          required: true
          description: >-
            Fiat amount to price, decimal string in major units, greater than
            zero. This parameter is named `amount` (not `fiatAmount`); a missing
            or malformed value is refused with 400 invalid_request naming it,
            before the provider is asked.
      responses:
        '200':
          description: The rate, fees included.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardRateResponse'
        '400':
          description: >-
            Cannot price this.


            - `invalid_request`: side is not "buy", cryptoCurrency is not the
            configured asset, fiatCurrency unsupported, or `amount` missing or
            not a positive decimal string (the message names the field). Also
            when the amount is outside the provider's card payment window: the
            message names the published minimum and maximum, or says the window
            is unpublished here.

            - `<provider code>`: The card provider refused (4xx) for a reason of
            its own: its numeric code is passed through as `code` with its
            message. Never reported as the provider being unavailable.
          x-error-codes:
            - invalid_request
            - <provider code>
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '401':
          description: >-
            No usable API key.


            - `unauthorized`: Missing, malformed or unknown key. One
            undifferentiated answer on purpose.
          x-error-codes:
            - unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '429':
          description: >-
            Over this key's rate.


            - `rate_limited`: More requests per second than the key is
            configured for. Counted PER KEY (all your users share one bucket),
            never per IP.
          x-error-codes:
            - rate_limited
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '502':
          description: >-
            The provider behind this route is unavailable.


            - `upstream_error`: The payment provider answered a 5xx or did not
            answer.
          x-error-codes:
            - upstream_error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
        '503':
          description: |-
            The card vertical is not configured here.

            - `not_configured`: This deployment has no card provider configured.
          x-error-codes:
            - not_configured
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
      security:
        - bearerAuth: []
components:
  schemas:
    IsoCurrency:
      type: string
      pattern: ^[A-Za-z]{3}$
      description: ISO 4217 currency code, three letters (case-insensitive on input).
      example: EUR
    DecimalMajorUnits:
      type: string
      pattern: ^\d+(\.\d+)?$
      description: >-
        Decimal string in the currency's major unit, e.g. "100" or "25.50".
        Never a JSON number.
      example: '100'
    CardRateResponse:
      type: object
      properties:
        environment:
          $ref: '#/components/schemas/Environment'
        side:
          type: string
          const: buy
        fiatCurrency:
          type: string
          example: EUR
        cryptoCurrency:
          type: string
          example: USDC
        fiatAmount:
          type: string
          description: Fees included - what the buyer would actually be charged.
        cryptoAmount:
          type: string
        rate:
          type: string
      required:
        - environment
        - side
        - fiatCurrency
        - cryptoCurrency
        - fiatAmount
        - cryptoAmount
        - rate
      additionalProperties: false
    ErrorEnvelope:
      type: object
      properties:
        environment:
          $ref: '#/components/schemas/Environment'
        error:
          type: object
          properties:
            code:
              type: string
              description: >-
                Machine-readable error code. Branch on this, never on the
                message.
              example: invalid_request
            message:
              type: string
              description: Human-readable explanation. Wording may change.
              example: amount must be a decimal string of the token's smallest unit.
            fields:
              description: >-
                Per-field complaints from the bank provider, when it named the
                field it refused (bank routes only). Field names, never values.
              example:
                applicantInfo.nationality: iso3166_1_alpha2
              type: object
              propertyNames:
                type: string
              additionalProperties:
                type: string
          required:
            - code
            - message
          additionalProperties: false
      required:
        - environment
        - error
      additionalProperties: false
      description: The one error shape this API produces.
    Environment:
      type: string
      enum:
        - sandbox
        - production
      description: >-
        Which environment answered. `sandbox`: at least one money upstream is
        the provider's sandbox - no real money moves there, and the card
        corridor is the sandbox's asset (read GET /v1/config), not the
        documented production one. `production`: every configured upstream is
        real. Derived from the configured upstream hosts at boot, never a flag.
      example: sandbox
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: Your API key, issued by us and shown once at creation.

````