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:

GuideWhy
Getting StartedIntegration overview
AuthenticationPartner token and identity headers
Wallet DeploymentThe 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:

  1. The corporation's owner_address on record equals the caller's X-User-Wallet.
  2. The caller's employee record inside that corporation holds the Owner role
    (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:

HeaderValue
AuthorizationBearer <partner_token>
X-User-WalletThe owner's EOA address — the signer behind the corporation wallet
X-User-EmailThe owner's email address
X-Chain-IdChain 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"
}
FieldTypeRequiredDescription
corporation_addressstringYesThe corporation wallet address created on-chain
corporation_namestringNoFull legal name. Validated when present
corporation_registration_numberstringNoCompany registration number. Validated when present
corporation_registration_countrystringNoISO 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

FieldValidation (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
and corporation_registration_country are 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 with Capability 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_nameDerived short id
Acme Inc.acme-inc
ACME & Sons (UK) Ltdacme-sons-uk-ltd
+Acmeacme

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": []
    }
  ]
}

Confirmed on the Primary wallet 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
is Confirmed fails on a wallet the platform does not yet consider usable.

Rejected means 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

  1. The corporation record is created with the supplied legal details.
  2. The owner's employee registration is completed — their wallet address and email are bound to the
    employee record created on-chain by createCorporationForCorporateWallet.
  3. The Wirex KYC oracle advances the on-chain corporation status as KYB progresses.
  4. A /v2/webhooks/corporations notification 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 ReasonError DetailsDescriptionResolution
ErrorMissingFieldfield: corporation_addresscorporation_address not providedSend the corporation wallet address
ErrorInvalidFieldfield: corporation_addressAddress format not recognisedUse the address form matching the chain
ErrorInvalidFieldfield: corporation_nameName contains disallowed characters or is outside 2–100Match the name regex
ErrorInvalidFieldfield: corporation_registration_numberNot 6–15 uppercase alphanumerics or dashesUppercase the value
ErrorInvalidFieldfield: corporation_registration_countryNot a two-letter uppercase codeUse ISO 3166-1 alpha-2, uppercase

Authorization Errors (401)

Error ReasonDescriptionResolution
ErrorGeneralOnly owner of the corporation can register the corporationX-User-Wallet is not the corporation's owner address, or the caller's employee record does not hold the Owner roleRegister from the address recorded as the corporation's creator on-chain

Server Errors (500)

Error ReasonDescriptionResolution
ErrorGeneralFailed to get user from contextSend both X-User-Wallet and X-User-Email
ErrorGeneralFailed to query corporationThe corporation does not exist for this partner_id — complete on-chain registration first
ErrorGeneralFailed to query employeeNo employee record for this address in this corporation — the on-chain owner assignment did not land
ErrorGeneralFailed to begin corporation registrationDownstream rejection. Registration is not partially applied; retry with corrected data
ErrorGeneralFailed to complete employee registrationThe 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. Read GET /api/v1/corporations before retrying, to
distinguish "not registered" from "already registered".


Did this page help you?