Skip to main content
POST
/
v2
/
users
/
{userId}
/
orchestration-addresses
Create an orchestration address
curl --request POST \
  --url https://production.hifibridge.com/v2/users/{userId}/orchestration-addresses \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "source": {},
  "destination": {
    "currency": "usd",
    "accountId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
  },
  "thresholdAmount": "100.00"
}
'
{
  "id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "userId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "address": "0xAbC0123456789AbCdEf0123456789AbCdEf01234",
  "source": {
    "chain": "BASE"
  },
  "destination": {
    "currency": "usd",
    "accountId": "3c90c3cc-0d44-4b50-8888-8dd25736052a"
  },
  "schedule": {
    "nextRunAt": "2023-11-07T05:31:56Z"
  },
  "thresholdAmount": "100.00",
  "createdAt": "2023-11-07T05:31:56Z",
  "updatedAt": "2023-11-07T05:31:56Z",
  "deactivatedAt": "2023-11-07T05:31:56Z",
  "balance": {
    "currency": "usdc",
    "amount": "100.500000"
  }
}

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Path Parameters

userId
string
required

ID of the user

Query Parameters

profileId
string<uuid>

Optional profile (client/organization) scope. When omitted the request is scoped to the caller's default profile. Used by requestId idempotency: addresses are unique per (profileId, requestId).

Body

application/json

Provisions a new persistent on-chain address that automatically offramps any stablecoin it receives.

Mode rules (cross-field):

  • mode=PER_DEPOSIT — must NOT include schedule or thresholdAmount.
  • mode=SCHEDULED — MUST include schedule.interval; must NOT include thresholdAmount. schedule.nextRunAt is optional.
  • mode=THRESHOLD — MUST include thresholdAmount; must NOT include schedule.

Source rules: source.currency must be supported on source.chain (e.g. USDT on TRON, USDC on Base/Polygon/Ethereum/Solana). Unsupported pairs like USDC on TRON are rejected with 400.

Offramp minimums: each destination rail has a minimum offramp amount (e.g. ≥ 5 for SWIFT, ≥ 1 for wire/ACH/RTP; USDT carries a ≥ 10 floor). mode=THRESHOLD requires thresholdAmount to meet that minimum, and a batch is only ever created once the pending deposits reach it — deposits below the minimum are held PENDING to accumulate.

Idempotency: requestId is the client-supplied idempotency key. Repeating the same requestId with the same payload returns the existing record (200). Repeating with a different payload returns 409 RESOURCE_CONFLICT indicating which field differs (e.g. requestId already used with a different source.currency).

Wallet provisioning: the response is returned synchronously after the escrow wallet is provisioned, so status=ACTIVE and address is non-null in the typical case. If the provider call is in flight, status=PENDING_WALLET and address=null — retry the same call (same requestId) to drive provisioning forward.

requestId
string<uuid>
required

Client-supplied idempotency key (UUID v4 recommended). Unique per (profileId, requestId).

source
object
required

The on-chain source the orchestration address accepts deposits in. A stablecoin contract must exist for the (currency, chain) pair — USDC and USDT are both supported on Base/Polygon/Ethereum/Solana, while TRON supports USDT only. Unsupported pairs (e.g. USDC on TRON) are rejected at create time with 400.

destination
object
required

The destination payout configuration. v1 ships USD only, via an existing offramp account.

mode
enum<string>
required

Determines when deposits are converted into an offramp.

  • PER_DEPOSIT — each deposit is batched into its own offramp immediately, UNLESS the cumulative PENDING amount is below the destination rail's offramp minimum, in which case the deposit is held PENDING and all pending deposits are batched together once their cumulative amount reaches the minimum.
  • SCHEDULED — deposits accumulate until the next schedule boundary (HOURLY/DAILY/WEEKLY), then the entire pending pool is batched together (only if it meets the offramp minimum; otherwise it rolls into the next tick).
  • THRESHOLD — deposits accumulate until their summed amount reaches thresholdAmount, then the entire pending pool is batched.
Available options:
PER_DEPOSIT,
SCHEDULED,
THRESHOLD
schedule
object

Required when mode=SCHEDULED. Forbidden otherwise.

thresholdAmount
string | null

Required when mode=THRESHOLD. Forbidden otherwise. Decimal amount in the address's source currency (e.g. "100.00"). Must be at least the destination rail's offramp minimum (e.g. ≥ 5 for SWIFT, ≥ 1 for wire/ACH/RTP; USDT ≥ 10), else 400. Aggregate pending deposits are summed in integer token units (BigInt) and compared to this value, so floating-point drift never blocks the threshold.

Example:

"100.00"

Response

A single orchestration address record.

An orchestration address record.

id
string<uuid>

Unique orchestration address ID.

userId
string<uuid>

ID of the user that owns this orchestration address.

address
string | null

The on-chain wallet address that accepts deposits. null while status=PENDING_WALLET (provisioning in flight); populated once the wallet exists.

Example:

"0xAbC0123456789AbCdEf0123456789AbCdEf01234"

source
object

Source token + chain the address accepts.

destination
object

Destination payout configuration.

mode
enum<string>

Determines when deposits are converted into an offramp.

  • PER_DEPOSIT — each deposit is batched into its own offramp immediately, UNLESS the cumulative PENDING amount is below the destination rail's offramp minimum, in which case the deposit is held PENDING and all pending deposits are batched together once their cumulative amount reaches the minimum.
  • SCHEDULED — deposits accumulate until the next schedule boundary (HOURLY/DAILY/WEEKLY), then the entire pending pool is batched together (only if it meets the offramp minimum; otherwise it rolls into the next tick).
  • THRESHOLD — deposits accumulate until their summed amount reaches thresholdAmount, then the entire pending pool is batched.
Available options:
PER_DEPOSIT,
SCHEDULED,
THRESHOLD
schedule
object

Populated only when mode=SCHEDULED; null otherwise.

thresholdAmount
string | null

Populated only when mode=THRESHOLD; null otherwise. Decimal amount in the source currency.

Example:

"100.00"

status
enum<string>

Lifecycle status of the orchestration address.

  • PENDING_WALLET — created but the escrow wallet is still being provisioned. The on-chain address is null. Typically transient (a few seconds).
  • ACTIVE — wallet provisioned, ready to receive deposits.
  • DEACTIVATED — soft-deleted. The on-chain wallet still exists and can receive funds, but incoming deposits are recorded with status=IGNORED and never offramped.
Available options:
PENDING_WALLET,
ACTIVE,
DEACTIVATED
createdAt
string<date-time>
updatedAt
string<date-time>
deactivatedAt
string<date-time> | null

ISO 8601 timestamp when the address was deactivated. null if still active.

balance
object

The escrow wallet's live on-chain balance of the source token. Present ONLY on the single-address GET (GET /orchestration-addresses/{id}); the list endpoint omits it to avoid a provider call per row. null if the wallet isn't provisioned yet or the balance lookup failed — the GET still returns 200.

Example:
{
"currency": "usdc",
"amount": "100.500000"
}