Skip to main content
A withdrawal moves funds out of a customer’s Meridian balance to a destination instrument, such as an external wallet. Withdrawals use the Transaction Intent API, a two-step flow. You first create an intent, which returns a preview with the exchange rate and fees but moves no money. You then commit that intent, which creates the actual transaction.

Prerequisites

Your program must be configured with the RETAIN routing policy. The routing policy determines what happens to funds when they arrive in a balance, and it is set during enrollment:
  • RETAIN — deposited funds stay on the balance until you move them. This is what makes manual withdrawals possible.
  • SWEEP — deposited funds are automatically forwarded to a preconfigured credit instrument. Meridian initiates the withdrawal for you, so there is nothing to trigger manually.
The policy is submitted as a routing_policy entry in the Information Request during onboarding:
The withdrawal destination is also established during onboarding. For an external wallet destination, submit it alongside the routing policy:
If your program is configured with SWEEP, funds leave the balance automatically and this flow does not apply. Contact your Solutions Engineer if you need a RETAIN program configured.
You also need:
  • an enrollment in ACTIVE status — see Onboarding your customer
  • an access token for the program context, with the transactions:create scope
  • a funded balance to withdraw from
  • the payment instrument IDs for both sides of the movement (see below)

Identifying the two instruments

Every intent moves funds from a debit instrument to a credit instrument. Both are identified by payment instrument ID.

Debit instrument: the account ID

The debit instrument ID is the account id. Call GET /v1/accounts to list the customer’s accounts, or GET /v1/accounts/{accountId} for a single one, and pass that id as debitInstrumentId:
GET /v1/accounts
The debit instrument must be a balance. Passing any other instrument type returns 400 with the message Debit instrument must be a balance. Both instruments must also belong to the authenticated caller, or the request returns 403.

Credit instrument: provided by Meridian after onboarding

The credit instrument ID is provided by Meridian once your program has been onboarded. Your withdrawal destination is registered as part of program configuration — for an external wallet, from the destination_external_wallet_account_number entry you submit in the Information Request. Meridian creates a payment instrument for that destination and gives you its ID once the program is configured. Unlike the debit side, this ID is not returned by the accounts API. A RETAIN account reports only the policy type, with no destination:
GET /v1/accounts/{accountId}
Store the destination instrument ID with your program configuration so your integration can reference it on every withdrawal. Contact your Solutions Engineer if you need it confirmed or you add a new destination.

Making a withdrawal

1

Create the transaction intent

Call POST /v1/transaction-intents with both instruments and the amount. The response is a preview: it returns the exchange rate, the converted amount, and any fees, but no funds move yet.
2

Review the quoted rate

Show the customer the quoted exchangeRate, creditAmount, and fees from the intent so they can confirm before committing.
3

Commit the intent

Call POST /v1/transaction-intents/{transactionIntentId}/commit to execute the movement. This creates the transaction and returns the intent with a relatedTransactionId.
4

Track the transaction

Use the returned relatedTransactionId with GET /v1/transactions/{transactionId}, and consume transaction webhooks, to follow the withdrawal to completion.

Step 1: Create the intent

fixedSide tells Meridian which side of the conversion your amount refers to. Use DEBIT to specify how much leaves the balance, or CREDIT to specify how much should arrive at the destination.
Request
The response is the intent preview, in CREATED status:
Response (201)
No funds have moved at this point. Keep the returned id — you need it to commit.

Step 2: Commit the intent

Commit with the same idempotencyKey you used to create the intent:
Request
Response (200)
The relatedTransactionId is the transaction Meridian created. Committing the same intent again returns the same result rather than creating a second transaction.

Intent status values

An intent holds a quoted exchange rate, so it does not stay valid indefinitely. If a customer takes too long to confirm, the intent reaches EXPIRED and committing it returns an error — create a new intent to get a fresh rate. The intent does not return an expiry timestamp, so treat the quote as short-lived and commit promptly after the customer confirms.

Idempotency

The idempotencyKey is required on both calls, and the key you commit with must match the key the intent was created with. Use one unique key per withdrawal attempt — generated from your own reference for the withdrawal — and reuse it if you need to retry either call. This makes retries safe: a repeated request returns the original result instead of creating a duplicate withdrawal. Your integration should:
  • confirm the program uses RETAIN before exposing withdrawal functionality in your UI
  • show the quoted exchangeRate, creditAmount, and fees to the customer before committing
  • treat the intent as short-lived, and request a new one when an intent reaches EXPIRED
  • store the idempotencyKey with your own withdrawal record so retries reuse it
  • track completion through the relatedTransactionId and the transaction webhook, not the intent itself