---
title: "Create a buy instruction"
method: PUT
path: "/v1/stablecoin/fiat-instructions/{id}"
tags: ["Fiat instructions"]
---

# Create a buy instruction

`PUT /v1/stablecoin/fiat-instructions/{id}`

## Request

- Base URL: `https://api.ripple.com`
- URL: `https://api.ripple.com/v1/stablecoin/fiat-instructions/{id}`
- Auth: OAuth 2
  - Client credentials
  - Token URL: `https://api.ripple.com/v2/oauth/token` scopes: `rlusd_customers:write`
- TypeScript: <https://skmtc.dev/ripple/apis/ripple-mint-api/docs/v1/stablecoin/fiat-instructions/:id/put.ts> (a function with typed inputs; its response is checked against the schema)

Declares an incoming fiat payment under an id you choose, and returns the `memo` to quote in
that payment's reference field so the funds can be attributed and the RLUSD minted to the
wallet you named.

You generate the UUID for `{id}` client-side and it becomes the instruction's identity.
Reusing an id that already exists is rejected with a `409` carrying code
`FIAT_INSTRUCTION_ALREADY_EXISTS`.

Only a `CRYPTO` destination may be created here. Redemption (`FIAT`) instructions are
created by Ripple when your redemption is registered, and are read-only to you.

> **Put the `memo` verbatim into the payment's reference field, and nothing else.** A
> `RIPxxxxxxx` wallet ripId token in the payment's free text takes precedence over a memo
> during matching, which would credit that wallet and leave this instruction `UNUSED`.

## Path parameters

- `id` string, uuid, required

## Request body

- NewFiatInstruction: Request body for [Create a buy instruction](#operation/createFiatInstruction). Only a `CRYPTO` destination may be created here; `FIAT` (redemption) instructions are created by Ripple.
  - `currency` string, required: ISO-4217 fiat currency code of the payment you intend to send.
  - `destination` FiatInstructionDestination, required: Where the RLUSD goes once the instruction is claimed.
    - `type` 'CRYPTO' | 'FIAT', required: `CRYPTO` for a buy instruction - the RLUSD is minted to one of your wallets. `FIAT` only ever appears on a redemption instruction, which Ripple creates for you and which cannot be created through this API.
    - `walletRipId` string, nullable: Destination wallet ripId (e.g. `RIP0000001`). Required when `type` is `CRYPTO`; absent when `type` is `FIAT`. Resolve valid ids with [List wallets](#operation/listWallets).

## Response `200`

Instruction created; its memo is in the response

- FiatInstruction
  - `id` string, uuid, required: Instruction identifier. You supply it in the `PUT` path for a buy instruction; Ripple generates it for a redemption instruction.
  - `memo` string, required: Routing memo that correlates a fiat payment back to this instruction - quote it verbatim in the payment's reference field so the funds can be attributed. Assigned by Ripple and globally unique: `RL` followed by 14 Crockford base32 characters, 16 in total. Crockford base32 excludes `I`, `L`, `O` and `U` to avoid transcription ambiguity.
  - `currency` string, nullable: ISO-4217 fiat currency code. Always present on a buy instruction. May be absent on a redemption instruction whose originating fiat payment carries no currency.
  - `destination` FiatInstructionDestination, required: Where the RLUSD goes once the instruction is claimed.
    - `type` 'CRYPTO' | 'FIAT', required: `CRYPTO` for a buy instruction - the RLUSD is minted to one of your wallets. `FIAT` only ever appears on a redemption instruction, which Ripple creates for you and which cannot be created through this API.
    - `walletRipId` string, nullable: Destination wallet ripId (e.g. `RIP0000001`). Required when `type` is `CRYPTO`; absent when `type` is `FIAT`. Resolve valid ids with [List wallets](#operation/listWallets).
  - `status` 'UNUSED' | 'USED' | 'DELETED' | 'CANCELED', required: Lifecycle status. A new instruction is `UNUSED` and never expires; it becomes `USED` when its fiat payment claims it, or `CANCELED` when Ripple cancels the payment behind it. Both are terminal. `DELETED` exists on the underlying record but is never served: the reads exclude deleted instructions outright, so a deleted instruction returns `404 FIAT_INSTRUCTION_NOT_FOUND` rather than a `DELETED` status.
  - `createdAt` string, date-time, required: Timestamp when the instruction was created
  - `bankDetails` StablecoinBankDetails: The Ripple bank account to wire fiat to when buying stablecoin. Quote the instruction's `memo` on the transfer so the funds can be attributed to it - the `reference` below is a separate value the bank wants, not a substitute for the memo. Unlike `BankAccount`, which redacts your own account numbers to their last four digits, these are served in full: this is the beneficiary of an outgoing wire, and a truncated account number cannot be paid. At least one of `accountNumber` and `iban` is always present - an account that could not be paid is omitted from the response entirely rather than returned partially.
    - `bankName` string, required: Name of the bank holding the account. May be an empty string.
    - `accountName` string, required: Name the account is held under - the Ripple legal entity you are paying. May be an empty string.
    - `accountNumber` string: Account number to wire to.
    - `iban` string: IBAN to wire to, for accounts identified that way.
    - `swiftBicCode` string
    - `routingNumber` string
    - `reference` string: Reference Ripple wants quoted on transfers to this account. Distinct from the instruction's `memo`, which is what actually attributes the payment - send both.
    - `bankAddress` StablecoinBankAddress: Postal address of the bank account.
      - `street` string: Street address. Where the bank's address is recorded over two lines, both are returned here joined by `, `.
      - `city` string
      - `state` string: State, province or region.
      - `zipCode` string
      - `country` string

## Other responses

- `400`: Malformed body, a missing `currency` or `destination`, a `destination.type` other than `CRYPTO`, or a `CRYPTO` destination without a `walletRipId` (`INVALID_REQUEST_BODY`).
- `401`: Missing or expired access token
- `403`: The access token lacks `rlusd_customers:write`, or Ripple holds no RLUSD customer record for your tenant (`FORBIDDEN`). Nothing is persisted in the latter case: the customer is resolved before the instruction is written.
- `409`: An instruction already exists under this id (`FIAT_INSTRUCTION_ALREADY_EXISTS`).
- `500`: Unexpected server error
- `502`: An upstream system Ripple depends on could not be reached (`UPSTREAM_UNAVAILABLE`). Safe to retry: these are reads with no side effects, and the one write that returns it — `createFiatInstruction` — is idempotent on `id`.

## Changes

- **2026-09-18** `6db752579872`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/ripple/apis/ripple-mint-api/changes/v1/stablecoin/fiat-instructions/:id/put.md)

---

[API](https://skmtc.dev/ripple/apis/ripple-mint-api.md) - [All operations](https://skmtc.dev/ripple/apis/ripple-mint-api/llms.txt) - [OpenAPI document](https://skmtc.dev/ripple/apis/ripple-mint-api/revisions/6db752579872?raw)
