Skip to main content
This page covers flows that branch off the core walkthrough in Common Flows. Read that page first — it introduces Customer, Recipient, Destination, and Account. Everything here assumes those are already in place. On this page:

One-off Offramp (Single USD Payout)

Use a one-off offramp when you need a single USD payout — a vendor invoice, a customer refund, a scheduled disbursement — and want to embed a human-readable reference on the bank wire. One-offs generate a single-use crypto deposit address that’s discarded after the transaction completes. What one-off offramps give you over a reusable offramp account:
  • payment_reference — text carried into the bank wire. Per-rail constraints:
    • ACH — 1 to 18 chars. Letters, digits, and spaces only (no hyphens or punctuation). Delivered as the ACH addenda.
    • Wire (Fedwire) — 1 to 140 chars. Delivered as the wire message.
    • SWIFT — 5 to 140 chars across at most 4 lines of 35 characters. Letters, digits, spaces, commas, and periods only. Carried as the wire’s remittance information; whether the payee sees it depends on the receiving bank and any intermediaries, so do not rely on it for payee-side reconciliation.
    Your recipient sees this on their statement and uses it to reconcile against an invoice number. (SEPA is not currently offered as a payout rail.)
  • destination_payment_rail — override the rail per transaction (e.g. force fedwire instead of the destination’s default ach).
  • developer_fee_bps — per-transaction developer fee override. The API does not return developer_fee_bps on account or transaction reads, so record the value you set. The fee actually charged appears as client_fee in each transaction’s receipt.

Create the One-off Transaction

Prerequisite: a bank Destination (destination_type: "fiat_us") already attached to a Recipient for this Customer — see Add a Bank Destination.
Response:
Send exactly send_amount to crypto_address. The address is single-use and discarded after the transaction completes. Dakota converts the stablecoin and wires USD to the bank Destination with INV 2024 042 included as the payment reference. Subscribe to transaction.one_off.created and transaction.one_off.updated to track status.
Sandbox object-create endpoints reject mainnet network IDs and cap per-request amount at $2 USD. USDT is not yet supported in sandbox (coming soon); USD, USDC, and RD work today. See Testing — Sandbox restrictions.

SWIFT Payouts (International Wire)

SWIFT is Dakota’s international USD wire rail. Use it to pay recipients whose bank accounts are outside the US domestic rails (ACH, Fedwire, FedNow). SWIFT is USD only, settles in 1–3 business days, and is gated on the customer’s international_wire capability. If your customer does not have that capability, contact Dakota support.

Set up a SWIFT offramp

  1. Create a Recipient with a physical address. An address is required before adding any fiat destination — see Destinations & Recipients.
  2. Add a fiat_iban Destination to the Recipient with capabilities: ["swift"]. Include iban, account_holder_name, account_holder_address, bank_name, and bic. bank_address is required whenever bic is provided. See the IBAN destination fields.
  3. Create the offramp Account pointing at that destination:
Each stablecoin deposit to the returned source_crypto_address triggers a USD SWIFT wire to the IBAN destination. For a single payout instead of a reusable account, create a one-off offramp with destination_payment_rail: "swift".

SWIFT for onramps

SWIFT also works as an inbound rail. Include swift in capabilities when creating an onramp account; this narrows the account to SWIFT deposits. The returned bank_account deposit instructions then carry the BIC and the beneficiary’s postal address (account_holder_address) — give the sender both, along with the account details. The sender’s bank asks for the beneficiary address on international wires, and the sender must copy it exactly as shown.

SWIFT caveats

  • Intermediary fees. Intermediary and beneficiary banks can deduct fees en route. Dakota does not control or learn those deductions, and they do not appear in the transaction receipt’s external_fee — the amount received can be lower than the amount sent.
  • payment_reference delivery is not guaranteed. The reference is carried as the wire’s remittance information; whether the payee sees it depends on the receiving bank and any intermediaries. Constraints: 5–140 characters across at most 4 lines of 35 characters; letters, digits, spaces, commas, and periods only.
  • rail and capabilities are immutable after account creation. PUT /accounts/{account_id} only updates destination routing and developer_fee_bps. To add SWIFT for an existing customer, create a new account with rail: "swift".
  • Returns carry no NACHA code. An international wire return may come back as a reduced amount after intermediary fees, without an R-code.

One-off Swap (Single Cross-Chain Swap)

Use a one-off swap when the target network varies per swap (a reusable swap account pins destination_network_id) or you want to apply a different developer_fee_bps on this specific swap. payment_reference and destination_payment_rail are offramp-only and do not apply to swaps.

Create the One-off Swap

Prerequisite: a crypto Destination on the target network/asset already attached to a Recipient — see Add a Crypto Destination.
Response:
Send exactly send_amount to crypto_address. Dakota converts and delivers the destination asset on the target network. Same transaction.one_off.* webhooks as one-off offramp.
Sandbox object-create endpoints reject mainnet network IDs and cap per-request amount at $2 USD. USDT is not yet supported in sandbox (coming soon); USD, USDC, and RD work today. See Testing — Sandbox restrictions.

One-off transaction lifecycle

Both one-off offramps and one-off swaps share the same OneOffTransactionStatus values and the same lifecycle rules. Inspect status on the transaction object or on each transaction.one_off.updated event to drive your own state machine. pending_return, returned, pending_reversal, and reversed only apply to one-off offramps (the bank leg). They do not appear on one-off swaps, which are crypto-to-crypto. This mirrors the general Transaction lifecycle — one-offs surface pending as their initial status rather than not_started.

Cancel a one-off transaction

Call POST /transactions/{transaction_id}/cancellations to cancel a one-off transaction that has not yet delivered. A successful cancellation returns 204 No Content and the transaction moves to cancelled. Cancellation is only meaningful before Dakota starts settling the outbound leg — in practice, while the transaction is still in pending and no deposit has arrived at crypto_address. The endpoint returns 400 Invalid request or transaction cannot be cancelled when the target transaction is not in a cancellable state — for example, when it has already reached a terminal status (completed, failed, cancelled, returned, reversed) or is far enough along that the outbound leg can no longer be halted. The detail field on the problem response carries the specific reason. See Errors for the response shape. One-off requests do not accept a return_address (unlike reusable offramp accounts, which do). If a deposit lands on a crypto_address for a one-off that has already been cancelled, contact Dakota support with the transaction id to reconcile — the cancellation endpoint does not itself handle recovered funds.

Failed, returned, and reversed one-offs

For terminal non-success statuses, the fields on the OneOffTransaction object are your source of truth:
  • failed — read failure_reason for the cause.
  • returned — read return_code (e.g. R01) and return_reason for the bank’s reason, return_deadline for the return window, and net_recovered_amount when the return settled short.
  • reversed — read reversal_reason (Lead Bank ACH reversal code, e.g. duplicate, receiver_incorrect) and reversal_initiated_at.
Unlike a reusable offramp account, a one-off transaction has no return_address on the create request. If a one-off ends in returned or reversed and you need to reconcile the recovered value, contact Dakota support with the transaction id.