Referral system
A set of methods for working with the bot's referral program: issuing referral codes, statistics on referred users, reward balance, and payouts.
Throughout all methods, a "user" means a Telegram user of your bot, and is passed as
user_id(this is the Telegram ID, not your internal ID).
How it works in a nutshell
You create a referral code for a user (
create-code) and give them a link likehttps://t.me/your_bot?start=CODE.When a new person follows this link, they are automatically counted as a referral for this user.
If you use your own codes (not issued by this API), let the system know who owns which code via
set-code-owners.To find out how many people a user has referred and how much they're owed, use the
referralsandbalancemethods.When a user wants to withdraw their reward, call
payout.If an accrual turns out to be erroneous, it can be reversed via
reverse-accrual.
1. Create a referral code
POST /v1/referral/create-code (GET is also supported)
Creates a new unique referral code for a user and immediately returns a ready-made invitation link. The same user can have any number of codes — each call creates a new code, and old ones are not revoked.
Parameters
user_id
int
yes
Telegram ID of the user for whom the code is created (referrer)
Example call
Response
code
string
The code itself, 8 characters. Digits and letters without easily confused characters (no 0, O, 1, l, I), so the code is easy to read and enter manually
link
string|null
Ready-made invitation link in the form https://t.me/<bot>?start=<code>. Will be null if the bot has no username set
Possible errors
400
user_id not provided, or is not a number
Provide a valid Telegram ID
401
API key not provided or invalid
Check the Api-Key header / api-key parameter
500
Internal server error
Retry the request later; if it keeps happening, contact support
2. Assign an owner to a code (set-code-owners)
2. Assign an owner to a code (set-code-owners)
POST /v1/referral/set-code-owners
This method is only needed in one case: if your bot itself generates or issues referral codes (not via create-code), and our system doesn't know about it. The method tells the system: "this code belongs to this user."
An additional effect is backfilling: if there were already visits via this code before you reported the owner, all of them will be retroactively counted for this user as referrals.
You can pass several codes in a single request.
Parameters (request body — array of objects)
code
string
yes
Referral code
user_id
int
yes
Telegram ID of the code owner (referrer)
Example call
Response
code
string
The code that was processed
owner_id
int
Telegram ID that was assigned to the code
created
bool
true — the code didn't exist before and was just registered. false — the code already existed and was simply assigned an owner
backfilled
int
How many past visits via this code retroactively got this owner as their referrer
Possible errors
400
Request body is not an array, or is an empty array
Provide a non-empty JSON array of objects
400
One of the objects is missing code or user_id (or user_id equals 0)
Check that both fields are filled in for each object
401
API key not provided or invalid
Check the API key
500
Internal server error
Retry the request later
3. List of a user's codes
GET /v1/referral/codes
Returns all referral codes issued to a specific user via create-code, plus the total number of people they've referred (across all of their codes combined).
Parameters
user_id
int
yes
Telegram ID of the user
Example call
Response
total_referrals
int
Total number of people this user has referred (across all of their codes)
codes
array
List of codes, newest to oldest
codes[].code
string
The code
codes[].link
string|null
Ready-made invitation link
codes[].date_create
string
Date and time the code was created (YYYY-MM-DD HH:MM:SS, UTC)
The method only shows codes created via
create-code. Codes assigned viaset-code-ownerswithout prior creation will not appear in this list.
Possible errors
400
user_id not provided, or is not a number
Provide a valid Telegram ID
401
API key not provided or invalid
Check the API key
500
Internal server error
Retry the request later
4. List of referred users
GET /v1/referral/referrals
Returns a list of people the user has referred via their referral codes (across all codes combined), with the date of each visit.
Parameters
user_id
int
yes
—
Telegram ID of the referrer
limit
int
no
50
How many records to return at once (1 to 200; out-of-range values are automatically clamped to the bounds)
offset
int
no
0
How many records to skip from the start of the list — used for pagination
Example call
Response
referrals
array
List of referred users, newest to oldest
referrals[].referral_id
int
Telegram ID of the referred user
referrals[].date
string
Date and time the user followed the referral link (UTC)
Possible errors
400
user_id not provided, or is not a number
Provide a valid Telegram ID
401
API key not provided or invalid
Check the API key
500
Internal server error
Retry the request later
5. Reward balance
GET /v1/referral/balance
Shows how much money (or other reward currency) the user has accumulated for the people they've referred, broken down by status.
Parameters
user_id
int
yes
Telegram ID of the referrer
Example call
Response
balance
array
One row per currency (unit_id) for which the user has any accruals
balance[].unit_id
int
Identifier of the reward currency/unit
balance[].available
number
Available for withdrawal right now
balance[].reserved
number
Reserved — already included in a created but not yet processed payout
balance[].paid
number
Already paid out to the user previously
balance[].on_hold
number
On hold — accrued but not yet confirmed for payout (e.g. pending review)
Possible errors
400
user_id not provided, or is not a number
Provide a valid Telegram ID
401
API key not provided or invalid
Check the API key
500
Internal server error
Retry the request later
6. Request a payout
POST /v1/referral/payout
Initiates a payout of the user's entire available (available) balance. The method only creates a payout request — the actual payout (e.g. sending a webhook notification about the disbursement) is carried out by the system separately, on a schedule.
Important: the method does not check a minimum withdrawal threshold and does not ask for confirmation — if you call it, a request is created immediately for the full available amount. The decision of when to call this method (e.g. only once the user has accumulated at least 100 ₸) is up to your bot.
Parameters
user_id
int
yes
—
Telegram ID of the referrer
unit_id
int
no
not set
The currency to withdraw funds in. If not provided, the entire available balance is withdrawn across any currency where it exists
method
string
no
webhook
Payout execution method: webhook — the system will send a payout notification to your webhook itself; manual — the payout will be marked as requiring manual processing by an administrator
Example call
POST /v1/referral/payout
Response
payout_id
int
Identifier of the created payout request. Use it to find this payout in GET /v1/referral/payouts
Possible errors
400
user_id not provided, or is not a number
Provide a valid Telegram ID
400
The user has no available balance to withdraw (no available balance)
Check the balance via GET /v1/referral/balance before calling — there's nothing to withdraw if available is zero
401
API key not provided or invalid
Check the API key
500
Internal server error
Retry the request later
7. Payout history
GET /v1/referral/payouts
Returns a list of all of the user's payout requests — both already processed ones and those still in progress.
Parameters
user_id
int
yes
—
Telegram ID of the referrer
limit
int
no
50
How many records to return at once (1 to 200)
offset
int
no
0
How many records to skip from the start of the list
Example call
Response
payouts
array
List of payout requests, newest to oldest
payouts[].payout_id
int
Identifier of the request
payouts[].amount
number
Payout amount
payouts[].unit_id
int
Payout currency/unit
payouts[].status
int
Numeric status of the request (internal processing stage)
payouts[].method
string
Execution method: webhook or manual
payouts[].initiated_by
string
Who initiated the request: api (via this method), admin (manually in the admin panel), or auto (automatically by the system)
payouts[].requested_at
string
Date and time the request was created (UTC)
payouts[].processed_at
string|null
Date and time the request was actually processed. null if not yet processed
Possible errors
400
user_id not provided, or is not a number
Provide a valid Telegram ID
401
API key not provided or invalid
Check the API key
500
Internal server error
Retry the request later
8. Reverse an accrual
POST /v1/referral/reverse-accrual
Cancels one specific reward accrual by its identifier (accrual_id). Used when an accrual was made by mistake (for example, a referred user's payment was cancelled or refunded).
The behavior depends on the accrual's current state:
if the accrual hasn't been paid out yet — it's simply marked as cancelled, and the amount disappears from the user's balance;
if the accrual has already been paid out — a compensating record is created (essentially a "minus" for the same amount), and the accrual itself is marked as reversed.
Parameters (request body)
accrual_id
int
yes
Identifier of the accrual to be reversed
reason
string
no
Reason for the reversal — stored for history, doesn't affect anything
Example call
Response
The method returns no additional data — a successful response (ok: true) means the accrual has been reversed.
Possible errors
400
accrual_id not provided
Provide a valid accrual identifier
404
No accrual found with this accrual_id (or it belongs to another bot)
Check that accrual_id is correct and belongs to your bot
409
The accrual is already in a state that doesn't allow reversal (e.g. already reversed earlier)
No need to reverse it again — the accrual is already inactive
401
API key not provided or invalid
Check the API key
500
Internal server error
Retry the request later
9. Mark a user as a referral (mark-referral)
POST /v1/referral/mark-referral
Directly marks a user as a referral — without following a referral link. Use this if you already know (from your own data) that a user came from a specific referrer, and just want to inform the system about it.
Specify the referrer one of two ways:
code— an existing referral code (issued viacreate-codeor reported viaset-code-owners);referrer_user_id— the referrer's Telegram ID directly. If they don't have a code yet, one will be created automatically.
You cannot pass both parameters at the same time.
The method is idempotent: if the user already has a linked referrer (including from an earlier link visit), a repeat call changes nothing — the response returns the existing referrer.
Parameters (request body)
referral_user_id
int
yes
Telegram ID of the user to be marked as a referral
code
string
one of two (code or referrer_user_id)
An existing referral code of the referrer
referrer_user_id
int
one of two (code or referrer_user_id)
Telegram ID of the referrer
Example call
Response
referral_id
int
Telegram ID of the marked referral (same as referral_user_id)
referrer_id
int|null
Telegram ID of the referrer. null is only possible when linking by code, if that code doesn't yet have a known owner
code
string|null
The code through which the link was made. null if the link was made via referrer_user_id and the referrer already had their own code (it was used, but its value isn't returned)
already_attributed
bool
true — the user already had a referrer (this request changed nothing, returned what already existed). false — the link was created by this call
Possible errors
400
referral_user_id not provided, or both code and referrer_user_id were provided at the same time, or neither was provided
Provide referral_user_id and exactly one of code/referrer_user_id
400
A user is attempting to become a referral of themselves
Check that referral_user_id and the referrer are different users
404
The specified code was not found
Check the code, or use referrer_user_id instead
401
API key not provided or invalid
Check the API key
500
Internal server error
Retry the request later
10. List of accruals
GET /v1/referral/accruals
Returns the income side of the user's balance history — a list of individual reward accruals (one row per referred user and event). Withdrawals (payouts) are returned by GET /v1/referral/payouts — together, these two methods provide the full feed of balance movements.
Reversed and cancelled accruals (see reverse-accrual) do not appear in this list — this is a ledger of the "live" balance, not a complete audit trail.
Parameters
user_id
int
yes
—
Telegram ID of the referrer
limit
int
no
50
How many records to return at once (1 to 200)
offset
int
no
0
How many records to skip from the start of the list
Example call
Response
accruals
array
List of accruals, newest to oldest
accruals[].id
int
Identifier of the accrual (used as accrual_id in reverse-accrual)
accruals[].date
string
Date and time the accrual was created (UTC)
accruals[].referral_id
int
Telegram ID of the referred user whose action triggered the reward
accruals[].amount
number
Accrual amount (can be negative — a compensating record after a reversal)
accruals[].unit_id
int|null
Currency/unit of the reward
accruals[].status
int
0 — on hold, 1 — confirmed (available for withdrawal), 2 — paid out
accruals[].available_at
string|null
When the accrual will become available for withdrawal (holding period). null if no holding period applies or it has already passed
Possible errors
400
user_id not provided, or is not a number
Provide a valid Telegram ID
401
API key not provided or invalid
Check the API key
500
Internal server error
Retry the request later
11. Current reward rate
GET /v1/referral/rates
Shows the terms under which a user receives a reward for referrals — for each active program rule separately (if the bot has several rules, e.g. for payments and for subscriptions). Useful for showing the user "you receive 10% of every payment" in your interface.
If the user has already had at least one accrual under a rule, their locked-in rate is returned (locked: true), even if the program's general rate has changed since then. If there have been no accruals yet, the rule's current rate is returned (locked: false); it will be locked in for the user automatically upon the first applicable accrual.
Parameters
user_id
int
yes
Telegram ID of the referrer
Example call
Response
rates
array
One row per active program rule for the bot
rates[].rule_id
int
Identifier of the rule
rates[].rule_name
string|null
Name of the rule (as set in the admin panel)
rates[].trigger_event_id
int
Type of event for which the reward is granted under this rule
rates[].reward_type
string
fixed — a fixed amount, percent — a percentage of the event amount, external — the reward is issued on your side
rates[].reward_amount
number|null
Reward amount for fixed
rates[].reward_percent
number|null
Reward percentage for percent
rates[].unit_id
int|null
Currency/unit of the reward
rates[].locked
bool
true — the rate is locked in specifically for this user (won't change if the program's overall rate is edited); false — the program's current general rate applies
rates[].source
string|null
auto — locked in automatically on the first accrual; manual — set individually by an administrator; null if locked is false
Possible errors
400
user_id not provided, or is not a number
Provide a valid Telegram ID
401
API key not provided or invalid
Check the API key
500
Internal server error
Retry the request later
Common error format
If a request fails, the response will always contain "ok": false:
ok
Always false on error
error
Text description of the error reason
error_code
HTTP error code (matches the HTTP response status code)
Last updated