Reliance

Provide complete verified user data to Wirex when you handle KYC verification.

Before You Start

Read the following guides before proceeding:

GuideWhy
Getting StartedPlatform overview and setup
Api BasicsRequired headers and request configuration
AuthenticationHow to obtain access tokens
WebhooksReceive status notifications
OnboardingUser and wallet registration
User ProfileUser capabilities and status

When to Use

  • You perform full KYC verification on your platform
  • You want to provide complete user data at registration
  • Users should be immediately active without additional verification

Approval Required: Reliance is only available after a detailed audit by Wirex and may be rejected. Contact your Wirex account manager to discuss eligibility and requirements.


Request

POST /api/v2/user
{
  "wallet_address": "0xA7E41d5680dE394EaA2ed417169DFf56840Fb3EE",
  "initial_data": {
    "profile": {
      "first_name": "Alex",
      "last_name": "Grey",
      "date_of_birth": "1990-01-15",
      "nationality": "GB",
      "email": "[email protected]",
      "phone_number": "+447700900123"
    },
    "residence_address": {
      "line1": "10 Downing Street",
      "line2": "Flat 2",
      "city": "London",
      "post_code": "SW1A 2AA",
      "country": "GB"
    }
  }
}

Field Requirements

Important: The wallet_address must be the user's EOA address (the signer), not the Smart Wallet address.

Profile Fields

FieldTypeRequiredValidation
wallet_addressstringYesUser's EOA address
initial_data.profile.emailstringYesValid email format, must be unique
initial_data.profile.first_namestringYesAlphabetic characters
initial_data.profile.last_namestringYesAlphabetic characters
initial_data.profile.date_of_birthstringYesYYYY-MM-DD format
initial_data.profile.nationalitystringYesISO 3166-1 alpha-2 code
initial_data.profile.phone_numberstringYesE.164 format (e.g., +447700900123)

Phone Number: The phone number provided during reliance onboarding is automatically marked as confirmed. It will be used for 3DS Authentication OTP codes and Read Card Details OTP verification. No separate confirmation step is required.

Address Fields

FieldTypeRequiredValidation
initial_data.residence_address.line1stringYesStreet address
initial_data.residence_address.line2stringNoApartment, suite, etc.
initial_data.residence_address.citystringYesCity name
initial_data.residence_address.statestringNoState or province
initial_data.residence_address.post_codestringYesPostal code
initial_data.residence_address.countrystringYesISO 3166-1 alpha-2 code

Code Examples

async function registerUserReliance(accessToken, walletAddress, profile, address, chainId, baseUrl) {
  const response = await fetch(`${baseUrl}/api/v2/user`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
      'X-Chain-Id': chainId.toString(),
    },
    body: JSON.stringify({
      wallet_address: walletAddress,
      initial_data: { profile, residence_address: address },
    }),
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(`Registration failed: ${error.error_description}`);
  }
  return response.json();
}

// Usage
const profile = {
  first_name: 'Alex', last_name: 'Grey', date_of_birth: '1990-01-15',
  nationality: 'GB', email: '[email protected]', phone_number: '+447700900123',
};
const address = {
  line1: '10 Downing Street', line2: 'Flat 2', city: 'London',
  post_code: 'SW1A 2AA', country: 'GB',
};

const { id } = await registerUserReliance(
  access_token, '0xA7E41d5680dE394EaA2ed417169DFf56840Fb3EE',
  profile, address, 8453, 'https://api-baas.wirexapp.com'
);
import requests

def register_user_reliance(access_token, wallet_address, profile, residence_address, chain_id, base_url):
    response = requests.post(
        f"{base_url}/api/v2/user",
        headers={
            "Authorization": f"Bearer {access_token}",
            "Content-Type": "application/json",
            "X-Chain-Id": str(chain_id),
        },
        json={
            "wallet_address": wallet_address,
            "initial_data": {"profile": profile, "residence_address": residence_address},
        },
    )
    response.raise_for_status()
    return response.json()

# Usage
profile = {
    "first_name": "Alex", "last_name": "Grey", "date_of_birth": "1990-01-15",
    "nationality": "GB", "email": "[email protected]", "phone_number": "+447700900123",
}
address = {
    "line1": "10 Downing Street", "line2": "Flat 2", "city": "London",
    "post_code": "SW1A 2AA", "country": "GB",
}

user = register_user_reliance(
    access_token, "0xA7E41d5680dE394EaA2ed417169DFf56840Fb3EE",
    profile, address, 8453, "https://api-baas.wirexapp.com"
)
func RegisterUserReliance(accessToken, walletAddress string, profile, address map[string]string, chainID int, baseURL string) (string, error) {
    reqBody, _ := json.Marshal(map[string]interface{}{
        "wallet_address": walletAddress,
        "initial_data": map[string]interface{}{
            "profile": profile, "residence_address": address,
        },
    })

    req, _ := http.NewRequest("POST", baseURL+"/api/v2/user", bytes.NewBuffer(reqBody))
    req.Header.Set("Authorization", "Bearer "+accessToken)
    req.Header.Set("Content-Type", "application/json")
    req.Header.Set("X-Chain-Id", fmt.Sprintf("%d", chainID))

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return "", err
    }
    defer resp.Body.Close()

    var result struct{ ID string `json:"id"` }
    json.NewDecoder(resp.Body).Decode(&result)
    return result.ID, nil
}

Document Upload

After user registration, you must upload verification documents.

POST /api/v1/user/documents

Required Documents

Document TypeDescription
selfieUser's selfie photo
poiProof of Identity (passport, national ID, driver's license)
poaProof of Address (utility bill, bank statement)

All documents must be uploaded before the user account can be fully activated.


Flow

sequenceDiagram
    participant Backend as Your Backend
    participant BaaS as Wirex API

    Backend->>BaaS: 1. POST /api/v2/user { wallet_address, initial_data }
    BaaS-->>Backend: { id }

    Backend->>BaaS: 2. POST /api/v1/user/documents (selfie, poi, poa)

    Note over BaaS: 3. Validate data & docs
    Note over BaaS: 4. Activate account

    BaaS->>Backend: 5. POST /webhook/users (verification_status)

Webhooks

Wirex sends webhook notifications when verification status changes.

Note: This is a legacy webhook format that will be replaced with a v2 model in a future release.

Endpoint: POST {your_webhook_base_url}/webhook/users

You will receive status updates as verification progresses:

  • Applied → documents received, validation in progress
  • Approved → verification complete, user is active
  • Rejected → verification failed, contact Wirex support

See Webhooks for payload details.


What Happens Next

After registration and document upload:

  1. Wirex validates the provided data and documents
  2. User record is created with the provided profile and address
  3. Webhook notification sent with verification_status updates
  4. User account is activated upon approval

The user can perform all operations once verification is approved.


Your Responsibilities

When using reliance onboarding, you are responsible for:

  • Performing identity verification to regulatory standards
  • Maintaining verification records and audit trails
  • Ensuring data accuracy and currency
  • Complying with applicable KYC/AML regulations

Error Handling

Profile Validation Errors

FieldErrorPattern/Requirement
wallet_addressInvalid format^0x[a-fA-F0-9]{40}$ (EVM)
first_nameInvalid format^[a-zA-Z][a-zA-Z\-' ]{1,50}$
last_nameInvalid format^[a-zA-Z][a-zA-Z\-' ]{1,50}$
date_of_birthInvalid formatYYYY-MM-DD
nationalityInvalid formatISO 3166-1 alpha-2 (^[A-Z]{2}$)
emailInvalid formatValid email address
phone_numberInvalid formatE.164 format (^\+?\d{1,15}$)

Address Validation Errors

FieldErrorPattern/Requirement
line1Invalid format^[A-Za-z0-9&.,''\-/() :+#]{2,100}$
line2Invalid format^[A-Za-z0-9&.,''\-/() :+#]{2,100}$
cityInvalid format^[A-Za-z\s\-'.]{2,100}$
stateInvalid format^[A-Za-z][A-Za-z\s\-']{1,99}$
post_codeInvalid format^[A-Za-z0-9\s\-]{3,12}$
countryInvalid formatISO 3166-1 alpha-2 (^[A-Z]{2}$)

Document Upload Errors

FieldErrorValid Values
documentMissingFile is required
document_typeInvalidselfie, identity_card, passport, driver_license, proof_of_address, other
document_countryInvalidISO 3166-1 alpha-2
sideInvalidfront, back, none

Registration Errors

Error ReasonDescriptionResolution
ErrorNotFoundWallet not registered in Accounts contractComplete on-chain registration first
ErrorAlreadyExistsEmail already existsUse a different email address
ErrorAlreadyExistsWallet address already existsUser already registered

Error Response Format

{
  "error_reason": "ErrorInvalidField",
  "error_description": "Invalid format for phone_number",
  "error_category": {
    "category": "CategoryValidationFailure",
    "http_status_code": 400
  },
  "error_details": [
    { "key": "field", "details": "initial_data.profile.phone_number" },
    { "key": "issue", "details": "invalid_format" }
  ]
}