Overview
A Registered Address is a crypto destination address that your organization whitelists against a customer. Registering screens the address once and records it; a crypto payout withpurpose: intercompany then requires its destination.recipient.address to match a registered self_custody entry for that customer — otherwise the payout returns 422 RECIPIENT_NOT_WHITELISTED. A third_party registration does not satisfy the intercompany gate: intercompany moves funds between accounts the customer owns, so the destination must be a wallet the customer controls. For the same reason, the payout request’s own destination.recipient.attestation.custody must be self — a third_party attestation declares a change of beneficial owner and returns 422 RECIPIENT_NOT_WHITELISTED even when the address is registered as self_custody. The registered address is a whitelist match by chain + address that gates the payout, not a recipient you reference by id: every POST /v2/payouts still carries the full destination.recipient, and there is no registeredAddressId field. For any other purpose, registering is not required — the inline recipient is accepted without a prior whitelist entry.
Registering an address always creates it synchronously and then screens it. Most registrations clear immediately: the POST returns 201 with status registered. When screening needs more time, the POST returns 202 with status pending_screening, and the address is resolved shortly after to either registered (usable) or suspended (blocked). A registration that screening rejects returns 409. An address in pending_screening is not yet usable — it gates an intercompany payout only once it is registered, so poll the address until it leaves pending_screening before relying on it.
Custody types
A registered address declares who controls the destination wallet, set by thetype discriminator:
self_custody— the customer owns and controls the wallet. RequiresselfCustodyAttestation: true. Only aself_custodyaddress unlockspurpose: intercompanypayouts.third_party— the wallet belongs to someone else (for example, a counterparty’s wallet). RequiresoriginatorDetailsdescribing the beneficial owner, used for Travel Rule disclosure. Athird_partyaddress is screened and recorded, but because it names a different beneficial owner it does not satisfy theintercompanypayout gate:entityType: "individual"→firstName,lastName,dateOfBirth,countryOfCitizenshipentityType: "business"→legalName,country
Lifecycle
Re-registering an address that is already
registered or pending_screening for the customer is idempotent — it returns the existing record rather than creating a duplicate.
Key fields
API surface
POST /v2/customers/:customerId/wallets/registered-addresses— register an address (requiresIdempotency-Key); returns201 registeredwhen screening clears immediately,202 pending_screeningwhen it resolves asynchronously, or409if screening rejectsGET /v2/customers/:customerId/wallets/registered-addresses— list registered addresses for the customerGET /v2/wallets/registered-addresses/:id— get a single registered addressDELETE /v2/wallets/registered-addresses/:id— revoke a registered address (terminal)
Testing in sandbox
In the sandbox environment, the screening verdict is deterministic — it is driven by the address you register:
An address parked
pending_screening by the 0x999 review value is resolved self-service:
POST /v2/sandbox/wallets/registered-addresses/:id/simulate/compliance-decisionwith body{ "outcome": "approve" | "reject" }— returns200with the address at its final status.approvemoves it toregisteredand releases any deposits from that address that were waiting on its registration;rejectmoves it tosuspended(not reversible, and re-registering the same address returns409).
200 with the address’s current state (safe for client retries), while a conflicting decision returns 409. The magic values are checked top to bottom — a sanctioned match (address or originator name) wins over the 0x999 review prefix. The fixed Tron review value parks at most once per customer (a resolved registration replays idempotently instead of re-parking); for repeated runs use fresh 0x999 EVM addresses.