API reference · Withdrawals
Withdraw crypto
POST/v1/withdrawals/crypto
Requests a withdrawal to a crypto address and emails a confirmation link to the account's email address. Nothing is sent, or held, until that link is opened, within 30 minutes. Idempotency-Key is required.
- Scope
withdrawals:create- Rate-limit class
withdrawal- Authentication
- Signed
- Idempotency-Key
- Required
Parameters
Idempotency-Keystringheaderrequired1 to 64 characters of [A-Za-z0-9_-]. Kept for 24 h; reuse it to retry safely.
Request body
application/json · CreateCryptoWithdrawalRequest. Unknown fields are rejected.
assetstringrequiredAn upper-case asset symbol.
networkstringoptionalNeeded only for an asset on several networks: USDC is ethereum (the default) or solana.
amountstring (decimal)requiredThe amount taken from the balance, fee included.
addressstringrequiredmemostringoptionalRequired for XRP (destination tag) and HBAR (memo).
travel_ruleTravelRulerequiredTravel rule details about the recipient, as the app asks for them.
5 properties
address_ownerstring (enum)requiredWhose address it is: yours, or someone else's.
wallet_typestring (enum)requiredhosted: an account at an exchange or other provider; self_hosted: a wallet whose keys the owner holds.
beneficiaryobjectoptionalRequired when address_owner is other: full_name for an individual, company_name and registration_number for a company.
4 properties
typestring (enum)requiredfull_namestringoptionalcompany_namestringoptionalregistration_numberstringoptional
vaspstring (enum)optionalRequired when wallet_type is hosted: the exchange that holds the address.
vasp_namestringoptionalThe exchange's name when vasp is other.
Responses
202 Accepted
The withdrawal, awaiting email confirmation. application/json · Withdrawal
idstringtypestring (enum)statusstring (enum)awaiting_confirmation: a crypto withdrawal waiting for the link in the confirmation email; expired: that link was not used in time; pending: being processed; completed: sent; canceled; failed.
assetstringAn upper-case asset symbol.
networkstring | nullCrypto only.
amountstring (decimal)Taken from the balance, fee included.
feestring (decimal)nullableThe withdrawal fee in the asset; null when it isn't known yet.
addressstring | nullCrypto only.
memostring | nullbank_accountstring | nullBank only.
tx_idstring | nullThe blockchain transaction id, once sent.
sourcestring (enum)Where the record was made: this API, the mobile app or the webapp.
created_atstring (date-time)confirm_bystring (date-time)nullableFor awaiting_confirmation: the confirmation email's link works until this time.
completed_atstring (date-time)nullable
Every response carries MK-Request-Id, plus RateLimit-Policy and RateLimit.
Errors
Errors use the error envelope. Match on code.
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | The request is malformed: bad JSON, an unknown or invalid field, or a missing header. |
| 401 | invalid_signature | The MK-* headers are missing or malformed, the key id is unknown, or the signature doesn't match. |
| 401 | key_expired | The key has passed its expiry date. |
| 401 | key_revoked | The key was revoked. |
| 401 | timestamp_out_of_range | MK-Timestamp is more than 30 seconds from the server clock. |
| 401 | nonce_reused | This key already used this MK-Nonce. |
| 403 | ip_not_allowed | The request came from an address outside the key's IP allowlist. |
| 403 | insufficient_scope | The key doesn't have the scope this endpoint needs. |
| 403 | account_restricted | The account can't use the API right now (for example locked, inactive, or onboarding not finished). |
| 403 | api_access_disabled | API access is switched off. |
| 403 | forbidden | This action is switched off for the API right now. |
| 409 | idempotency_conflict | This Idempotency-Key was used with a different request body. |
| 409 | idempotency_in_progress | A request with this Idempotency-Key is still being processed. |
| 413 | payload_too_large | The request body is larger than 8 KB. |
| 415 | unsupported_media_type | Request bodies must be application/json. |
| 422 | insufficient_funds | The available balance doesn't cover the trade, gift card or withdrawal. |
| 422 | amount_below_minimum | The amount is below the minimum. |
| 422 | asset_not_withdrawable | The asset can't be withdrawn on this network right now. |
| 429 | rate_limited | Too many requests. Wait for Retry-After seconds. |
| 429 | too_many_concurrent_requests | Too many requests in flight for this key or account. |
| 429 | key_suspended | The key is suspended, for example after sustained rate limiting. |
| 500 | internal_error | Something went wrong on our side. |
| 502 | bad_gateway | An upstream service answered unexpectedly. |
| 503 | overloaded | The service is overloaded. Retry after Retry-After seconds. |
| 503 | service_unavailable | The service is temporarily unavailable. |
| 503 | maintenance | The API is read-only for maintenance. |
| 504 | gateway_timeout | An upstream service didn't answer in time. A POST may still complete; retry with the same Idempotency-Key. |
Request
# Signed by sign-headers.sh: see Authentication
body='{"asset":"BTC","amount":"0.01","address":"bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh","travel_rule":{"address_owner":"self","wallet_type":"self_hosted"}}'
idempotency_key=$(uuidgen) # reuse it to retry safely
curl https://public-api.myntkaup.is/v1/withdrawals/crypto \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $idempotency_key" \
$(./sign-headers.sh POST /v1/withdrawals/crypto "$body" | sed 's/^/-H /') \
--data "$body"import { Myntkaup } from "@myntkaup/api";
const client = new Myntkaup(); // reads the key from the environment
// Nothing is sent until the link in the confirmation email is opened.
const withdrawal = await client.withdrawals.createCrypto({
asset: "BTC",
amount: "0.01",
address: "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
travelRule: { addressOwner: "self", walletType: "self_hosted" },
});
console.log(withdrawal.status, withdrawal.confirm_by);from myntkaup import Myntkaup
client = Myntkaup() # reads the key from the environment
# Nothing is sent until the link in the confirmation email is opened.
withdrawal = client.withdrawals.create_crypto(
asset="BTC",
amount="0.01",
address="bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
travel_rule={"address_owner": "self", "wallet_type": "self_hosted"},
)
print(withdrawal["status"], withdrawal["confirm_by"])Response
{
"id": "wd_01JB8X2Q4M7Z3V9K5T1N6R0P2W",
"type": "crypto",
"status": "awaiting_confirmation",
"asset": "BTC",
"network": "bitcoin",
"amount": "0.01",
"fee": "0.0005",
"address": "bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh",
"memo": null,
"bank_account": null,
"tx_id": null,
"source": "public_api",
"created_at": "2026-11-03T10:15:10Z",
"confirm_by": "2026-11-03T10:45:10Z",
"completed_at": null
}Base URL https://public-api.myntkaup.is