# Create a buy instruction

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`.

Endpoint: PUT /v1/stablecoin/fiat-instructions/{id}
Version: 1.0.0
Security: oauth2

## Security:

  - `oauth2` (unknown)
    oauth2 scopes: rlusd_customers:write

## Path parameters:

  - `id` (string, required)
    The id you are creating the instruction under, as a UUID you choose.

## Request fields (application/json):

  - `currency` (string, required)
    ISO-4217 fiat currency code of the payment you intend to send.
    Example: USD

  - `destination` (object, required)
    Destination for the resulting RLUSD. `type` must be `CRYPTO` and `walletRipId` must be
supplied; anything else is rejected with a `400` carrying code `INVALID_REQUEST_BODY`.

  - `destination.type` (string, 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.
    Enum: "CRYPTO", "FIAT"

  - `destination.walletRipId` (string)
    Destination wallet ripId (e.g. `RIP0000001`). Required when `type` is `CRYPTO`;
absent when `type` is `FIAT`. Resolve valid ids with
[List wallets](#operation/listWallets).
    Example: RIP0000001

## Response 200:

  - `200` (unknown)
    Instruction created; its memo is in the response

## Response 200 fields (application/json):

  - `id` (string, 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.
    Example: RL7Q3K9ZP2MTX4VB

  - `currency` (string)
    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.
    Example: USD

  - `destination` (object, required)
    Where the RLUSD goes once the instruction is claimed.

  - `destination.type` (string, 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.
    Enum: "CRYPTO", "FIAT"

  - `destination.walletRipId` (string)
    Destination wallet ripId (e.g. `RIP0000001`). Required when `type` is `CRYPTO`;
absent when `type` is `FIAT`. Resolve valid ids with
[List wallets](#operation/listWallets).
    Example: RIP0000001

  - `status` (string, 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.
    Enum: "UNUSED", "USED", "DELETED", "CANCELED"

  - `createdAt` (string, required)
    Timestamp when the instruction was created

  - `bankDetails` (object)
    The Ripple bank account to wire the fiat to. Resolved from the default bank account
registered against your stablecoin product, so it is the same on every instruction
rather than unique to one.
Absent when your account has no active default bank account on file, when that account
is not yet linked to a Ripple receiving bank, or when the details could not be
retrieved. The instruction and its `memo` are returned either way, so treat the field as
optional. [Get bank details](#operation/getFiatBankDetails) serves the same object on
its own and, unlike this field, reports why it is unavailable.

  - `bankDetails.bankName` (string, required)
    Name of the bank holding the account. May be an empty string.
    Example: ABC Bank

  - `bankDetails.accountName` (string, required)
    Name the account is held under - the Ripple legal entity you are paying. May be an empty
string.
    Example: RIPPLE LABS CAYMAN LTD.

  - `bankDetails.accountNumber` (string)
    Account number to wire to.
    Example: 000000

  - `bankDetails.iban` (string)
    IBAN to wire to, for accounts identified that way.

  - `bankDetails.swiftBicCode` (string)
    Example: ABCBUS33XXX

  - `bankDetails.routingNumber` (string)
    Example: 0000

  - `bankDetails.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.

  - `bankDetails.bankAddress` (object)
    Postal address of the bank account.

  - `bankDetails.bankAddress.street` (string)
    Street address. Where the bank's address is recorded over two lines, both are returned
here joined by `, `.
    Example: 1 Example Street

  - `bankDetails.bankAddress.city` (string)
    Example: Singapore

  - `bankDetails.bankAddress.state` (string)
    State, province or region.
    Example: Singapore

  - `bankDetails.bankAddress.zipCode` (string)
    Example: 000000

  - `bankDetails.bankAddress.country` (string)
    Example: Singapore

## Response 400:

  - `400` (unknown)
    Malformed body, a missing `currency` or `destination`, a `destination.type` other than
`CRYPTO`, or a `CRYPTO` destination without a `walletRipId` (`INVALID_REQUEST_BODY`).

## Response 400 fields (application/problem+json):

  - `type` (string)
    URI reference identifying the problem type

  - `title` (string)
    Short, human-readable summary of the problem

  - `status` (integer)
    HTTP status code

  - `code` (string)
    Machine-readable error code
    Enum: "TRANSACTION_NOT_FOUND", "TRANSACTION_INVALID_STATUS_TRANSITION", "TRANSACTION_DESTINATION_TYPE_IMMUTABLE", "FIAT_INSTRUCTION_NOT_FOUND", "FIAT_INSTRUCTION_ALREADY_EXISTS", "FIAT_INSTRUCTION_INVALID_STATUS_TRANSITION", "STABLECOIN_BANK_DETAILS_NOT_FOUND", "WALLET_NOT_FOUND", "WALLET_NOT_APPROVED", "FORBIDDEN", "UPSTREAM_UNAVAILABLE", "INVALID_REQUEST_BODY", "UNKNOWN_EXCEPTION"

## Response 401:

  - `401` (unknown)
    Missing or expired access token

## Response 401 fields (application/problem+json):

  - `type` (string)
    URI reference identifying the problem type

  - `title` (string)
    Short, human-readable summary of the problem

  - `status` (integer)
    HTTP status code

  - `code` (string)
    Machine-readable error code
    Enum: "TRANSACTION_NOT_FOUND", "TRANSACTION_INVALID_STATUS_TRANSITION", "TRANSACTION_DESTINATION_TYPE_IMMUTABLE", "FIAT_INSTRUCTION_NOT_FOUND", "FIAT_INSTRUCTION_ALREADY_EXISTS", "FIAT_INSTRUCTION_INVALID_STATUS_TRANSITION", "STABLECOIN_BANK_DETAILS_NOT_FOUND", "WALLET_NOT_FOUND", "WALLET_NOT_APPROVED", "FORBIDDEN", "UPSTREAM_UNAVAILABLE", "INVALID_REQUEST_BODY", "UNKNOWN_EXCEPTION"

## Response 403:

  - `403` (unknown)
    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.

## Response 403 fields (application/problem+json):

  - `type` (string)
    URI reference identifying the problem type

  - `title` (string)
    Short, human-readable summary of the problem

  - `status` (integer)
    HTTP status code

  - `code` (string)
    Machine-readable error code
    Enum: "TRANSACTION_NOT_FOUND", "TRANSACTION_INVALID_STATUS_TRANSITION", "TRANSACTION_DESTINATION_TYPE_IMMUTABLE", "FIAT_INSTRUCTION_NOT_FOUND", "FIAT_INSTRUCTION_ALREADY_EXISTS", "FIAT_INSTRUCTION_INVALID_STATUS_TRANSITION", "STABLECOIN_BANK_DETAILS_NOT_FOUND", "WALLET_NOT_FOUND", "WALLET_NOT_APPROVED", "FORBIDDEN", "UPSTREAM_UNAVAILABLE", "INVALID_REQUEST_BODY", "UNKNOWN_EXCEPTION"

## Response 409:

  - `409` (unknown)
    An instruction already exists under this id (`FIAT_INSTRUCTION_ALREADY_EXISTS`).

## Response 409 fields (application/problem+json):

  - `type` (string)
    URI reference identifying the problem type

  - `title` (string)
    Short, human-readable summary of the problem

  - `status` (integer)
    HTTP status code

  - `code` (string)
    Machine-readable error code
    Enum: "TRANSACTION_NOT_FOUND", "TRANSACTION_INVALID_STATUS_TRANSITION", "TRANSACTION_DESTINATION_TYPE_IMMUTABLE", "FIAT_INSTRUCTION_NOT_FOUND", "FIAT_INSTRUCTION_ALREADY_EXISTS", "FIAT_INSTRUCTION_INVALID_STATUS_TRANSITION", "STABLECOIN_BANK_DETAILS_NOT_FOUND", "WALLET_NOT_FOUND", "WALLET_NOT_APPROVED", "FORBIDDEN", "UPSTREAM_UNAVAILABLE", "INVALID_REQUEST_BODY", "UNKNOWN_EXCEPTION"

## Response 500:

  - `500` (unknown)
    Unexpected server error

## Response 500 fields (application/problem+json):

  - `type` (string)
    URI reference identifying the problem type

  - `title` (string)
    Short, human-readable summary of the problem

  - `status` (integer)
    HTTP status code

  - `code` (string)
    Machine-readable error code
    Enum: "TRANSACTION_NOT_FOUND", "TRANSACTION_INVALID_STATUS_TRANSITION", "TRANSACTION_DESTINATION_TYPE_IMMUTABLE", "FIAT_INSTRUCTION_NOT_FOUND", "FIAT_INSTRUCTION_ALREADY_EXISTS", "FIAT_INSTRUCTION_INVALID_STATUS_TRANSITION", "STABLECOIN_BANK_DETAILS_NOT_FOUND", "WALLET_NOT_FOUND", "WALLET_NOT_APPROVED", "FORBIDDEN", "UPSTREAM_UNAVAILABLE", "INVALID_REQUEST_BODY", "UNKNOWN_EXCEPTION"

## Response 502:

  - `502` (unknown)
    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`.

## Response 502 fields (application/problem+json):

  - `type` (string)
    URI reference identifying the problem type

  - `title` (string)
    Short, human-readable summary of the problem

  - `status` (integer)
    HTTP status code

  - `code` (string)
    Machine-readable error code
    Enum: "TRANSACTION_NOT_FOUND", "TRANSACTION_INVALID_STATUS_TRANSITION", "TRANSACTION_DESTINATION_TYPE_IMMUTABLE", "FIAT_INSTRUCTION_NOT_FOUND", "FIAT_INSTRUCTION_ALREADY_EXISTS", "FIAT_INSTRUCTION_INVALID_STATUS_TRANSITION", "STABLECOIN_BANK_DETAILS_NOT_FOUND", "WALLET_NOT_FOUND", "WALLET_NOT_APPROVED", "FORBIDDEN", "UPSTREAM_UNAVAILABLE", "INVALID_REQUEST_BODY", "UNKNOWN_EXCEPTION"

