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

# Convert a balance

> Converts a balance held in a previous Account Currency into the current
Account Currency. Requires the **Owner** or **Admin** role.

- The rate is the reference rate at the time of the request, with **no
  fee and no spread**. `toAmount` is `fromAmount` × `rate`, rounded to
  the cent.
- Only the **available** amount converts. Without `amount`, the whole
  available amount of `fromCurrency` is converted; pending and on-hold
  funds stay until they become available.
- The converted amount is available in the Account Currency balance at
  once. A conversion is final; it cannot be reversed.
- **Idempotent:** repeating the request with the same `idempotencyKey`
  for the same currency returns the stored conversion with `200`
  instead of booking it again (`201`).

Not available with API keys.


> [!NOTE]
>
> A dashboard endpoint: it uses the signed-in dashboard session, not an API key, and requires the Owner or Admin role. It converts a balance held in a previous Account Currency into the current Account Currency at the reference rate, with no fee. See [converting a previous-currency balance](/guides/settlement.md#converting-a-previous-currency-balance).

| HTTP | `code` | When |
| - | - | - |
| 400 | `invalid_conversion` | Unknown currency, an amount of zero or less, or a missing `idempotencyKey` (or one longer than 200 characters). |
| 409 | `convert_same_currency` | `fromCurrency` is the Account Currency. |
| 409 | `insufficient_funds` | Less is available in that balance than requested, or nothing at all. `detail` names both figures. |
| 409 | `idempotency_key_reused` | The `idempotencyKey` belongs to another merchant account or another currency. |
| 409 | `account_currency_changed` | The Account Currency changed while the conversion was being booked. Retry. |
| 503 | `rate_unavailable` | No reference rate right now. Try again shortly. |


## OpenAPI

````yaml openapi.yaml POST /api/v1/merchant/balances/convert
openapi: 3.1.0
info:
  title: Qint Merchant API
  version: '1.1'
  description: >
    The Qint merchant API is a server-to-server API for creating and reading

    **payment intents**. You create an intent, redirect the buyer to the
    returned

    `checkoutUrl` (Qint's hosted checkout at `checkout.qint.ch`), and get
    notified

    of status changes via [webhooks](https://docs.qint.ch/webhooks/overview).


    ### Authentication

    Every request is authenticated with a Qint-issued API key

    (`qk_live_` + 32 alphanumeric characters), sent either as

    `Authorization: Bearer qk_live_…` or as an `X-Api-Key: qk_live_…` header.

    Keys carry **Read** and/or **Write** scopes: creating intents requires

    Write, reading them requires Read. The merchant account must be approved

    before the API accepts requests.


    ### Errors

    Errors are returned as RFC 7807 `application/problem+json` documents with

    `title`, `status` and `detail` fields.


    ### Rate limits

    The merchant API is rate limited. When a limit is exceeded the API responds

    with `429 Too Many Requests` — back off and retry. Intent creation is

    retry-safe: the required `idempotencyKey` makes a retried request return

    the original intent instead of creating a duplicate.


    ### Settlement

    Every payment is credited to the merchant's balance in its **Account

    Currency** (CHF, EUR, USD or GBP; CHF by default) at the rate fixed when

    the buyer is quoted. Since 20 October 2026 a payment intent reports the

    credit as `creditAmount`, `creditCurrency` and `creditRate`; the former

    stablecoin fields `creditUsdt` and `creditAsset` are no longer returned,

    and `creditRate` changed meaning. See

    [the breaking change
    note](https://docs.qint.ch/api-reference/introduction#breaking-change-20-october-2026).


    ### Dashboard endpoints

    The endpoints tagged **Dashboard** serve the Qint dashboard. They

    authenticate with the dashboard's signed-in session, not with an API key,

    and are documented so that the balance, balance conversion and Account

    Currency rules are described in one place.
  contact:
    name: Qint support
    email: support@qint.ch
    url: https://qint.ch
servers:
  - url: https://api.qint.ch
    description: Production
security:
  - bearerAuth: []
  - apiKeyHeader: []
tags:
  - name: Payment intents
    description: Create standalone payments and read their status.
  - name: Currencies
    description: Which fiat currencies Qint currently offers for new payments.
  - name: Dashboard
    description: >
      The merchant balance, conversions of a previous-currency balance and the
      Account Currency, as used by the Qint dashboard. Signed-in dashboard
      session only; API keys are not accepted.
paths:
  /api/v1/merchant/balances/convert:
    post:
      tags:
        - Dashboard
      summary: Convert a balance
      description: |
        Converts a balance held in a previous Account Currency into the current
        Account Currency. Requires the **Owner** or **Admin** role.

        - The rate is the reference rate at the time of the request, with **no
          fee and no spread**. `toAmount` is `fromAmount` × `rate`, rounded to
          the cent.
        - Only the **available** amount converts. Without `amount`, the whole
          available amount of `fromCurrency` is converted; pending and on-hold
          funds stay until they become available.
        - The converted amount is available in the Account Currency balance at
          once. A conversion is final; it cannot be reversed.
        - **Idempotent:** repeating the request with the same `idempotencyKey`
          for the same currency returns the stored conversion with `200`
          instead of booking it again (`201`).

        Not available with API keys.
      operationId: convertBalance
      parameters:
        - $ref: '#/components/parameters/MerchantIdHeader'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConvertBalanceRequest'
            example:
              fromCurrency: EUR
              amount: 2400
              idempotencyKey: convert-eur-2026-10-20
      responses:
        '200':
          description: >-
            A repeated request with the same `idempotencyKey`; the stored
            conversion.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalanceConversion'
        '201':
          description: The conversion was booked.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BalanceConversion'
        '400':
          $ref: '#/components/responses/InvalidConversion'
        '401':
          $ref: '#/components/responses/NotSignedIn'
        '403':
          $ref: '#/components/responses/NoMerchantAccess'
        '409':
          $ref: '#/components/responses/ConversionRefused'
        '503':
          $ref: '#/components/responses/RateUnavailable'
      security:
        - dashboardSession: []
components:
  parameters:
    MerchantIdHeader:
      name: X-Merchant-Id
      in: header
      required: false
      description: >
        The merchant account to act on, for users with access to more than one.
        Not needed when the user belongs to a single merchant account.
      schema:
        type: string
        format: uuid
  schemas:
    ConvertBalanceRequest:
      type: object
      required:
        - fromCurrency
        - idempotencyKey
      properties:
        fromCurrency:
          $ref: '#/components/schemas/AccountCurrency'
        amount:
          type:
            - number
            - 'null'
          description: >
            The amount to convert, in `fromCurrency`, kept to the cent. Omitted
            or `null`, the whole available amount of that balance.
          examples:
            - 2400
        idempotencyKey:
          type: string
          maxLength: 200
          description: >
            **Required.** Your unique key for this conversion. Repeating the
            request with the same key returns the stored conversion.
          examples:
            - convert-eur-2026-10-20
      additionalProperties: false
    BalanceConversion:
      type: object
      description: A conversion of a previous-currency balance into the Account Currency.
      required:
        - id
        - fromCurrency
        - fromAmount
        - toCurrency
        - toAmount
        - rate
        - rateSource
        - rateAt
        - idempotencyKey
        - createdAt
      properties:
        id:
          type: string
          description: Conversion id (`cv_…`).
          examples:
            - cv_4k8m2p9q7w1x
        fromCurrency:
          $ref: '#/components/schemas/AccountCurrency'
        fromAmount:
          type: number
          description: The amount taken from the `fromCurrency` balance.
          examples:
            - 2400
        toCurrency:
          $ref: '#/components/schemas/AccountCurrency'
        toAmount:
          type: number
          description: >-
            The amount added to the Account Currency balance, rounded to the
            cent.
          examples:
            - 2256.48
        rate:
          type: number
          description: >-
            Units of `toCurrency` per 1 unit of `fromCurrency`. The reference
            rate; no fee, no spread.
          examples:
            - 0.9402
        rateSource:
          type: string
          description: Where the rate came from.
        rateAt:
          type: string
          format: date-time
          description: The time of the rate.
        requestedByUserId:
          type:
            - string
            - 'null'
          format: uuid
          description: The dashboard user who requested it.
        idempotencyKey:
          type: string
        createdAt:
          type: string
          format: date-time
    AccountCurrency:
      type: string
      enum:
        - CHF
        - EUR
        - USD
        - GBP
      description: >
        The fiat currency new payments are credited in (CHF unless the merchant
        chooses otherwise). It can change at any time; a balance in a previous
        Account Currency stays in that currency. Every payment is credited in
        the Account Currency of its quote, at the rate fixed when the buyer was
        quoted.
    Problem:
      type: object
      description: RFC 7807 problem details (`application/problem+json`).
      properties:
        type:
          type: string
          description: A URI reference identifying the problem type.
        title:
          type: string
          description: Short human-readable summary.
        status:
          type: integer
          description: The HTTP status code.
        detail:
          type: string
          description: Human-readable explanation of this occurrence.
        traceId:
          type: string
          description: Request correlation id — include it in support requests.
        code:
          type: string
          description: >
            Machine-readable error code: `amount_out_of_range`,
            `terms_acceptance_required` or `rate_unavailable` on the merchant
            API; `invalid_account_currency` on the Account Currency endpoint;
            `invalid_conversion`, `convert_same_currency`, `insufficient_funds`,
            `idempotency_key_reused`, `account_currency_changed` or
            `rate_unavailable` on the balance conversion endpoints. Absent on
            most errors, including a disabled currency, so fall back to `status`
            and `detail`.
        minChf:
          type: number
          description: Only with `amount_out_of_range` — the minimum payment in CHF.
        maxChf:
          type: number
          description: >-
            Only with `amount_out_of_range` — your effective maximum payment in
            CHF.
        amountChf:
          type: number
          description: >-
            Only with `amount_out_of_range` — the CHF equivalent of the
            submitted amount.
      example:
        type: https://tools.ietf.org/html/rfc9110#section-15.5.1
        title: An error occurred while processing your request.
        status: 400
        detail: 'currency must be one of: CHF, EUR, USD, GBP.'
        traceId: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00
  responses:
    InvalidConversion:
      description: >
        `code: invalid_conversion`: an unknown currency, an amount of zero or
        less, or a missing `idempotencyKey` (or one longer than 200 characters).
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    NotSignedIn:
      description: No signed-in dashboard session.
    NoMerchantAccess:
      description: >
        The signed-in user is not a member of this merchant account, or (for a
        change) lacks the required role.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    ConversionRefused:
      description: |
        The conversion is refused; `code` says why:
        - `convert_same_currency`: `fromCurrency` is the Account Currency.
        - `insufficient_funds`: the balance has less available than requested
          (or nothing at all).
        - `idempotency_key_reused`: the key belongs to another merchant account
          or another currency.
        - `account_currency_changed`: the Account Currency changed while the
          conversion was being booked. Retry.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            title: An error occurred while processing your request.
            status: 409
            detail: Requested 2400.01 EUR but only 2400.00 EUR is available.
            code: insufficient_funds
    RateUnavailable:
      description: >-
        `code: rate_unavailable`: no reference rate right now. Try again
        shortly.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >
        `Authorization: Bearer qk_live_…` — a Qint API key created in the
        dashboard under Developers → API keys.
    apiKeyHeader:
      type: apiKey
      in: header
      name: X-Api-Key
      description: >
        Alternative to the Authorization header — send the same `qk_live_…` key
        as `X-Api-Key`.
    dashboardSession:
      type: apiKey
      in: cookie
      name: qint_session
      description: >
        The signed-in session of the Qint dashboard (dashboard.qint.ch). Only
        the Dashboard endpoints use it; API keys are not accepted there.

````

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