TeleScan API
Check phone numbers against Telegram programmatically β drop it into your own website, panel, or automation in minutes.
https://api.gramlab.click
Quickstart
Every request needs your API key. Get one from the bot, then check your first batch of numbers:
# Replace tsk_live_<your_key> with your real key
curl -X POST https://api.gramlab.click/v1/check \
-H "Authorization: Bearer tsk_live_<your_key>" \
-H "Content-Type: application/json" \
-d '{ "numbers": ["+15551234567", "+447911123456"] }'
const res = await fetch('https://api.gramlab.click/v1/check', {
method: 'POST',
headers: {
'Authorization': 'Bearer tsk_live_<your_key>',
'Content-Type': 'application/json',
},
body: JSON.stringify({ numbers: ['+15551234567', '+447911123456'] }),
});
const data = await res.json();
console.log(data.results);
import requests
resp = requests.post(
"https://api.gramlab.click/v1/check",
headers={"Authorization": "Bearer tsk_live_<your_key>"},
json={"numbers": ["+15551234567", "+447911123456"]},
)
print(resp.json()["results"])
Authentication
Send your API key as a Bearer token on every request:
Authorization: Bearer tsk_live_<your_key>
Check numbers
/v1/check
Checks up to 100 phone numbers per request. Visible accounts are checked first. Unresolved numbers may receive a Telegram login code during ban checking. Submit only numbers you own or have permission to check. No OTP submission is required or accepted.
Request
curl -X POST https://api.gramlab.click/v1/check \
-H "Authorization: Bearer tsk_live_<your_key>" \
-H "Content-Type: application/json" \
-d '{
"numbers": ["+15551234567", "+447911123456"]
}'
Response
{
"results": [
{ "number": "+15551234567", "status": "unknown" },
{ "number": "+447911123456", "status": "registered" }
]
}
Ban checks share a one-hour per-number cache/cooldown across the bot and API. Cached results include cached: true; completed probes include checkedAt. Each ban-check batch has a 30-second time budget and a short shared busy window. Use a client timeout of at least 60 seconds. Results outside the budget remain Unknown.
reason: phone_number_banned confirms a ban. code_requested means Telegram accepted the code request, not that the number is Fresh. Other Unknown reasons: retry_exhausted, otp_cooldown, auth_rate_limited, auth_timeout, auth_unavailable, auth_response_unverified, invalid_number, ban_check_busy, ban_check_budget, ban_check_unavailable. No Fresh result is emitted without verified evidence.
Status values
| Status | Meaning |
|---|---|
unknown | Fresh/banned status could not be confirmed. See reason values above. |
deleted | Telegram marks the returned account deleted; this does not prove a phone-number ban. |
restricted | Telegram marks the returned account restricted; this does not prove a spam/flood lock. |
green | Legacy status; not emitted by contact lookup (fresh cannot be verified) |
banned | Telegram explicitly returned PHONE_NUMBER_BANNED during login-code request |
locked | Legacy status; contact lookup cannot verify spam/flood locks |
registered | Unfresh: Telegram returned a matching account; usability is not verified |
Usage
/v1/usage
Returns your current key status.
Request
curl https://api.gramlab.click/v1/usage \
-H "Authorization: Bearer tsk_live_<your_key>"
Response
{
"keyPrefix": "tsk_live_ab12cd34",
"active": true,
"expiresAt": "2026-09-05T18:55:26.161Z",
"lastUsedAt": "2026-08-05T19:02:11.000Z"
}
Errors
Errors are always JSON: { "error": { "code", "message" } }
| HTTP | Code | Meaning |
|---|---|---|
| 400 | INVALID_BODY / INVALID_NUMBERS / TOO_MANY_NUMBERS | Malformed request |
| 401 | MISSING_KEY / INVALID_KEY | Auth header missing or key invalid |
| 402 | ACCESS_EXPIRED | API access subscription has expired |
| 429 | RATE_LIMITED | More than 60 requests/minute on this key |
| 503 | RATE_LIMITED_UPSTREAM / SERVICE_UNAVAILABLE | Checking temporarily unavailable β retry shortly |
Rate limits
Up to 60 requests per minute per key. This protects shared checking capacity β it isn't a usage cap on your monthly plan, which is genuinely unlimited.