---
title: "Check a recipient"
method: POST
path: "/v1/recipients/check"
tags: ["Recipients"]
---

# Check a recipient

`POST /v1/recipients/check`

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.

## Request body

- RecipientCheckRequest
  - `type` 'stars' | 'premium', required
  - `recipient` Recipient, required
    - `username` string, required — Telegram @username (the leading `@` is optional, case-insensitive). After canonicalisation (strip `@`, lowercase) must match `[a-z0-9_]{1,32}` — invalid or oversized handles return 400.
  - `months` 3 | 6 | 12 — Only meaningful for `type=premium` (defaults to 3). Must be 3, 6, or 12.

## Response `200`

Resolution + eligibility result.

- RecipientCheckResult
  - `resolved` boolean, required — Whether the @username was found on Telegram.
  - `eligible` boolean, required — Whether the recipient can receive the item.
  - `recipient_name` string, 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_message` string, nullable — Fragment's raw rejection text, propagated verbatim — set only when `eligible` is false. `null` when eligible.
  - `indeterminate` boolean — `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.

## Other responses

- `400` — Malformed request.
- `401` — Missing or invalid `X-Api-Key`.
- `429` — A rate limit was reached — the per-minute request budget, the tighter pricing/recipient-check probe cap (60 req/min), the daily order cap, or the per-recipient flood guard. See **Rate limits** in the overview. The per-minute-budget responses also carry `RateLimit-*` + `Retry-After` headers.

---

[API](https://skmtc.net/mystars/apis/mystars-faas-fulfilment-api.md) · [All operations](https://skmtc.net/mystars/apis/mystars-faas-fulfilment-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/mystars/mystars-faas-fulfilment-api/revisions/3c24cb3dfa12/schema)
