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/v1/payments/transfer-batches/{batchId}/retryRun 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 · example xbatch_example

    Transfer batch identifier.

Headers

  • x-project-id · string · min length 1 · example prj_example

    Required for dashboard sessions. API keys use their assigned project.

  • Idempotency-Key · string · required

    Use 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 returns 422. Retry and recovery rules.

Responses

  • 200 Failed recipients resent

    • data · object · required

      Transfer batch response payload.

      • batch · object · required

        Transfer batch details.

        • id · string · required · example xbatch_example

          Transfer batch identifier.

        • organizationId · string · required · min length 1 · example org_example

          Organization identifier.

        • projectId · string · required · min length 1 · example prj_example

          Project identifier for the transfer batch.

        • externalId · string | null · required · example payroll_2026_06_30

          Caller-provided batch correlation ID.

        • sourceCustodyWalletId · string | null · required · example cwlt_example

          Exact source SDP Wallet ID, or null for unresolved legacy batches.

        • sourceProviderWalletId · string · required · min length 1 · example privy_wallet_123

          Source Provider wallet ID retained as evidence.

        • sourceAddress · string · required · min length 32 · max length 44 · example So11111111111111111111111111111111111111112

          Source custody wallet address.

        • token · string · required · example SOL

          Token symbol or mint address.

        • status · string · required · one of pending, processing, confirmed, failed, partially_failed, archived · example processing

          Transfer batch status.

        • totalAmount · string | null · required · example 1000.00

          Total requested batch amount in UI units, when computed.

        • recipientCount · integer · required · example 20

          Number of recipient rows in the batch.

        • transactionCount · integer · required · example 1

          Number of Solana transaction chunks for the batch.

        • createdAt · string · required · format date-time · example 2025-01-01T00:00:00.000Z

          ISO 8601 timestamp.

        • updatedAt · string · required · format date-time · example 2025-01-01T00:00:00.000Z

          ISO 8601 timestamp.

      • recipients · object[]

        Recipient rows for the batch, included on detail responses.

        • id · string · required

          Transfer batch recipient identifier.

        • batchId · string · required

          Parent transfer batch identifier.

        • transferId · string | null · required · min length 1 · example xfr_example

          Payment transfer chunk that settled this recipient, once assigned.

        • externalId · string | null · required · example payroll_row_001

          Caller-provided recipient correlation ID.

        • counterpartyId · string · required · example cpty_example

          Counterparty identifier for the recipient.

        • counterpartyAccountId · string · required · example cpacct_example

          Counterparty account identifier for the recipient.

        • destination · string · required · min length 32 · max length 44 · example So11111111111111111111111111111111111111112

          Resolved Solana destination address.

        • amount · string · required · example 100.00

          Token amount in UI units (decimal string).

        • status · string · required · one of pending, processing, confirmed, failed, archived · example pending

          Transfer batch recipient status.

        • error · string | null · required

          Recipient-level failure reason, when available.

        • createdAt · string · required · format date-time · example 2025-01-01T00:00:00.000Z

          ISO 8601 timestamp.

        • updatedAt · string · required · format date-time · example 2025-01-01T00:00:00.000Z

          ISO 8601 timestamp.

      • transfers · object[]

        Payment transfer chunk records associated with this batch.

        • fireblocks · object

          Native 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 · example xfr_example

          Transfer identifier (SDP record ID, not the on-chain signature).

        • organizationId · string · required · min length 1 · example org_example

          Organization identifier.

        • custodyWalletId · string | null · required · example cwlt_example

          Exact SDP Wallet ID associated with the persisted transfer, or null for unresolved legacy and observed rows.

        • providerWalletId · string · required · min length 1 · example privy_wallet_123

          Provider wallet ID retained as evidence; not an execution selector.

        • projectId · string · min length 1 · example prj_example

          Project identifier for the transfer.

        • type · string · required · example transfer

          Transfer type.

        • kind · string · required

          Dashboard transaction kind derived from the transfer type and originating Payments resource.

        • direction · string · required · one of inbound, outbound · example outbound

          Transfer direction.

        • status · string · required · one of pending, processing, confirmed, finalized, failed, awaiting_payment, settling, completed, canceled, expired · example confirmed

          Transfer status.

        • signature · string | null · required · example sig_example

          Solana transaction signature (tx id/hash).

        • serializedTx · string | null · required · min length 1 · example base64_tx_example

          Base64-encoded transaction payload, if available. Always null for transfer batch chunks, whose signed bytes stay server-side.

        • slot · integer | null · required · example 123456

          Slot number, if confirmed.

        • blockTime · string | null · required · format date-time · example 2025-01-01T00:00:00.000Z

          Block time, if confirmed.

        • confirmedAt · string · format date-time · example 2025-01-01T00:00:00.000Z

          When SDP confirmed the transfer. A ramp is confirmed once its delivery is verified onchain.

        • fee · integer | null · required · example 5000

          Transaction fee in lamports.

        • error · string | null · required · example Signature failed

          Error message if the transaction failed.

        • initiatedBy · object

          Initiator that triggered the transfer.

          • type · string · required · one of api_key, user, system · example api_key

            Initiator type.

          • id · string

            Initiator identifier if applicable.

          • display · string

            Human-friendly label for the initiator.

        • source · string · min length 32 · max length 44 · example So11111111111111111111111111111111111111112

          Source wallet address.

        • destination · string · min length 32 · max length 44 · example So11111111111111111111111111111111111111112

          Destination wallet address.

        • memo · string · max length 256

          Optional memo for the transfer.

        • rampsMemo · object · required

          Free-form key-value memo for offchain reconciliation of ramp transfers. At most 20 entries.

          • * · string · min length 1 · max length 256
        • token · string

          Token symbol or mint address.

        • amount · string · example 100.00

          Token amount in UI units (decimal string).

        • counterpartyId · string · example cpty_example

          Counterparty tied to the transfer record, when available.

        • counterpartyDisplayName · string · example Acme Studio

          Current display name of the counterparty tied to the transfer.

        • providerReference · string · example ramp_quote_example

          Provider quote or transaction reference used for ramp correlation.

        • deliveryMode · string · one of hosted, manual_instructions, session_widget · example session_widget

          Ramp 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 · example USD

          Fiat currency for the ramp leg.

        • fiatAmount · string · example 100.00

          Quoted 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 · object

          What the provider reports paying out once it settles an off-ramp sale. Provider-reported: SDP cannot verify a bank payout.

          • amount · string · required · example 20.82

            Fiat paid out, in display units. Differs from the quoted fiatAmount when the provider re-prices the sale at receipt.

          • currency · string · required · example USD

            ISO currency of the payout, as the provider reports it.

          • reportedAt · string · format date-time · example 2025-01-02T00:00:00.000Z

            When the provider reported the payout.

        • deliveryMismatch · object

          Present while SDP holds a provider-settled ramp in settling because the chain contradicts the provider's delivery. A new provider report clears it.

          • reason · string · required · one of provider_report_mismatch, transaction_failed, predates_transfer, not_delivered, amount_mismatch, transaction_not_found · example amount_mismatch

            Why 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, or transaction_not_found (no finalized transaction an hour after the report; SDP keeps checking, and a later delivery completes the transfer).

          • checkedAt · string · required · format date-time · example 2025-01-02T00:00:00.000Z

            When SDP's delivery check reached this verdict.

          • reportedAmount · string · example 20

            What the provider reported delivering, in display units.

          • observedAmount · string · example 0.5

            What the chain shows the quoted wallet received, in display units.

        • risk · object

          Optional risk evaluation for the transfer.

          • provider · string · required · example trm

            Risk scoring provider.

          • score · string · required · example 0.12

            Provider-specific risk score.

          • level · string · required · one of low, medium, high, unknown · example low

            Risk level classification.

          • evaluatedAt · string · required · format date-time · example 2025-01-01T00:00:00.000Z

            Timestamp when risk was evaluated.

        • createdAt · string · required · format date-time · example 2025-01-01T00:00:00.000Z

          Creation timestamp.

        • updatedAt · string · required · format date-time · example 2025-01-02T00:00:00.000Z

          Last update timestamp.

    • meta · object · required

      Response metadata.

      • requestId · string · required · min length 1 · example req_example

        Request identifier for tracing.

      • timestamp · string · required · format date-time · example 2025-01-01T00:00:00.000Z

        ISO 8601 timestamp.

  • 400 Bad Request

    • error · object · required

      Standard error payload.

      • code · string · required

        Machine-readable error code.

      • message · string · required

        Human-readable error message.

      • details · object

        Optional error details for debugging.

        • * · any
    • meta · object

      • requestId · string · min length 1 · example req_example

        Request identifier for tracing.

  • 401 Unauthorized

    Same fields as 400.

  • 403 Forbidden. Requires the transfer_batches.execute action: an API key must hold it (a module's manage or execute also covers its read), and a signed-in member's organization role must include it. Without it the error is INSUFFICIENT_PERMISSIONS and error.details.action names the action. Any other 403 names its own reason.

    Same fields as 400.

  • 404 Not Found

    Same fields as 400.

  • 409 Conflict

    Same fields as 400.

  • 422 Unprocessable Entity

    Same fields as 400.

  • 500 Internal Server Error

    Same 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.

Is this page helpful?