v2

latestOpenAPI 3.1.0Proprietary2026-07-3191563.2 KB
Recipients

Check a recipient

Resolve a @username and check whether they can receive the requested item, before you create an order. Read-only and fail-open — a transient oracle hiccup resolves to eligible: true rather than blocking you.

Why type is required. The check runs against the very product you intend to order, so it must know which one. Pass type: stars to resolve a Stars recipient, or type: premium to resolve a Premium-gift recipient (the Premium path also takes months — 3, 6 or 12). Always check with the same type you'll use in POST /v1/orders: a Stars check does not prove a Premium gift will be accepted, and vice-versa.

⚠️ A recipient who already has an active Premium subscription cannot be gifted Premium. Telegram blocks gifting a Premium subscription to anyone whose subscription is still active (for example, an annual plan that has not expired yet) — this is Telegram's restriction, not ours. The check surfaces it as eligible: false with reason: "already_subscribed" and Telegram's verbatim wording in telegram_message. The same recipient also makes POST /v1/orders fail with 422 recipient_ineligible: no order is created and you are not charged. Pre-flighting Premium recipients here is the cheapest way to tell your user before they pay.

Rate limit: this endpoint carries a tighter per-tenant cap of 60 requests/min (in addition to the standard per-tenant budget), because each call performs a live upstream lookup. If you exceed this, you receive a 429 and should back off for the remainder of the minute.

post/v1/recipients/check

Request body

type'stars' | 'premium' required
months3 | 6 | 12

Only meaningful for type=premium (defaults to 3). Must be 3, 6, or 12.

Example request

{
  "recipient": {
    "username": "durov"
  }
}

Response

Resolution + eligibility result.

resolvedboolean required

Whether the @username was found on Telegram.

eligibleboolean required

Whether the recipient can receive the item.

recipient_namestring nullable

The resolved recipient's display name from Fragment, when available (best-effort) — useful to confirm you're sending to the right person. null if Fragment returned no name.

reason'already_subscribed' | 'not_found' | 'ineligible' | 'null' nullable

Permanent-rejection class, set only when eligible is false: already_subscribed, not_found, or ineligible. null when eligible.

telegram_messagestring nullable

Fragment's raw rejection text, propagated verbatim — set only when eligible is false. null when eligible.

indeterminateboolean

true when the eligibility probe could not reach a verdict and this endpoint FAILED OPEN — eligible is then a permissive default, not a measurement. false on every real verdict (eligible or not).

Treat an indeterminate response as "unknown", never as "yes": the recipient has not been checked. It is safe to proceed to POST /v1/orders (which runs its own authoritative check), but do not present it to a buyer as a confirmed-deliverable recipient.

Always present since 1.11.0. Clients written against an earlier version saw the field absent; absent and false mean the same thing.