---
title: "Register a withdrawal address"
method: POST
path: "/v1/wallets"
tags: ["Partner API"]
---

# Register a withdrawal address

`POST /v1/wallets`

## Request

- Base URL: `https://sandbox.onlink.africa`
- URL: `https://sandbox.onlink.africa/v1/wallets`
- Auth: API key in header `X-OnLink-Key`

Creates the address in pending_partner_approval and emails a 6-digit code to a registered administrator. The address is not usable until your administrator confirms the code and OnLink approves it. Re-registering the same address is idempotent: the existing registration is returned and no second row is created. If that registration is still awaiting your administrator and its code is no longer usable (expired, or cancelled after too many incorrect attempts), re-registering re-issues a fresh code — this is how you recover such an address. A code that is still live is never replaced, and no code is issued once the address has moved past your administrator’s approval.

## Request body

- RegisterWalletDto
  - `chain` 'tron', required: Only tron at launch.
  - `asset` 'USDT', required: Only USDT at launch.
  - `address` string, required: The withdrawal address. Validated for base58check format AND checksum before it is stored.
  - `label` string: Your own label for this address. Never used for routing.

## Response `201`

Address registered, pending approval

- RegisterWalletResponseDto
  - `walletId` string, uuid, required: The registration id. Use it for POST /v1/wallets/{id}/confirm and DELETE /v1/wallets/{id}.
  - `chain` 'tron', required: Network. Tron only at launch.
  - `asset` 'USDT', required: Asset. USDT only at launch.
  - `address` string, required: The withdrawal address, **in full** — exactly as stored, checksum already verified. Compare the entire string when you reconcile: a truncated rendering makes a lookalike address indistinguishable from the real one, and USDT sent to the wrong address is an irrecoverable burn.
  - `label` string, nullable, required: Your own label, echoed back. Never used for routing. `null` if you sent none.
  - `status` 'pending_partner_approval' | 'pending_onlink_approval' | 'active' | 'revoked', required: Where the address sits in the two-party approval. **`active` is the only deliverable value** — a correct administrator code moves it to `pending_onlink_approval`, and OnLink’s own review is what makes it usable. `revoked` is terminal.
  - `screeningStatus` 'pending' | 'clear' | 'flagged', required: Address-screening outcome. Never defaults to a clear verdict: a newly registered address reads `pending` until a screen has actually run.
  - `createdAt` string, date-time, required: When the address was registered, ISO 8601 UTC.
  - `approvalSentTo` string, nullable, required: The administrator mailbox the 6-digit code was sent to, **masked** (`j•••@yourcompany.com`). Masked rather than whole so the response is not an address-harvesting oracle for anyone holding a leaked credential. `null` when no code was issued — an idempotent re-registration of an address that is already past your administrator’s approval.
  - `nextStep` string, required: Plain-language next action, keyed to `status`. Prose for a human reading the response — branch on `status`, not on this string.

## Other responses

- `400`: Invalid address (format or checksum), chain or asset
- `401`: Signature missing or invalid
- `409`: No administrator registered to send the approval code to

---

[API](https://skmtc.dev/onlink/apis/onlink-partner-api.md) - [All operations](https://skmtc.dev/onlink/apis/onlink-partner-api/llms.txt) - [OpenAPI document](https://skmtc.dev/onlink/apis/onlink-partner-api/revisions/1d1c6a3671f2?raw)
