CustomerRegistrationByAffiliate¶
Endpoint¶
POST /customer/registration/by-affiliate
Creates a CRM lead attributed to an existing affiliate. The endpoint is
currently public and rate limited by source IP. It does not create a trading
account. When the requested brand has authorize_after_registration = 1, the
response also creates a customer session and contains __token and
__datalake_token. The latter can be null if the active v2 signer or
current authorization context is unavailable; registration still succeeds.
The server assigns a random identicon avatar derived from the customer's email
and a generated UUID. A client-supplied avatar is ignored; existing customer
records are not bulk-updated.
The former command AffiliateRegistration and endpoint
POST /affiliate/registration remain available as deprecated compatibility
aliases.
The affiliate code and its active access to the requested brand are validated. Under negotiated license brand policy v1, the requested brand must also be admitted for API use. The customer stores the affiliate's canonical string code. Browser fingerprint, installation ID, request host, and marketing-touch lookup are not used. Direct attribution is recorded for affiliate funnel statistics.
Authorization¶
No bearer token is required. affiliate_code is mandatory, but is an
identifier rather than a credential.
Request Parameters¶
| Field | Type | Required | Description |
|---|---|---|---|
affiliate_code |
string | Yes | Public affiliate code, 1–128 characters. The affiliate and its access to brand must both be active |
brand |
string | Yes | Brand code, 1–64 characters. The HTTP host is not used to resolve it |
email |
string | Yes | Customer email, 3–255 characters; must be unique |
password |
string | Yes | Customer cabinet password, 6–128 characters |
full_name |
string | Conditional | Display name, up to 255 characters. Required when no structured name component is supplied |
first_name |
string | Conditional | First name, up to 128 characters. At least one name field must be non-empty |
middle_name |
string | Conditional | Middle name, up to 128 characters |
last_name |
string | Conditional | Last name, up to 128 characters |
phone |
string | No | Customer phone, up to 64 characters. A number in international format +<code>... is used to resolve country_of_residence |
preferred_language |
string | No | Preferred language code, up to 16 characters |
timezone |
string | No | Customer timezone, up to 64 characters |
country_of_residence |
string | No | Country of residence, up to 64 characters. If absent, the server resolves an ISO 3166-1 alpha-2 code from the dialling code of a +-prefixed phone, then from the source IP. For a shared code such as +1 (US, CA), the source IP country is used when it is one of them, otherwise the code's primary country |
citizenship |
string | No | Citizenship, up to 64 characters |
address_of_residence |
string | No | Residence address, free text, up to 255 characters |
marketing_allowed |
int | No | Marketing consent: 0 or 1 |
lead_source |
string | No | Lead source, up to 128 characters. Defaults to affiliate |
campaign |
string | No | Caller-supplied campaign code, up to 128 characters |
introducer_id |
string | No | External introducer reference, up to 128 characters |
landing_url |
string | No | Landing URL, up to 2048 characters |
referrer_url |
string | No | Referrer URL, up to 2048 characters |
utm_source |
string | No | UTM source, up to 255 characters. Defaults to affiliate |
utm_medium |
string | No | UTM medium, up to 255 characters |
utm_campaign |
string | No | UTM campaign, up to 255 characters |
utm_content |
string | No | UTM content, up to 255 characters |
utm_term |
string | No | UTM term, up to 255 characters |
meta_json |
string | No | Integration metadata encoded as a string, up to 4000 characters |
group_name |
string | No | Deprecated compatibility field, up to 32 characters. Accepted but ignored; no account is opened |
source_type is not accepted from the caller and is always set to 3
(CUSTOMER_SOURCE_AFFILIATE). Name normalization follows
CustomerRegistration.
Request Example¶
{
"affiliate_code": "AFF-PRIMARY",
"brand": "ALFA",
"email": "[email protected]",
"password": "strong-password",
"first_name": "John",
"middle_name": "Michael",
"last_name": "Smith",
"full_name": "John Michael Smith",
"phone": "+35700000000",
"preferred_language": "en",
"timezone": "Asia/Nicosia",
"country_of_residence": "CY",
"citizenship": "CY",
"address_of_residence": "12 Example Street, Limassol",
"marketing_allowed": 1,
"lead_source": "affiliate-portal",
"campaign": "AFF_Q4",
"introducer_id": "partner-lead-501",
"landing_url": "https://partner.example/register",
"referrer_url": "https://partner.example/",
"utm_source": "partner-portal",
"utm_medium": "affiliate",
"utm_campaign": "autumn",
"utm_content": "banner-a",
"utm_term": "forex",
"meta_json": "{\"external_lead_id\":\"501\"}"
}
Response Parameters¶
| Field | Type | Description |
|---|---|---|
registered |
bool | true after the customer was created |
__token |
string | Conditional primary customer session JWT, present only when the brand has authorize_after_registration = 1 |
__datalake_token |
string or null | Conditional Data Lake JWT for the issued session; may be null when the v2 signer or current authorization context is unavailable |
affiliate_code |
string | Canonical affiliate code resolved from the request |
account_created |
bool | Always false; account creation is delegated to workflow |
account_creation |
string | Always workflow |
deprecated_fields |
string[] | Present only when deprecated input was supplied; currently may contain group_name |
customer |
object | Complete created customer record described below |
customer object¶
| Field | Type | Description |
|---|---|---|
customer_id |
int | Server-assigned customer identifier |
external_id |
string | External customer identifier; empty for public registration |
type |
int | Customer type; public registration forces individual customer |
status |
int | Customer status; initially active |
lifecycle_flags |
int64 | Milestone bit mask; initially 0 |
customer_kind |
int | 0 lead, 1 client; initially 0 |
conversion_flags |
int64 | Conversion snapshot; initially 0 |
enable |
int | Customer enabled flag; initially 1 |
enable_otp |
int | OTP flag; initially 0 |
deposit_allowed |
int | Deposit permission; initially 1 |
withdrawal_allowed |
int | Withdrawal permission; initially 1 |
first_name |
string | Normalized first name |
last_name |
string | Normalized last name |
middle_name |
string | Normalized middle name |
full_name |
string | Normalized display name |
birth_date |
int64 | Birth date timestamp; initially 0 because this endpoint does not accept it |
citizenship |
string | Supplied citizenship |
country_of_residence |
string | Supplied country, or the ISO 3166-1 alpha-2 code resolved from the phone or by GeoIP |
address_of_residence |
string | Supplied residence address |
avatar |
string | Server-generated public identicon reference; client-supplied values are ignored |
email |
string | Customer email |
phone |
string | Customer phone |
preferred_language |
string | Preferred language |
timezone |
string | Customer timezone |
brand |
string | Canonical brand code |
desk |
string | CRM desk; initially empty |
manager_id |
int | CRM manager; initially 0 |
lead_source |
string | Supplied lead source or affiliate |
campaign |
string | Supplied campaign code |
affiliate_id |
string | Canonical affiliate code, not the numeric request identifier |
introducer_id |
string | Supplied introducer reference |
source_type |
int | Always 3 for this method |
landing_url |
string | Supplied landing URL |
referrer_url |
string | Supplied referrer URL |
utm_source |
string | Supplied UTM source or affiliate |
utm_medium |
string | Supplied UTM medium |
utm_campaign |
string | Supplied UTM campaign |
utm_content |
string | Supplied UTM content |
utm_term |
string | Supplied UTM term |
import_batch_id |
string | Import batch; initially empty |
old_id |
string | Legacy identifier; initially empty |
created_by_import |
int | CRM import marker; always 0 for this method |
assigned_manager_id |
int | Assigned CRM manager; initially 0 |
crm_stage |
string | CRM stage; initially empty |
segment |
string | CRM segment; initially empty |
tags_json |
string | CRM tags; initially empty |
email_verified |
int | Email verification flag; initially 0 |
phone_verified |
int | Phone verification flag; initially 0 |
marketing_allowed |
int | Supplied marketing consent or its default |
tax_id |
string | Tax ID; initially empty |
national_id |
string | National ID; initially empty |
pep_status |
int | PEP status; forced to the public-registration default |
sanctions_status |
int | Sanctions status; forced to the public-registration default |
risk_level |
int | Risk level; initially low risk |
aml_status |
int | AML status; initially pending |
kyc_status |
int | KYC status; initially not verified |
kyc_current_level |
int | Current KYC level; initially 0 |
kyc_required_level |
int | Required KYC level; initially 0 |
kyc_risk_level |
int | KYC risk level; initially 0 |
sales_status |
int | Sales status; initially 0 |
risk_status |
int | Risk workflow status; initially 0 |
finance_status |
int | Finance workflow status; initially 0 |
kyc_updated_time |
int64 | Last KYC update time; initially 0 |
aml_updated_time |
int64 | Last AML update time; initially 0 |
last_contact_time |
int64 | Last contact time; initially 0 |
first_contact_time |
int64 | First contact time; initially 0 |
next_contact_time |
int64 | Next planned contact time; initially 0 |
conversion_time |
int64 | Conversion time; initially 0 |
last_login_time |
int64 | Last customer login time; initially 0 |
last_online_time |
int64 | Read-only time when any trading account of the customer last went offline in the trading terminal; initially 0 |
archive_time |
int64 | Archive time; initially 0 |
created_time |
int64 | Creation time as Unix timestamp |
updated_time |
int64 | Last update time as Unix timestamp |
created_by |
int | Creating manager; initially 0 for public intake |
updated_by |
int | Updating manager; initially 0 |
registration_ip |
string | Source IP supplied by the HTTP layer |
meta_json |
string | Supplied integration metadata |
Full Response Example¶
{
"registered": true,
"customer": {
"customer_id": 1042,
"external_id": "",
"type": 0,
"status": 0,
"lifecycle_flags": 0,
"customer_kind": 0,
"conversion_flags": 0,
"enable": 1,
"enable_otp": 0,
"deposit_allowed": 1,
"withdrawal_allowed": 1,
"first_name": "John",
"last_name": "Smith",
"middle_name": "Michael",
"full_name": "John Michael Smith",
"birth_date": 0,
"citizenship": "CY",
"country_of_residence": "CY",
"address_of_residence": "12 Example Street, Limassol",
"avatar": "8e68414e-0e3f-48dd-b7b8-f5be9e26d4f7.svg",
"email": "[email protected]",
"phone": "+35700000000",
"preferred_language": "en",
"timezone": "Asia/Nicosia",
"brand": "ALFA",
"desk": "",
"manager_id": 0,
"lead_source": "affiliate-portal",
"campaign": "AFF_Q4",
"affiliate_id": "AFF-PRIMARY",
"introducer_id": "partner-lead-501",
"source_type": 3,
"landing_url": "https://partner.example/register",
"referrer_url": "https://partner.example/",
"utm_source": "partner-portal",
"utm_medium": "affiliate",
"utm_campaign": "autumn",
"utm_content": "banner-a",
"utm_term": "forex",
"import_batch_id": "",
"old_id": "",
"created_by_import": 0,
"assigned_manager_id": 0,
"crm_stage": "",
"segment": "",
"tags_json": "",
"email_verified": 0,
"phone_verified": 0,
"marketing_allowed": 1,
"tax_id": "",
"national_id": "",
"pep_status": 0,
"sanctions_status": 0,
"risk_level": 0,
"aml_status": 0,
"kyc_status": 0,
"kyc_current_level": 0,
"kyc_required_level": 0,
"kyc_risk_level": 0,
"sales_status": 0,
"risk_status": 0,
"finance_status": 0,
"kyc_updated_time": 0,
"aml_updated_time": 0,
"last_contact_time": 0,
"first_contact_time": 0,
"next_contact_time": 0,
"conversion_time": 0,
"last_login_time": 1790236800,
"last_online_time": 0,
"archive_time": 0,
"created_time": 1790236800,
"updated_time": 1790236800,
"created_by": 0,
"updated_by": 0,
"registration_ip": "203.0.113.10",
"meta_json": "{\"external_lead_id\":\"501\"}"
},
"__token": "<HS256 session JWT>",
"__datalake_token": "<EdDSA Data Lake JWT or null>",
"affiliate_code": "AFF-PRIMARY",
"account_created": false,
"account_creation": "workflow"
}
__token and __datalake_token are conditional. Both are absent, and
last_login_time remains 0, when the brand has
authorize_after_registration = 0. When a session is created, the Data Lake
token follows the Data Lake token profile; it may be null if signing is unavailable.
When group_name was supplied, the same response additionally contains
"deprecated_fields": ["group_name"].
Workflow¶
Successful creation emits customer.created. To provision an account,
configure a CRM workflow with account.open. It requires params.group,
accepts optional positive params.leverage, verifies that the enabled group
belongs to the customer brand, and is idempotent for customer plus group. For a
new account, the action applies the target group's positive default_deposit
through the standard balance-in finance path; an existing account is not
credited again.
Errors¶
| HTTP | Error | Description |
|---|---|---|
400 |
INVALID_DATA |
Invalid field type/length or no usable name |
403 |
INVALID_AFFILIATE |
Affiliate is missing, inactive, or unavailable for the brand |
403 |
BRAND_NOT_AVAILABLE |
Brand is disabled in legacy mode |
404 |
BRAND_NOT_FOUND |
Body brand is unknown, or negotiated license policy denies API admission |
409 |
DUPLICATE_RECORD |
Email is already registered |
429 |
rate limit | More than 10 registration attempts per minute from one source IP |