Skip to main content

Save a Counterparty

Saves a destination an account can withdraw to: a coin and an address, plus the memo on chains that route by one. v2 calls it a beneficiary; it is the same record.

An account cannot save the same destination twice for one coin. Saving one that was deleted brings the original record back, with the same id, so withdrawals that named it before still find it. The restored record takes the label, network and reference sent now; one left out is cleared.

The address is checked for its form only, not against the chain: an address that is not valid on the coin's network is saved all the same. Check it before saving.

This endpoint takes no Idempotency-Key. Retrying a save that went through answers 409 counterparty_already_exists; find the record with List Counterparties.

Beta

Part of crypto v3, in beta. While crypto v3 counterparties are off for the account, this answers 404 feature_not_enabled.

customer_id is required from every key: a workspace-scoped key names any account of the workspace; an account-scoped key names its own.

Replaces POST /api/v2/crypto/beneficiaries.

Authorization:

Every request is signed with your API key: a short-lived JWT, signed with your private key, sent in one header on /v3/* and /api/v2/* alike.

Headers:
Authorization: APIKey {SIGNED_JWT}

How to build and sign the JWT: Authentication.

Endpoint

POST

/v3/crypto/counterparties

Request Body Sample​

{
"customer_id": "cst_01h455vb4pex5vsknk084sn02q",
"coin": "USDC",
"address": "0x8f3b2c1d0e9a7b6c5d4e3f2a1b0c9d8e7f6a5b4c",
"label": "Supplier payouts",
"network": "ERC20",
"reference": "supplier-17"
}

Request Body Schema​

FieldTypeDescription
customer_idstring (cst_…)Required. The account the counterparty belongs to.
coinstringRequired. A crypto ticker, for example BTC or USDC. Any casing is accepted; the answer is upper case.
addressstringRequired. Where the money goes, up to 255 characters, with no spaces. On a chain that routes by memo it may carry the memo as <address>?dt=<tag>, the way exchanges often show it.
tagstringThe memo, on chains that route by one (XRP); up to 64 characters, with no spaces. Sending it as well as a memo inside address is fine when the two agree.
labelstringOptional. Your name for it, up to 255 characters.
networkstringOptional. A note of the chain, for example ERC20, up to 255 characters. Descriptive only: the coin decides where the money goes.
referencestringOptional. Your own string, up to 255 characters, answered back on reads. It need not be unique.

Response Sample​

200 OK

{
"id": "wlt_01k8z5q7r9s1t3v5w7x9y1z3a5",
"customer_id": "cst_01h455vb4pex5vsknk084sn02q",
"coin": "USDC",
"address": "0x8f3b2c1d0e9a7b6c5d4e3f2a1b0c9d8e7f6a5b4c",
"label": "Supplier payouts",
"network": "ERC20",
"reference": "supplier-17",
"status": "active",
"created_at": "2026-10-20T15:40:00Z",
"updated_at": "2026-10-20T15:40:00Z"
}

Response Schema​

The counterparty, with the fields of a List Counterparties row, without customer. The memo, if any, is in tag, never inside address.

It also sends the crypto_beneficiary_created webhook.

Errors​

StatusmessageWhen
400failed to parse requestThe body is not valid JSON, customer_id is not a cst_… id, or coin is not a ticker.
400customer_requiredNo customer_id.
400invalid_account_idA workspace-scoped key sent an account_id query parameter (see Turning it on) that is not a cst_… id.
400coin_not_cryptocoin is a fiat currency, such as USD.
400invalid_addressaddress is only spaces, has spaces or control characters inside it, ends in ?dt= with no memo, carries ?dt= twice, or is longer than 255 characters together with its memo.
400tag_conflictaddress carries one memo and tag another.
400invalid_tagtag has spaces or control characters, or contains ?dt=.
400invalid_labellabel is longer than 255 bytes (characters outside ASCII take more than one).
401unauthorizedMissing or invalid signature.
403forbiddenAn account-scoped key named another account, or customer_id is not an account of the workspace.
404feature_not_enabledCrypto v3 counterparties are not enabled for the account. See Turning it on.
409counterparty_already_existsThe account already has this destination for this coin.
422Validation failedcoin or address is missing, or a text field is longer than allowed; details names it.

Coming from v2​

v2 (POST /api/v2/crypto/beneficiaries)v3
accountId (uuid)customer_id (cst_…)
reference requiredreference optional, and not unique
memo only inside addresstag, or inside address
id (uuid)id (wlt_…): the same id as a TypeID
createdAt, updatedAtcreated_at, updated_at

Support and Resources​

If you need assistance or have any questions, our support team is here to help. You can contact our support team at support@blockwyre.com.

Stay Updated​

Stay up-to-date with the latest news, updates, and features from BlockWyre by following us on social media:

We are excited to have you on board and look forward to seeing how you leverage BlockWyre's powerful tools to enhance your financial operations. Happy integrating!