Saltar al contenido principal

Withdrawals

Withdrawal history

GET /v2/withdrawals

List withdrawals

Every debit from the account, newest first. One withdrawal is one row, fee included: the fee is reported as fee ON the withdrawal it belongs to, never as a separate row, so summing total over this list is the account’s outflow with no double-counting and no filtering needed.

The NETWORK_FEE and TRANSFER_FEE sub-types exist in the enum but are Skipo’s own accounting for the gas it pays, booked against a Skipo-internal account — they never appear on a customer’s list.

Amounts default to rebased; the always-present base block carries the settled figures. fee is the flat fee Skipo charges, NOT the blockchain network fee, which Skipo absorbs.

Parámetros

ParámetroEnTipoRequeridoDescripción
pagequeryintegernoDefault: 1.
limitqueryintegernoDefault: 25.
assetSymbolquerystringno
statusquerystringno
subTypequeryINTERNAL | EXTERNAL_CRYPTO | EXTERNAL_FIAT_BANK | EXTERNAL_FIAT_REDPAY | NETWORK_FEE | TRANSFER_FEEno
assetFormatqueryAssetFormatnoHow to express tokenised-equity (xStock) amounts. rebased (default) = underlying equity (real shares); base = settled SPV tokens, i.e. what moved on chain and in the ledger. No effect on other assets.
startDatequerystringnoISO-8601 start date.
endDatequerystringnoISO-8601 end date.

Respuestas

CódigoDescripciónCuerpo
200Éxito.data: WithdrawalResource[] · pagination: PaginationMeta
401application/problem+json (RFC 9457) — branch on code, not on the status: unauthorized (not retryable), key_expired (not retryable), key_revoked (not retryable).
403application/problem+json (RFC 9457) — branch on code, not on the status: insufficient_scope (not retryable), ip_not_allowed (not retryable), api_access_disabled (not retryable).
429application/problem+json (RFC 9457) — branch on code, not on the status: rate_limited (retryable).
500application/problem+json (RFC 9457) — branch on code, not on the status: internal_error (retryable).
502application/problem+json (RFC 9457) — branch on code, not on the status: downstream_unavailable (retryable).
503application/problem+json (RFC 9457) — branch on code, not on the status: maintenance (retryable).

POST /v2/withdrawals

Create a withdrawal

Money movement — requires a Tier-2 signed request (X-API-Key header + signed Authorization JWT), not a bare bearer key.

Fees. By default amount is the total DEBITED and the destination receives amountfee, as on Binance, Kraken, Coinbase and OKX — so sweeping a balance is one call: send the balance. Set feeMode: "add" to make amount the figure that ARRIVES, debiting amount + fee. The response reports amount (sent), fee and total (debited) either way.

The fee is per chain, and this body does not name one. The chain is whatever the destination contact is registered on. Read the fee from GET /v2/assetsnetworks[].withdrawalFee matched on the contact’s crypto.networkId — the asset-level withdrawalFee reports the cheapest chain and will understate any other.

Rejections move nothing: the balance is checked before any funds are held. If a withdrawal fails after it is accepted, the full total — amount and fee — returns to the balance.

Autenticación: Petición firmada (Tier-2)

Cuerpo de la peticiónCreateWithdrawalDto

Respuestas

CódigoDescripciónCuerpo
201Creado.WithdrawalResource
400application/problem+json (RFC 9457) — branch on code, not on the status: validation_error (not retryable).
401application/problem+json (RFC 9457) — branch on code, not on the status: unauthorized (not retryable), key_expired (not retryable), key_revoked (not retryable), invalid_signature (not retryable), clock_skew (retryable), nonce_reused (retryable).
403application/problem+json (RFC 9457) — branch on code, not on the status: insufficient_scope (not retryable), ip_not_allowed (not retryable), api_access_disabled (not retryable), two_factor_required (not retryable).
422application/problem+json (RFC 9457) — branch on code, not on the status: unprocessable (not retryable).
429application/problem+json (RFC 9457) — branch on code, not on the status: rate_limited (retryable).
500application/problem+json (RFC 9457) — branch on code, not on the status: internal_error (retryable).
502application/problem+json (RFC 9457) — branch on code, not on the status: downstream_unavailable (retryable).
503application/problem+json (RFC 9457) — branch on code, not on the status: maintenance (retryable).

GET /v2/withdrawals/{id}

Get a withdrawal by id

Takes the same assetFormat as the list. A PENDING withdrawal has no transactionHash YET — it appears on a later read once the transaction is broadcast, so poll this or subscribe to withdrawal.status.updated rather than treating the initial null as final.

Parámetros

ParámetroEnTipoRequeridoDescripción
idpathstring
assetFormatqueryAssetFormatnoHow to express tokenised-equity (xStock) amounts. rebased (default) = underlying equity (real shares); base = settled SPV tokens, i.e. what moved on chain and in the ledger. No effect on other assets.

Respuestas

CódigoDescripciónCuerpo
200Éxito.WithdrawalResource
401application/problem+json (RFC 9457) — branch on code, not on the status: unauthorized (not retryable), key_expired (not retryable), key_revoked (not retryable).
403application/problem+json (RFC 9457) — branch on code, not on the status: insufficient_scope (not retryable), ip_not_allowed (not retryable), api_access_disabled (not retryable).
404application/problem+json (RFC 9457) — branch on code, not on the status: not_found (not retryable).
429application/problem+json (RFC 9457) — branch on code, not on the status: rate_limited (retryable).
500application/problem+json (RFC 9457) — branch on code, not on the status: internal_error (retryable).
502application/problem+json (RFC 9457) — branch on code, not on the status: downstream_unavailable (retryable).
503application/problem+json (RFC 9457) — branch on code, not on the status: maintenance (retryable).

Esquemas

CreateWithdrawalDto

CampoTipoDescripción
assetSymbolstringAsset to withdraw, as the SETTLED asset code. ⚠️ Unlike every read endpoint, this one does NOT accept the rebased ticker of a tokenised equity: amount here is in settled units and the body declares no assetFormat, so accepting NVDAX would move a different quantity than the one you signed. Sending it is rejected with the settled code and the conversion. Ej.: BTC.
amountstringAmount to withdraw, as a positive decimal string. How it is read against the fee depends on feeMode, which defaults to deduct: amount is the total DEBITED from the balance and the destination receives amountfee. To sweep a balance, send the balance. The fee is per CHAIN and the chain comes from the contact, not from this body — read it from GET /v2/assetsnetworks[].withdrawalFee, matched on the contact’s crypto.networkId. The asset-level withdrawalFee is the cheapest chain’s and will understate a withdrawal over any other one. Ej.: 0.05.
feeMode (opcional)anyHow amount relates to the withdrawal fee. deduct (default) — amount is the total debited; the destination receives amountfee. This is what Binance, Kraken, Coinbase and OKX do, and it is what makes sweeping a balance a single call. addamount is what the destination receives; the balance is debited amount + fee. Use it when the arriving figure must be exact — settling an invoice, a payroll line, topping an address to a specific number. ⚠️ add was the behaviour of this endpoint before feeMode existed. Either value is fully supported; the response is identical in shape and always reports all three of amount (sent), fee and total (debited), so neither mode requires the caller to re-derive anything. No effect on internal transfers or bank payouts, which carry no fee — set it unconditionally rather than branching on the destination type.
contactId (opcional)stringDestination contact id (a whitelisted address/account).
contactReference (opcional)stringDestination contact reference/alias.

PaginationMeta

CampoTipoDescripción
pagenumberEj.: 1.
limitnumberEj.: 25.
totalItemsnumberEj.: 100.
totalPagesnumberEj.: 4.

Problem

CampoTipoDescripción
typestringStable problem-type URI. Resolves to docs for this error. Ej.: https://docs.skipo.com/errors/rate_limited.
titlestringShort, human-readable summary (stable, English). Ej.: Rate limit exceeded.
statusnumberHTTP status code. Ej.: 429.
codestringStable machine-readable error code (equals the last path segment of type). Ej.: rate_limited.
retryablebooleanWhether retrying the identical request may succeed. Ej.: true.
detail (opcional)stringHuman-readable, possibly localized detail.
instance (opcional)stringThe request path that produced the error.
traceId (opcional)stringTrace id — joins BigQuery api_request and Cloud Logging.

WithdrawalBaseRepresentation

CampoTipoDescripción
assetstring | nullAsset code of the settled token. Populated on every read, including a rebased one — the rebased ticker maps back to the settled code through the maintainers snapshot. null only if that lookup misses, which means the asset is unknown to the snapshot rather than that the code was unobtainable. It is never the underlying ticker: a plausible-looking wrong code is worse than an obvious gap when reconciling against a webhook. Ej.: USDT.
amountstringAmount withdrawn excluding the fee, in settled units. Positive magnitude. Ej.: 1954.78138064.
feestringSkipo withdrawal fee, in settled units. Positive magnitude. Ej.: 0.5.
totalstringTotal debited (amount + fee), in settled units. Positive magnitude. Ej.: 1955.28138064.

WithdrawalResource

CampoTipoDescripción
idstringWithdrawal id. Use it to re-fetch this withdrawal and to match its ledger entry (source.id). Ej.: 9bba6d71-5966-4045-962f-77a737e14226.
typestringEj.: WITHDRAWAL.
subTypeINTERNAL | EXTERNAL_CRYPTO | EXTERNAL_FIAT_BANK | EXTERNAL_FIAT_REDPAY | NETWORK_FEE | TRANSFER_FEE
assetSymbolstringAsset code of the withdrawal. Ej.: USDT.
amountstringAmount withdrawn, excluding the fee. Positive magnitude, in assetSymbol. Ej.: 1954.78138064.
feestringThe withdrawal fee charged by Skipo, in assetSymbol. A flat fee — NOT the blockchain network fee, which Skipo absorbs. Positive magnitude. Ej.: 0.5.
totalstringTotal debited from the balance (amount + fee). Positive magnitude, in assetSymbol. Ej.: 1955.28138064.
statusstringEj.: COMPLETED.
createdAtstringEj.: 2026-07-16T16:58:54.216Z.
transactionHashstring | nullOn-chain transaction hash, when this withdrawal had one. null otherwise — an off-chain withdrawal (bank payout, internal transfer) never has one, and an on-chain withdrawal that has not been broadcast yet does not have one YET, so a PENDING withdrawal reports null and the hash appears on a later read. Top-level so that reading it never requires branching on subType. It is the same value as withdrawalData.transactionHash, which remains for the sub-types that already published it; this field additionally covers on-chain sub-types that carry a hash but publish no withdrawalData block. NOT a bank reference: on a fiat payout this is always null, even though the underlying record may hold the bank's own transaction id. Do not assume a 0x prefix — BTC, Solana and Tron hashes have none. Ej.: 0x8b3275b467d90d99bd99bb7bfec9402e393ce870d741131a9d69a7d42640ac5b.
bankReferencestring | nullThe bank's or payment provider's own reference for this payout, when one was recorded. null on every non-fiat withdrawal, and null on a fiat withdrawal that carries no reference (the large majority — 73 of 14,502 bank payouts on prod have one). It is recorded when the payout is confirmed, so a PENDING bank withdrawal reports null. The counterpart of transactionHash: a withdrawal settles either on a chain or through a bank, so at most one of the two fields is ever populated. Free-form and short (3-19 characters, not always numeric) — it is whatever the bank supplied, so treat it as an opaque string for reconciliation, never parse it. Ej.: null.
assetFormatanyWhich representation the top-level money fields are expressed in. Echoes what the request RESOLVED to, so a response that took the default is as self-describing as one that asked. POST /v2/withdrawals always answers base: a creation returns the figures as booked. Ej.: rebased.
multiplierstringRebase factor as it stood when the withdrawal was created — not today. "1" when no scaling applies. base.amount x multiplier = amount when assetFormat is rebased. "1" is NOT a claim that the asset does not rebase; read GET /v2/assets for its class. Ej.: 1.
baseWithdrawalBaseRepresentation
withdrawalDataobjectSub-type-specific details. The keys depend on transactionSubType, so branch on that rather than probing for fields. For EXTERNAL_CRYPTO this carries the CANONICAL chain identity, the same five fields GET /v2/assets[].networks and GET /v2/contacts publish — networkId (BSC, ETH, TRON), networkName, networkNativeAsset, evmChainId and assetType (the token standard, BEP20/ERC20/TRC20). Join on networkId: it is the one field that means the same thing on every v2 resource, so a movement, an asset and a saved destination line up without parsing prose. ⚠️ networkSymbol has been REMOVED from this block. It was the raw stored value and it disagreed with itself across the estate — 164,192 movements say BEP20 for the same chain 1,614 call BSC, and it also carried values that are not networks (INTERNAL, FIAT_NETWORK) and prose (Dogecoin, XRP Ledger). networkId replaces it and is a stable key. networkName above is the human-readable form. The canonical fields are always present on an EXTERNAL_CRYPTO movement and are null when the chain cannot be resolved, so the shape never changes underneath you.

Volver a la referencia de endpoints. Ver también: Paginación · Errores · Ids y correlación.