Reliance
Provide complete verified user data to Wirex when you handle KYC verification.
Before You Start
Read the following guides before proceeding:
| Guide | Why |
|---|---|
| Getting Started | Platform overview and setup |
| Api Basics | Required headers and request configuration |
| Authentication | How to obtain access tokens |
| Webhooks | Receive status notifications |
| Onboarding | User and wallet registration |
| User Profile | User 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
| Field | Type | Required | Validation |
|---|---|---|---|
wallet_address | string | Yes | User's EOA address |
initial_data.profile.email | string | Yes | Valid email format, must be unique |
initial_data.profile.first_name | string | Yes | Alphabetic characters |
initial_data.profile.last_name | string | Yes | Alphabetic characters |
initial_data.profile.date_of_birth | string | Yes | YYYY-MM-DD format |
initial_data.profile.nationality | string | Yes | ISO 3166-1 alpha-2 code |
initial_data.profile.phone_number | string | Yes | E.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
| Field | Type | Required | Validation |
|---|---|---|---|
initial_data.residence_address.line1 | string | Yes | Street address |
initial_data.residence_address.line2 | string | No | Apartment, suite, etc. |
initial_data.residence_address.city | string | Yes | City name |
initial_data.residence_address.state | string | No | State or province |
initial_data.residence_address.post_code | string | Yes | Postal code |
initial_data.residence_address.country | string | Yes | ISO 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 Type | Description |
|---|---|
selfie | User's selfie photo |
poi | Proof of Identity (passport, national ID, driver's license) |
poa | Proof 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 progressApproved→ verification complete, user is activeRejected→ verification failed, contact Wirex support
See Webhooks for payload details.
What Happens Next
After registration and document upload:
- Wirex validates the provided data and documents
- User record is created with the provided profile and address
- Webhook notification sent with
verification_statusupdates - 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
| Field | Error | Pattern/Requirement |
|---|---|---|
wallet_address | Invalid format | ^0x[a-fA-F0-9]{40}$ (EVM) |
first_name | Invalid format | ^[a-zA-Z][a-zA-Z\-' ]{1,50}$ |
last_name | Invalid format | ^[a-zA-Z][a-zA-Z\-' ]{1,50}$ |
date_of_birth | Invalid format | YYYY-MM-DD |
nationality | Invalid format | ISO 3166-1 alpha-2 (^[A-Z]{2}$) |
email | Invalid format | Valid email address |
phone_number | Invalid format | E.164 format (^\+?\d{1,15}$) |
Address Validation Errors
| Field | Error | Pattern/Requirement |
|---|---|---|
line1 | Invalid format | ^[A-Za-z0-9&.,''\-/() :+#]{2,100}$ |
line2 | Invalid format | ^[A-Za-z0-9&.,''\-/() :+#]{2,100}$ |
city | Invalid format | ^[A-Za-z\s\-'.]{2,100}$ |
state | Invalid format | ^[A-Za-z][A-Za-z\s\-']{1,99}$ |
post_code | Invalid format | ^[A-Za-z0-9\s\-]{3,12}$ |
country | Invalid format | ISO 3166-1 alpha-2 (^[A-Z]{2}$) |
Document Upload Errors
| Field | Error | Valid Values |
|---|---|---|
document | Missing | File is required |
document_type | Invalid | selfie, identity_card, passport, driver_license, proof_of_address, other |
document_country | Invalid | ISO 3166-1 alpha-2 |
side | Invalid | front, back, none |
Registration Errors
| Error Reason | Description | Resolution |
|---|---|---|
ErrorNotFound | Wallet not registered in Accounts contract | Complete on-chain registration first |
ErrorAlreadyExists | Email already exists | Use a different email address |
ErrorAlreadyExists | Wallet address already exists | User 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" }
]
}Updated 8 days ago
