Create Address
Mint a deposit address.
external_refset — mint a per-user address. The partner-user’s profile is lazy-provisioned on first sight.external_refabsent — mint a tenant-treasury address (pooled / no per-user attribution). Response omitsexternal_ref.
Idempotency-Key header is required for
this endpoint (enforced by idempotency_required). Same
key + same body within 24h replays the original response
verbatim — partner retries are safe. Same key + different
body returns 409 idempotency_conflict.
Beneath the Connect-side idempotency the underlying
AddressService.ensure_primary_address is itself
idempotent on (user, asset, network) via a Postgres advisory
lock. Two paths to the same address therefore converge whether
the partner sends the Idempotency-Key or not — the header is
the cleaner contract, the lock is the safety net.
Note idem is taken before auth in the dependency order
above so the Idempotency-Key header is parsed (which can 400
on its own) before the DB hit for the approval gate. Both
happen long before we touch BitGo / Rhino.
Sandbox routing: sk_test_… keys (auth.mode == "sandbox")
are routed to ConnectAddressesSandboxService, which makes no
downstream calls and returns a deterministic fake address.
This is the compliance-relevant boundary — the single point in
the codebase where sandbox traffic is prevented from reaching
real custody infrastructure. sk_live_… keys continue to
hit the real path.Authorizations
Paste your Connect API key (sk_live_… for production, sk_test_… for sandbox) without the Bearer prefix. Mint and rotate keys from the admin panel.
Headers
Body
Request body for POST /connect/v1/addresses.
Two modes, switched on the presence of external_ref:
external_refset → mint a deposit address for that partner-user (lazy-provisioning the underlying profile + mapping on first sight).external_refabsent → mint a tenant-treasury / pooled address (no per-user attribution).
The partner-facing semantics are identical in both modes; the
only difference is whether the response echoes external_ref.
Forbidden extras: typo'd field names surface as a 422 rather than being silently ignored. Partners can recover by checking their request body shape against the docs.
Asset code (USDT, XAUT). Case-insensitive.
2 - 16Network code (solana, ethereum). Case-insensitive.
2 - 16Partner's user identifier. Omit to mint a tenant-treasury address (no per-user attribution).
255Optional partner-supplied label persisted on the address row for the partner's own records.
255Response
Successful Response
A single deposit-address row in the partner-facing shape.
Opaque partner-stable identifier (e.g. addr_VVNEVDpzb2xhbmE6RWhKO...). Pass to GET /addresses/:id to retrieve this row again.
Asset code, uppercase (USDT, XAUT).
Network code, lowercase (solana, ethereum).
On-chain wallet address. Partner shares this with the user.
The partner's user id this address belongs to. Absent (key omitted from the JSON, not null) when the address is a tenant-treasury / pooled address minted by calling POST /addresses without external_ref.
Memo / destination tag for chains that require one (XRP, XLM, COSMOS). NULL on chains that don't.