Registering a Corporation
Link an on-chain corporation to a Wirex corporation record and complete the owner's employee record.
Before You Start
Read the following guides before proceeding:
| Guide | Why |
|---|---|
| Getting Started | Integration overview |
| Authentication | Partner token and identity headers |
| Wallet Deployment | The corporation must exist on-chain first |
Overview
Registration turns an on-chain corporation into a Wirex corporation record: it supplies the legal
details KYB will verify, and it completes the owner's employee record by binding their wallet address
and email.
Only the on-chain owner can register. The handler checks two things before writing anything:
- The corporation's
owner_addresson record equals the caller'sX-User-Wallet. - The caller's employee record inside that corporation holds the
Ownerrole
(ed7a5845-8727-4b06-9ba0-7d43ddc9e6aa).
Both are created by on-chain registration — this is the API-side confirmation that the on-chain step
succeeded.
Step 1: Register the Corporation
POST /api/v1/corporations/register
Headers:
| Header | Value |
|---|---|
Authorization | Bearer <partner_token> |
X-User-Wallet | The owner's EOA address — the signer behind the corporation wallet |
X-User-Email | The owner's email address |
X-Chain-Id | Chain the corporation was created on |
Both X-User-Wallet and X-User-Email are required. Omitting either returns 500 ErrorGeneral with
Failed to get user from context.
Request body:
{
"corporation_address": "0xA7E41d5680dE394EaA2ed417169DFf56840Fb3EE",
"corporation_name": "Acme Inc.",
"corporation_registration_number": "12345678",
"corporation_registration_country": "GB"
}| Field | Type | Required | Description |
|---|---|---|---|
corporation_address | string | Yes | The corporation wallet address created on-chain |
corporation_name | string | No | Full legal name. Validated when present |
corporation_registration_number | string | No | Company registration number. Validated when present |
corporation_registration_country | string | No | ISO 3166-1 alpha-2 country of registration. Validated when present |
Response:
{}Registration returns an empty object. Confirm the outcome by logging in and reading
GET /api/v1/corporations.
Field Validation
| Field | Validation (regex) | Notes |
|---|---|---|
corporation_address | ^(0x[a-fA-F0-9]{40}|C[A-Za-z2-7]{55}|G[A-Za-z2-7]{55}|T[1-9A-HJ-NP-Za-km-z]{33})$ | EVM, Stellar or Tron address form |
corporation_name | ^[A-Za-z0-9&.,'’\-/() :+#]{2,100}$ | 2–100 characters. No ", !, ?, * or _ |
corporation_registration_number | ^[A-Z0-9\-]{6,15}$ | 6–15 characters, uppercase only. A lowercase registration number is rejected |
corporation_registration_country | ^[A-Z]{2}$ | Uppercase ISO 3166-1 alpha-2 |
The three legal fields are optional at the API but not optional in practice.
corporation_name
andcorporation_registration_countryare what KYB and capability evaluation are driven from — a
corporation registered without a country resolves to an empty capability set, and every capability
check then fails withCapability is not active. Send all four fields.
Derived Short Id
The corporation's short id is derived server-side from corporation_name: lowercased, every character
outside a-z0-9 replaced with -, repeated dashes collapsed, leading and trailing dashes removed, and
any leading non-alphanumeric characters dropped.
corporation_name | Derived short id |
|---|---|
Acme Inc. | acme-inc |
ACME & Sons (UK) Ltd | acme-sons-uk-ltd |
+Acme | acme |
The short id is not returned by GET /api/v1/corporations — the read path does not expose it today.
Code
const response = await fetch(`${baseUrl}/api/v1/corporations/register`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${partnerToken}`,
'Content-Type': 'application/json',
'X-User-Wallet': ownerEoaAddress,
'X-User-Email': ownerEmail,
'X-Chain-Id': chainId
},
body: JSON.stringify({
corporation_address: corporationAddress,
corporation_name: 'Acme Inc.',
corporation_registration_number: '12345678',
corporation_registration_country: 'GB'
})
});response = requests.post(
f"{base_url}/api/v1/corporations/register",
headers={
"Authorization": f"Bearer {partner_token}",
"Content-Type": "application/json",
"X-User-Wallet": owner_eoa_address,
"X-User-Email": owner_email,
"X-Chain-Id": chain_id,
},
json={
"corporation_address": corporation_address,
"corporation_name": "Acme Inc.",
"corporation_registration_number": "12345678",
"corporation_registration_country": "GB",
},
)body, _ := json.Marshal(map[string]string{
"corporation_address": corporationAddress,
"corporation_name": "Acme Inc.",
"corporation_registration_number": "12345678",
"corporation_registration_country": "GB",
})
req, _ := http.NewRequest("POST", baseURL+"/api/v1/corporations/register", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer "+partnerToken)
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-User-Wallet", ownerEoaAddress)
req.Header.Set("X-User-Email", ownerEmail)
req.Header.Set("X-Chain-Id", chainId)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()Step 2: Log In
POST /api/v1/corporations/login
Returns the corporation token every subsequent call needs. See
Authentication.
Step 3: Read the Corporation
GET /api/v1/corporations
Confirms what was written and shows what the corporation can do next — its status,
verification_status, the capability list and the allowed actions. See
Corporation Profile.
At this point the corporation is Pending with verification_status None or Pending, and every
capability that requires a verification level reads NotFulfilled. Start KYB next — see
Verification (KYB).
Step 4: Wait for the Primary Wallet
GET /api/v1/wallets
The corporation's Primary wallet is created asynchronously after registration and starts at
wallet_status Unknown. Poll until it reads Confirmed.
{
"data": [
{
"wallet_address": "0xA7E41d5680dE394EaA2ed417169DFf56840Fb3EE",
"wallet_name": "Main Wallet",
"wallet_status": "Confirmed",
"wallet_type": "Primary",
"balances": []
}
]
}
Confirmedon thePrimarywallet is the gate between registering and transacting. It means the
platform has verified the wallet carries the required modules and policy. Every funded flow — card
issuance fees, bank transfers, corridor transfers, FX — debits this wallet, so calling them before it
isConfirmedfails on a wallet the platform does not yet consider usable.
Rejectedmeans the wallet configuration is invalid. Re-check the executor, the corporate policy and
the signer module against Wallet Deployment — re-registering
does not repair it.
What Happens Next
- The corporation record is created with the supplied legal details.
- The owner's employee registration is completed — their wallet address and email are bound to the
employee record created on-chain bycreateCorporationForCorporateWallet. - The Wirex KYC oracle advances the on-chain corporation status as KYB progresses.
- A
/v2/webhooks/corporationsnotification is delivered on each corporation state change.
Error Handling
{
"error_reason": "ErrorGeneral",
"error_description": "Only owner of the corporation can register the corporation",
"error_category": {
"category": "CategoryUnauthorized",
"http_status_code": 401
}
}Validation Errors (400)
| Error Reason | Error Details | Description | Resolution |
|---|---|---|---|
ErrorMissingField | field: corporation_address | corporation_address not provided | Send the corporation wallet address |
ErrorInvalidField | field: corporation_address | Address format not recognised | Use the address form matching the chain |
ErrorInvalidField | field: corporation_name | Name contains disallowed characters or is outside 2–100 | Match the name regex |
ErrorInvalidField | field: corporation_registration_number | Not 6–15 uppercase alphanumerics or dashes | Uppercase the value |
ErrorInvalidField | field: corporation_registration_country | Not a two-letter uppercase code | Use ISO 3166-1 alpha-2, uppercase |
Authorization Errors (401)
| Error Reason | Description | Resolution |
|---|---|---|
ErrorGeneral | Only owner of the corporation can register the corporation — X-User-Wallet is not the corporation's owner address, or the caller's employee record does not hold the Owner role | Register from the address recorded as the corporation's creator on-chain |
Server Errors (500)
| Error Reason | Description | Resolution |
|---|---|---|
ErrorGeneral | Failed to get user from context | Send both X-User-Wallet and X-User-Email |
ErrorGeneral | Failed to query corporation | The corporation does not exist for this partner_id — complete on-chain registration first |
ErrorGeneral | Failed to query employee | No employee record for this address in this corporation — the on-chain owner assignment did not land |
ErrorGeneral | Failed to begin corporation registration | Downstream rejection. Registration is not partially applied; retry with corrected data |
ErrorGeneral | Failed to complete employee registration | The corporation record was created but the owner's employee record was not completed. Retry the call |
Registering a corporation that is already registered is refused downstream and surfaces as
Failed to begin corporation registration. ReadGET /api/v1/corporationsbefore retrying, to
distinguish "not registered" from "already registered".
Updated 20 days ago

