Webmasters: token and landing page setup
How to create a webmaster in X10 CRM, get an API token and connect a landing page so that leads arrive with the right fields, source and UTM tags.
A webmaster is a partner or traffic source that holds its own token and can create leads in X10 CRM through the public API. Every lead is automatically signed with that webmaster: the source is visible, and reporting and payouts work. This page covers the whole path — from creating the token to a working form on the landing page.
Why this matters at the process level is on the CRM for dropshipping page: where leads come from, how each source's conversion is measured and what exactly you pay a partner for.
#Step 1. Create a webmaster and get the token
- 01
Open the “Webmasters” section
Choose Webmasters in the CRM side menu. It lists every partner, their tokens, the payout amount and whether they are active.
- 02
Click “Add webmaster”
Enter a name (it also becomes the lead source in the card, so make it readable:
Instagram Ads,Partner Ivanov,Landing shop-example) and the payout per lead. The amount can be changed later. - 03
Copy the token
The token is generated automatically — a random 43-character string. The table shows the ready-made API address next to it. Copy it with the button rather than by selecting it with the mouse: a stray trailing space breaks authorisation.
#Step 2. The API address
A lead is created with a single POST request. The token goes straight into the path — no separate authorisation headers are needed.
https://crm.your-domain.com/api/webmasters/{TOKEN}/leads/create/crm.your-domain.com— replace it with your CRM address (the same one you sign in to).{TOKEN}— the webmaster token from the previous step.- The trailing slash is required.
- The method is
POSTonly.GETreturns 405.
#Step 3. The first test request
Before touching the landing page, make sure the token works. Run the request from a terminal — the lead should appear in the CRM within seconds.
curl -X POST "https://crm.your-domain.com/api/webmasters/YOUR_TOKEN/leads/create/" \
-H "Content-Type: application/json" \
-d '{"phone": "380681234567", "fullname": "Test from the documentation"}'A successful response looks like this — lead_id is the number of the created lead:
{"ok": true, "lead_id": 10241}#Request format
| Parameter | Value |
|---|---|
| Method | POST (anything else returns 405) |
| Content-Type | application/json or application/x-www-form-urlencoded (a plain HTML form) |
| Authorisation | The token in the path. No headers, cookies or CSRF token required |
| Encoding | UTF-8; Cyrillic is supported |
#Lead fields
Only one field is required — phone. The rest are optional, but the more you send, the less the operator has to fill in by hand.
Required
phonestring, up to 32requiredThe customer’s phone number. Everything but digits is stripped automatically:
+38 (068) 123-45-67is stored as380681234567. We recommend sending the international format without the plus sign.
Main card fields
fullnamestring, up to 200The customer’s name.
commenttextA comment on the lead. A good place for the contents of the order: product, quantity.
landingstring, up to 255The name or domain of the landing page. Visible in the card and available in filters — the main way to separate several sites belonging to one webmaster.
project_idnumberThe ID of the CRM project the lead should land in. If omitted, the lead is created without a project.
date_of_birthstringDate of birth as
dd.mm.yyyyoryyyy-mm-dd. Any other format is stored as is, without an error.last_order_checktextA note about the customer’s previous order.
prev_delivery_citystring, up to 255The city of the previous delivery.
prev_np_departmentstring, up to 255The branch used for the previous delivery.
Delivery
citystring, up to 255Town or city.
city_refstring, up to 80The city REF from the Nova Poshta directory — send it and the operator will not have to look the city up by hand.
settlement_refstring, up to 80The Nova Poshta settlement REF.
np_departmentstring, up to 255Branch or parcel locker.
np_department_refstring, up to 80The Nova Poshta branch REF.
address, house, flat, floor, entrancestring, up to 255Courier delivery: street, house, flat, floor, entrance.
delivery_type, payment_typestring, up to 255The delivery and payment method as the customer chose them on the landing page.
Traffic tags
utm_source, utm_medium, utm_campaign, utm_content, utm_termstring, up to 255Standard UTM tags. Always send them — this is the only way to know which campaign brought the lead.
#What the CRM fills in itself
| Field | Value |
|---|---|
| Source | The name of the webmaster who owns the token |
| Source type | webmaster plus a link to the specific webmaster for reporting and payouts |
| Status | The status with the new code. If there is no such status in the CRM, the lead is created without one |
| Manager | Not assigned: the lead goes into the shared queue |
| Contact | Looked up by the same phone number. If the customer already exists, the lead is attached to the existing contact, and the name is only filled in when it was empty |
#Step 4. Connect the landing page
There are three workable ways. The first is the most reliable: the token stays on the server and you can see the result of every request.
<?php
// send-lead.php — the landing form posts here, and this file posts to the CRM.
// The token stays on the server and never reaches the page source.
$token = getenv('X10_WM_TOKEN');
$url = "https://crm.your-domain.com/api/webmasters/{$token}/leads/create/";
$payload = [
'phone' => $_POST['phone'] ?? '',
'fullname' => $_POST['name'] ?? '',
'comment' => $_POST['comment'] ?? '',
'landing' => $_SERVER['HTTP_HOST'] ?? '',
'city' => $_POST['city'] ?? '',
'np_department'=> $_POST['np'] ?? '',
'utm_source' => $_POST['utm_source'] ?? '',
'utm_medium' => $_POST['utm_medium'] ?? '',
'utm_campaign' => $_POST['utm_campaign'] ?? '',
];
$ch = curl_init($url);
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode($payload, JSON_UNESCAPED_UNICODE),
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 10,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status === 200) {
header('Location: /thank-you');
exit;
}
error_log("X10 CRM: lead was not created. HTTP {$status} {$response}");
header('Location: /?error=1');#Responses and errors
| Code | Response body | What happened |
|---|---|---|
| 200 | {"ok": true, "lead_id": 10241} | The lead was created; lead_id is its number in the CRM |
| 400 | {"error": "phone_required"} | phone was not sent, or it is empty once non-digit characters are stripped |
| 403 | {"error": "invalid_token"} | The token does not exist, was copied with extra characters, or the webmaster is disabled |
| 405 | — | The request used a method other than POST |
#Token security
- The token allows creating leads only. It gives no access to the database, calls or settings.
- In the browser version the token is visible in the page source. That is an acceptable risk (the worst case is spam leads), but if the traffic source is doubtful, proxy the request through your own backend.
- A compromised token is replaced in half a minute: Webmasters → edit → Generate new token. The old one stops working instantly — remember to update every landing page.
- To pause a partner temporarily, clear the Active checkbox: the API starts returning 403 immediately and the lead history is preserved.
#If something does not work
| Symptom | Cause | What to do |
|---|---|---|
403 invalid_token | A space or line break in the token; the webmaster is disabled; the token was regenerated | Copy the token with the button in the CRM and check the “Active” switch |
400 phone_required | The field on the landing page is called tel, telephone or user_phone | The field must be named exactly phone |
| The lead is created but the fields are empty | The field names do not match the list | Compare the names with the “Lead fields” section. Anything extra can be found in the lead’s metadata.payload |
| The lead has no status | The CRM has no status with the new code | Settings → CRM → Statuses: add one or rename a status code to new |
| A CORS error in the browser console | The landing page domain has not been added to the CRM allowed origins yet | Send us the domain and we will allow it. Or send the request from your own server (the PHP option) |
| Duplicate identical leads | The form is submitted several times in a row | Disable the submit button until the request finishes |
| No leads at all | The wrong CRM domain, or a missing trailing slash in the address | Check the address in the “API address” section — the trailing slash is required |
#Checklist before you send traffic
- The webmaster is created, the payout is set and the “Active” switch is on
- A test cURL request returned
{"ok": true}and the lead is visible in the CRM - The
phonefield arrives in international format landingis sent — so that sites can be told apart- UTM tags from the page address are passed through
- If you submit from the browser, the landing domain is in the CRM allowed origins
- The CRM has a status with the
newcode - The submit button is disabled while the request is in flight
- After a successful submission the visitor sees a thank-you page