Retry a transfer batch's failed recipients
Sends the batch's failed recipients again, from the same source wallet, 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. Only recipients that are still failed are ever sent, so a retry under a new key never pays anyone twice.
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.
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. A recipient the source wallet could not fund reads "The wallet used for this payment does not have enough funds. Add funds and try again."
-
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 · 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 on chain.
-
fee·integer | null· required · example0Network fee the source wallet paid, in lamports: 0 when SDP sponsored the transaction, null when not known.
-
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.
-
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.
-
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. -
502Bad GatewaySame fields as
400. -
503Service UnavailableSame fields as
400.