Retry a transfer batch's failed recipients
Sends the batch's failed recipients again, from the same source wallet with the batch's options, and no other recipient.
POST/Run in dashboard
A failed recipient was not paid: its transaction never reached the network or the network rejected it. Recipients still pending or processing may land and are never sent again. Each resent recipient keeps its row and links to its new chunk transfer. Takes no body and requires an Idempotency-Key: a retry with the same key sends nothing again: while its response is stored, it returns that saved response, and after a server error or once the response has expired, the batch as it stands. Read the batch's current state with GET /v1/payments/transfer-batches/{batchId}, and use a new key for each retry you mean to send. Any credential that may send from the batch's wallet can retry it. Each recipient is paid the address the batch recorded for it. Returns 409, sending nothing: TRANSFER_BATCH_NOTHING_TO_RETRY when the batch has no failed recipients (while it is processing, its unsent recipients become failed only once its request can no longer send them), TRANSFER_BATCH_RETRY_CLAIMED when a concurrent retry claimed them first, and TRANSFER_BATCH_DESTINATION_CHANGED (details.recipientIds) when a failed recipient's counterparty account has changed its address since (send that recipient in a new batch). A native SOL retry is refused with 409 AMOUNT_BELOW_RENT_MINIMUM, as create is, when a failed recipient would still be paid less than the rent-exempt minimum at an address with no account; its recipients stay failed. Only recipients that are still failed are ever sent, so a retry under a new key never pays anyone twice.
Requires an API key with the transfer_batches.execute action.
Path parameters
-
batchId·string· required · min length 1 · examplexbatch_exampleTransfer batch identifier.
Headers
-
x-project-id·string· min length 1 · exampleprj_exampleRequired for dashboard sessions. API keys use their assigned project.
-
Idempotency-Key·string· requiredUse a unique 1–255 printable ASCII key per operation. Reuse it with the same request on retries. An in-flight attempt returns
409; a changed request returns422. Retry and recovery rules.
Responses
-
200Failed recipients resent-
data·object· requiredTransfer batch response payload.
-
batch·object· requiredTransfer batch details.
-
id·string· required · examplexbatch_exampleTransfer batch identifier.
-
organizationId·string· required · min length 1 · exampleorg_exampleOrganization identifier.
-
projectId·string· required · min length 1 · exampleprj_exampleProject identifier for the transfer batch.
-
externalId·string | null· required · examplepayroll_2026_06_30Caller-provided batch correlation ID.
-
sourceCustodyWalletId·string | null· required · examplecwlt_exampleExact source SDP Wallet ID, or null for unresolved legacy batches.
-
sourceProviderWalletId·string· required · min length 1 · exampleprivy_wallet_123Source Provider wallet ID retained as evidence.
-
sourceAddress·string· required · min length 32 · max length 44 · exampleSo11111111111111111111111111111111111111112Source custody wallet address.
-
token·string· required · exampleSOLToken symbol or mint address.
-
status·string· required · one ofpending,processing,confirmed,failed,partially_failed,archived· exampleprocessingTransfer batch status.
-
totalAmount·string | null· required · example1000.00Total requested batch amount in UI units, when computed.
-
recipientCount·integer· required · example20Number of recipient rows in the batch.
-
transactionCount·integer· required · example1Number of Solana transaction chunks for the batch.
-
createdAt·string· required · formatdate-time· example2025-01-01T00:00:00.000ZISO 8601 timestamp.
-
updatedAt·string· required · formatdate-time· example2025-01-01T00:00:00.000ZISO 8601 timestamp.
-
-
recipients·object[]Recipient rows for the batch, included on detail responses.
-
id·string· requiredTransfer batch recipient identifier.
-
batchId·string· requiredParent transfer batch identifier.
-
transferId·string | null· required · min length 1 · examplexfr_examplePayment transfer chunk that settled this recipient, once assigned.
-
externalId·string | null· required · examplepayroll_row_001Caller-provided recipient correlation ID.
-
counterpartyId·string· required · examplecpty_exampleCounterparty identifier for the recipient.
-
counterpartyAccountId·string· required · examplecpacct_exampleCounterparty account identifier for the recipient.
-
destination·string· required · min length 32 · max length 44 · exampleSo11111111111111111111111111111111111111112Resolved Solana destination address.
-
amount·string· required · example100.00Token amount in UI units (decimal string).
-
status·string· required · one ofpending,processing,confirmed,failed,archived· examplependingTransfer batch recipient status.
-
error·string | null· requiredRecipient-level failure reason, when available.
-
createdAt·string· required · formatdate-time· example2025-01-01T00:00:00.000ZISO 8601 timestamp.
-
updatedAt·string· required · formatdate-time· example2025-01-01T00:00:00.000ZISO 8601 timestamp.
-
-
transfers·object[]Payment transfer chunk records associated with this batch.
-
fireblocks·objectNative Fireblocks transfer tracking. A processing payment may await approval in Fireblocks; network fees are paid by its source vault. A missing transaction ID means submission is still being reconciled. Do not create a replacement payment while its outcome is unknown.
-
transactionId·string | null· required -
status·string· required -
subStatus·string | null· required
-
-
id·string· required · min length 1 · examplexfr_exampleTransfer identifier (SDP record ID, not the on-chain signature).
-
organizationId·string· required · min length 1 · exampleorg_exampleOrganization identifier.
-
custodyWalletId·string | null· required · examplecwlt_exampleExact SDP Wallet ID associated with the persisted transfer, or null for unresolved legacy and observed rows.
-
providerWalletId·string· required · min length 1 · exampleprivy_wallet_123Provider wallet ID retained as evidence; not an execution selector.
-
projectId·string· min length 1 · exampleprj_exampleProject identifier for the transfer.
-
type·string· required · exampletransferTransfer type.
-
kind·string· requiredDashboard transaction kind derived from the transfer type and originating Payments resource.
-
direction·string· required · one ofinbound,outbound· exampleoutboundTransfer direction.
-
status·string· required · one ofpending,processing,confirmed,finalized,failed,awaiting_payment,settling,completed,canceled,expired· exampleconfirmedTransfer status.
-
signature·string | null· required · examplesig_exampleSolana transaction signature (tx id/hash).
-
serializedTx·string | null· required · min length 1 · examplebase64_tx_exampleBase64-encoded transaction payload, if available. Always null for transfer batch chunks, whose signed bytes stay server-side.
-
slot·integer | null· required · example123456Slot number, if confirmed.
-
blockTime·string | null· required · formatdate-time· example2025-01-01T00:00:00.000ZBlock time, if confirmed.
-
confirmedAt·string· formatdate-time· example2025-01-01T00:00:00.000ZWhen SDP confirmed the transfer. A ramp is confirmed once its delivery is verified onchain.
-
fee·integer | null· required · example5000Transaction fee in lamports.
-
error·string | null· required · exampleSignature failedError message if the transaction failed.
-
initiatedBy·objectInitiator that triggered the transfer.
-
type·string· required · one ofapi_key,user,system· exampleapi_keyInitiator type.
-
id·stringInitiator identifier if applicable.
-
display·stringHuman-friendly label for the initiator.
-
-
source·string· min length 32 · max length 44 · exampleSo11111111111111111111111111111111111111112Source wallet address.
-
destination·string· min length 32 · max length 44 · exampleSo11111111111111111111111111111111111111112Destination wallet address.
-
memo·string· max length 256Optional memo for the transfer.
-
rampsMemo·object· requiredFree-form key-value memo for offchain reconciliation of ramp transfers. At most 20 entries.
*·string· min length 1 · max length 256
-
token·stringToken symbol or mint address.
-
amount·string· example100.00Token amount in UI units (decimal string).
-
counterpartyId·string· examplecpty_exampleCounterparty tied to the transfer record, when available.
-
counterpartyDisplayName·string· exampleAcme StudioCurrent display name of the counterparty tied to the transfer.
-
providerReference·string· exampleramp_quote_exampleProvider quote or transaction reference used for ramp correlation.
-
deliveryMode·string· one ofhosted,manual_instructions,session_widget· examplesession_widgetRamp delivery mode. Hosted flows require the customer to complete a provider-hosted UI; manual instructions require the customer to fund displayed instructions; session widgets use a provider SDK session.
-
fiatCurrency·string· exampleUSDFiat currency for the ramp leg.
-
fiatAmount·string· example100.00Quoted fiat amount for the ramp leg: what the customer pays on an on-ramp, the payout quoted on an off-ramp. It never changes after the quote; an off-ramp's final payout is
fiatPayout. -
fiatPayout·objectWhat the provider reports paying out once it settles an off-ramp sale. Provider-reported: SDP cannot verify a bank payout.
-
amount·string· required · example20.82Fiat paid out, in display units. Differs from the quoted
fiatAmountwhen the provider re-prices the sale at receipt. -
currency·string· required · exampleUSDISO currency of the payout, as the provider reports it.
-
reportedAt·string· formatdate-time· example2025-01-02T00:00:00.000ZWhen the provider reported the payout.
-
-
deliveryMismatch·objectPresent while SDP holds a provider-settled ramp in
settlingbecause the chain contradicts the provider's delivery. A new provider report clears it.-
reason·string· required · one ofprovider_report_mismatch,transaction_failed,predates_transfer,not_delivered,amount_mismatch,transaction_not_found· exampleamount_mismatchWhy the chain contradicts the provider:
provider_report_mismatch(its report contradicts SDP's record),transaction_failed,predates_transfer(the transaction landed before the transfer),not_delivered(nothing of the quoted asset reached the quoted wallet),amount_mismatch, ortransaction_not_found(no finalized transaction an hour after the report; SDP keeps checking, and a later delivery completes the transfer). -
checkedAt·string· required · formatdate-time· example2025-01-02T00:00:00.000ZWhen SDP's delivery check reached this verdict.
-
reportedAmount·string· example20What the provider reported delivering, in display units.
-
observedAmount·string· example0.5What the chain shows the quoted wallet received, in display units.
-
-
risk·objectOptional risk evaluation for the transfer.
-
provider·string· required · exampletrmRisk scoring provider.
-
score·string· required · example0.12Provider-specific risk score.
-
level·string· required · one oflow,medium,high,unknown· examplelowRisk level classification.
-
evaluatedAt·string· required · formatdate-time· example2025-01-01T00:00:00.000ZTimestamp when risk was evaluated.
-
-
createdAt·string· required · formatdate-time· example2025-01-01T00:00:00.000ZCreation timestamp.
-
updatedAt·string· required · formatdate-time· example2025-01-02T00:00:00.000ZLast update timestamp.
-
-
-
meta·object· requiredResponse metadata.
-
requestId·string· required · min length 1 · examplereq_exampleRequest identifier for tracing.
-
timestamp·string· required · formatdate-time· example2025-01-01T00:00:00.000ZISO 8601 timestamp.
-
-
-
400Bad Request-
error·object· requiredStandard error payload.
-
code·string· requiredMachine-readable error code.
-
message·string· requiredHuman-readable error message.
-
details·objectOptional error details for debugging.
*·any
-
-
meta·object-
requestId·string· min length 1 · examplereq_exampleRequest identifier for tracing.
-
-
-
401UnauthorizedSame fields as
400. -
403Forbidden. Requires thetransfer_batches.executeaction: an API key must hold it (a module'smanageorexecutealso covers itsread), and a signed-in member's organization role must include it. Without it the error is INSUFFICIENT_PERMISSIONS anderror.details.actionnames the action. Any other 403 names its own reason.Same fields as
400. -
404Not FoundSame fields as
400. -
409ConflictSame fields as
400. -
422Unprocessable EntitySame fields as
400. -
500Internal Server ErrorSame fields as
400.
Example request
curl -X POST 'https://api.solana.com/v1/payments/transfer-batches/xbatch_example/retry' \
-H "Authorization: Bearer $SDP_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"Example responses
{
"data": {
"batch": {
"id": "xbatch_example",
"organizationId": "org_example",
"projectId": "prj_example",
"externalId": "payroll_2026_06_30",
"sourceCustodyWalletId": "cwlt_example",
"sourceProviderWalletId": "privy_wallet_123",
"sourceAddress": "So11111111111111111111111111111111111111112",
"token": "SOL",
"status": "processing",
"totalAmount": "1000.00",
"recipientCount": 20,
"transactionCount": 1,
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-01T00:00:00.000Z"
},
"recipients": [
{
"id": "_example",
"batchId": "batch_example",
"transferId": "xfr_example",
"externalId": "payroll_row_001",
"counterpartyId": "cpty_example",
"counterpartyAccountId": "cpacct_example",
"destination": "So11111111111111111111111111111111111111112",
"amount": "100.00",
"status": "pending",
"error": "example",
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-01T00:00:00.000Z"
}
],
"transfers": [
{
"fireblocks": {
"transactionId": "transaction_example",
"status": "example",
"subStatus": "example"
},
"id": "xfr_example",
"organizationId": "org_example",
"custodyWalletId": "cwlt_example",
"providerWalletId": "privy_wallet_123",
"projectId": "prj_example",
"type": "transfer",
"kind": "example",
"direction": "outbound",
"status": "confirmed",
"signature": "sig_example",
"serializedTx": "base64_tx_example",
"slot": 123456,
"blockTime": "2025-01-01T00:00:00.000Z",
"confirmedAt": "2025-01-01T00:00:00.000Z",
"fee": 5000,
"error": "Signature failed",
"initiatedBy": {
"type": "api_key"
},
"source": "So11111111111111111111111111111111111111112",
"destination": "So11111111111111111111111111111111111111112",
"rampsMemo": {
"invoice": "INV-123",
"po": "PO-9"
},
"amount": "100.00",
"counterpartyId": "cpty_example",
"counterpartyDisplayName": "Acme Studio",
"providerReference": "ramp_quote_example",
"deliveryMode": "session_widget",
"fiatCurrency": "USD",
"fiatAmount": "100.00",
"fiatPayout": {
"amount": "20.82",
"currency": "USD",
"reportedAt": "2025-01-02T00:00:00.000Z"
},
"deliveryMismatch": {
"reason": "amount_mismatch",
"checkedAt": "2025-01-02T00:00:00.000Z",
"reportedAmount": "20",
"observedAmount": "0.5"
},
"risk": {
"provider": "trm",
"score": "0.12",
"level": "low",
"evaluatedAt": "2025-01-01T00:00:00.000Z"
},
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-02T00:00:00.000Z"
}
]
},
"meta": {
"requestId": "req_example",
"timestamp": "2025-01-01T00:00:00.000Z"
}
}Error responses use the standard error shape.