Developer integration

Developer API: the complete access-code application flow

GetTGAPI public API v1: use an access code as your key for balance, number verification, progress, result retrieval and deletion, with errors and idempotent retries.

GetTGAPI editorial teamUpdated

API and quick start

Base URL: https://gettgapi.com/api/open/v1. Call from your server using the remaining uses on an access code. Customers do not need a platform account, Telegram client API credentials, a two-step password or device authorization. Each application still requires the number holder's developer portal verification code.

Download OpenAPI 3.1 · Download the complete Python example · Integration support

  1. Call GET /balance with the access code.
  2. Submit number, app details and consent to POST /applications. Save the returned application id.
  3. Poll at intervals of at least 5 seconds. For waiting_code with a non-null challenge, ask the number holder for this request's code.
  4. Submit it to POST /applications/{id}/code and continue polling.
  5. On succeeded, read GET /applications/{id}/result.
  6. Save securely in your system, verify the save, then call deletion. Deleted results cannot be reissued.

Existing apps are retrieved; creation is attempted only if none exists. Success is not guaranteed for every number. Restrictions and exceptions may require manual review.

Authorization and format

Every business request requires:

Authorization: Bearer YOUR_AUTHORIZATION_CODE
Accept: application/json

Writes also require:

Content-Type: application/json
Idempotency-Key: 2e8718cd-84ef-4830-b273-66b3afdd682d

Original hyphens in access codes are accepted; letters are case-insensitive. Never put codes in URLs, browser frontends, logs or public repositories. This API does not use website cookies or CSRF tokens and does not enable cross-origin CORS. A leaked code exposes its service permissions: contact the issuer to disable it.

Use HTTPS only. Maximum body size is 8 KiB. Unknown fields, wrong types and invalid formats are rejected. Times are Unix seconds; null means unavailable, not zero.

Success responses use this envelope:

{"data": {"available": 1}, "request_id": "server-generated-trace-id"}

This is illustrative; see each endpoint and OpenAPI for complete fields. X-Request-ID matches request_id. Responses must not be cached. Use the trace ID for support, not as your next write's idempotency key. Example message wording below is translated for readability; integrations must branch on machine-readable codes and statuses.

Access-code balance

GET /balance returns HTTP 200:

{
  "data": {
    "total": 10,
    "available": 8,
    "reserved": 1,
    "consumed": 1,
    "revoked": 0,
    "max_concurrent": 2,
    "result_retention_seconds": 1800
  },
  "request_id": "example-trace-id"
}

total = available + reserved + consumed + revoked. Reserved uses are in progress, consumed uses completed successfully, and revoked uses were withdrawn. A code can have at most two reserved applications at once. Website and API share this limit and balance.

Balance queries do not consume uses or redeem a code. An exhausted code can still read its API-created applications and delete temporary results. Disabled or suspended codes cannot access them; contact the issuer.

Create an application

POST /applications returns HTTP 202 on initial acceptance and successful idempotent replay.

{
  "phone": "+12025550123",
  "title": "My Telegram App",
  "short_name": "myapp2026",
  "consent": true
}
Field Requirement
phone Required, including country code. Digits with optional leading +; spaces are removed and a missing + is added. Other characters are rejected.
title Optional; defaults to My Telegram App. 3–60 characters: letters, numbers, underscore, spaces, dots and hyphens.
short_name Required; 5–32 characters. Starts with an English letter, followed by English letters, digits or underscore.
consent Required boolean true confirming authority to use the number; the string "true" is invalid.

HTTP 202 means accepted, not that a code arrived or an application succeeded. The response is the application object below. Initial acceptance reserves one use; success consumes it. Confirmed failure, cancellation before creation or a duplicate result releases it. Unknown results retain the reservation while checked.

Unfinished or successful records for the same code and number are not recreated. Matching API-origin details return the original application. Different details or a website-origin record return PHONE_ALREADY_USED. Deleted results still retain usage records; changing idempotency keys does not restore them or create another charge.

Application status

GET /applications/{id} returns HTTP 200 with:

{
  "data": {
    "id": "28f4a4d0-e69f-48d4-b520-85c479873b1f",
    "phone_mask": "+120••••123",
    "title": "My Telegram App",
    "short_name": "myapp2026",
    "status": "waiting_code",
    "message": "Check Telegram for the verification code and enter it below.",
    "challenge": {"id": "c8a34997-38bd-4a1c-90bb-5baac7dbabcc", "expires_at": 1790998200, "attempts_remaining": 5},
    "poll_after_seconds": 5,
    "retry_at": null,
    "result_expires_at": null,
    "quota": "reserved",
    "created_at": 1790997600,
    "updated_at": 1790997605
  },
  "request_id": "example-trace-id"
}
Status Client action
queued Continue polling.
processing Processing or reconciling; poll without creating again.
waiting_code Submit a code if challenge exists. If null, verification expired; cancel, then apply again if needed.
verifying Code submitted; poll without requesting another send.
retry_wait System wait or automatic retry. Consider retry_at and keep polling; no client resend is needed.
review_required Stop automatic polling. Contact support with application id and request_id.
succeeded Retrieve and securely save the result promptly.
failed Failure confirmed; reservation released. Use a new idempotency key if a new application is needed.
cancelled Cancelled; reservation released.
duplicate This code already has the same app result. No use consumed for this attempt; use your saved result.
deleted Temporary result cleared and unavailable.

quota is reserved, consumed or released. challenge exists only when code entry is currently allowed. Its id may change after failed input or renewed verification; query again. retry_at is a suggested wait-until time, not a completion guarantee. poll_after_seconds=0 means continuous polling is unnecessary.

GET /applications?limit=20&before={id} lists records. Limit is 1–50, default 20; before is optional. Results are ordered by creation time and id descending. The response has data.items and data.next_before; null means the end. Only this access code's API-created records are visible, excluding website results and other codes.

Submit a verification code

POST /applications/{id}/code returns HTTP 202 with the updated application.

{"challenge_id": "c8a34997-38bd-4a1c-90bb-5baac7dbabcc", "code": "Ab_cd-12"}

Code is 3–64 printable ASCII characters, without spaces, case-sensitive. Submit only the current developer portal code received by the number holder, not a two-step password or an old challenge's code. Each round allows at most 5 entries. Expiry is challenge.expires_at.

Acceptance only means queued for verification. Retry the same HTTP submission with its original key and identical parameters. If the code was wrong, query the new challenge and submit the correct code with a new key.

Cancel

POST /applications/{id}/cancel with {"confirm": true} returns HTTP 200 and the application.

Only cancellable states, such as queued, waiting for code or waiting to retry, permit this. Running applications and uncertain results return STATE_CONFLICT; keep polling or contact support. Repeating cancellation of cancelled or confirmed-failed applications does not return additional uses.

Retrieve and delete the result

GET /applications/{id}/result returns HTTP 200:

{
  "data": {"api_id": 12345678, "api_hash": "0123456789abcdef0123456789abcdef", "expires_at": 1790999400},
  "request_id": "example-trace-id"
}

These are sample values, not usable credentials. The default delivery window is 30 minutes; the actual expires_at governs. Reads neither extend retention nor consume uses, and multiple reads are allowed. Never put Hash in access logs, analytics, URLs or support chat.

After saving and verifying the result, call POST /applications/{id}/result/deletion with {"confirm": true}. HTTP 200:

{
  "data": {"application_id": "28f4a4d0-e69f-48d4-b520-85c479873b1f", "deleted_at": 1790998000, "status": "deleted"},
  "request_id": "example-trace-id"
}

Deletion clears our temporary API delivery copy while retaining counts and necessary operation records. It does not delete the Telegram app or your system's saved copy. After deletion, expiry or loss of temporary delivery storage, reads return HTTP 410. Deletion requests can be retried safely. Save first, delete second.

Idempotency, limits and retries

Every POST requires Idempotency-Key: 16–80 letters, digits, dots, underscores, colons or hyphens; UUIDs are recommended. Persist it before sending. Generate a new key per distinct operation. Reuse the original key when retrying after network timeout, disconnect or 5xx.

Within an access code, a key is globally bound to the operation and parameters and cannot be reused across endpoints. Replay returns the original application's current state, not necessarily an identical byte response. It does not resend codes, reserve or charge again. A deleted result does not make that key create a new application. Do not change keys merely because a response is unknown.

Limit Current value
All requests per access code 120 / minute
Writes per code 30 / 10 minutes, including idempotent retries
New creation requests per code 10 / 10 minutes
Business requests per IP 180 / minute, plus burst protection
Invalid keys per IP 15 / 10 minutes
Applications per number 5 / hour, shared with the website
Concurrent reservations per code 2, shared with the website
Code submissions 5 per round, plus 10 / 10 minutes per task

For 429 and 503, honor Retry-After; use exponential backoff with modest jitter. 5xx and network/read timeouts can occur after a write completed. Reuse its key rather than assuming no use was deducted. Usually correct input or check status for 4xx; never retry indefinitely.

Overload or inability to accept new work returns 503. Unaccepted requests do not reserve uses. Durable tasks resume after service failures, and uncertain submitted creations are checked rather than blindly repeated. A single-host deployment still has host and datacenter failure boundaries; no multi-host disaster-recovery SLA is promised.

Errors

{
  "error": {"code": "RATE_LIMITED", "message": "Too many requests. Wait before retrying.", "retryable": true, "retry_after_seconds": 60},
  "request_id": "provide-this-trace-id-to-support"
}

Use code and HTTP status, not parsed message wording or internal implementation details. Upstream errors are not returned verbatim. Retryable errors also include Retry-After. Trace IDs contain neither access codes nor results.

HTTP code Action
401 INVALID_KEY Check Authorization and the access code.
403 KEY_DISABLED Ask the issuer about disabled or suspended status.
403 ORIGIN_DENIED / HOST_DENIED Call the documented base URL from your server.
400 HTTPS_REQUIRED / IDEMPOTENCY_REQUIRED Use HTTPS and a valid idempotency key.
422 INVALID_INPUT / PHONE_INVALID / CONSENT_REQUIRED Correct fields and formats.
409 IDEMPOTENCY_CONFLICT Recover original parameters, or use a new key for a genuinely new operation.
409 QUOTA_EXHAUSTED / CONCURRENCY_LIMIT Query balance or wait for current work.
409 PHONE_ALREADY_USED Handle the original application instead of recreating it.
404 APPLICATION_NOT_FOUND Check id, access code and application channel.
409 CHALLENGE_EXPIRED / TOO_MANY_ATTEMPTS Query the application and current challenge.
409 STATE_CONFLICT Query progress or contact support.
409 RESULT_NOT_READY Continue polling progress.
410 RESULT_GONE Use your own saved copy.
429 RATE_LIMITED Wait for Retry-After.
503 SERVICE_BUSY / SERVICE_UNAVAILABLE Back off and retry with the original key.
408 REQUEST_TIMEOUT Retry the original request, retaining its key for writes.
413 BODY_TOO_LARGE Reduce the body to 8 KiB or less.
415 UNSUPPORTED_MEDIA_TYPE Send uncompressed application/json.
404 / 405 NOT_FOUND / METHOD_NOT_ALLOWED Check path and method.

Example client and secure storage

The Python example requires Python 3.10+ and requests. It stores request state in a restricted local directory, resumes uncertain requests with the same key, and asks about deletion only after safely saving the result. Do not commit its working directory.

python3 -m pip install requests
python3 gettgapi_client.py --work-dir ./private-application

Access codes and verification codes use hidden terminal input and are not logged. The client asks for a number and short_name. Reusing the directory resumes that operation; use a new directory for another number. Test with a number you control. HTTP acceptance and automated tests cannot replace real-number verification.

Encrypt results in your system, restrict staff read access and never expose access codes in a public client. Issue independent codes to different customers: a holder can manage all API-created applications belonging to that code.

For integration help, use gettgapi.com/en/help#contact with request_id and application id, without verification codes, full access codes or API Hash.