Telegram has released an OpenAPI description for its Bot API: a single api.json file lists all methods, objects, responses, and errors, as well as requests that Telegram itself sends to a bot's webhook. This is relevant for bot developers and library authors. Clients in any language can now be generated from the official file, rather than from parsed HTML documentation pages. The file is hosted on corefork.telegram.org, which features an updated version of the documentation, and describes the current Bot API version 10.3.
What This File Is
OpenAPI (formerly known as Swagger) is a standard format that describes an HTTP interface as data: addresses, parameters, field types, and response codes. Code generators use such descriptions to build client libraries, validators check requests, and editors render interactive documentation.
The file size is 1.83 MB, and its header contains "openapi": "3.2.0" and "version": "10.3". Revision 3.2.0 is the latest for the standard, published on 19 September 2025. Among its new features, the schema uses the $self field with its own address, named servers, and a separate mediaTypes section for recurring response bodies.
What's inside, counted directly from the file:
| Section | Count |
|---|---|
| Bot API Methods (POST) | 185 |
| File Downloads (GET on file server) | 1 |
| Total Object Schemas | 625 |
| of which method parameter sets | 177 |
Union types (oneOf/anyOf) | 31 |
| of which with discriminator | 22 |
| int64 format fields | 217 |
Operation links (links) | 23 |
| Webhooks | 1 |
Eight out of 185 methods have no parameters, hence there are 177 parameter sets. File downloads are described as a separate downloadFile operation with its own server api.telegram.org/file/bot{token}: in the HTML documentation, this was a prose paragraph, not a method.
Does It Match the Documentation?
The set of methods matches completely. From the HTML page core.telegram.org/bots/api, 185 method names are extracted; from the schema, there are 185 operations, with no discrepancies between the lists.
Objects are more complex because there are currently two versions of the documentation. The main domain describes 400 objects. On corefork.telegram.org/bots/api, there are 429: 30 more input types (InputRichText and its variants, InputInlineKeyboardMarkup, InputLocation, and others) and one less — RichBlockThinking, which disappeared from the Bot API 10.3 changelog in the updated version. The schema matches the corefork version: all 429 of its objects are present in the file.
Another 19 schemas exist only in the file. These are auxiliary constructs not present as separate objects in the prose: eight error responses (BadRequest, Unauthorized, TooManyRequests, and others), union types ChatId, ReplyMarkup, FileInput, UploadInput, and seven input variants of existing objects like InputMessageEntity and InputChatPermissions. An input variant describes what the bot sends, not what it receives: fields that the server populates itself are absent from it.
How Union Types and Files Are Described
The most challenging aspect for those who previously parsed HTML is where a single field accepts multiple types. In the schema, these are described programmatically.
Union types with a discriminator. ChatMember is a oneOf of six variants, with the status field selecting the variant: creator leads to ChatMemberOwner, kicked to ChatMemberBanned. MessageOrigin, InputMedia, BotCommandScope, ReactionType, and 17 other types are structured similarly. A code generator uses such a description to build a true sum type, not an object with all fields present at once.
Files. InputFile is described as binary content with the type application/octet-stream. The photo field in sendPhoto does not directly reference it, but rather FileInput: this is either an uploaded file or a non-empty string — a file_id or a URL. For album attachments, there is UploadInput: a file or a string like attach://<name>. The body of sendPhoto is declared as multipart/form-data, and all fields beyond the method parameters are allowed if they are files. This describes the approach where a file for attach:// arrives as a separate part of the form. Nested fields like caption_entities within the form are marked as JSON.
Responses. Each method responds with an envelope {"ok": true, "result": …}, and the result type is specified separately for each method. Errors are categorized by codes: for sendPhoto, these are 400, 401, 403, 421, 429, and 500.
What else the schema describes beyond the documentation
The webhook is described as a separate receiveUpdate operation. Telegram sends an update and can sign the request with an X-Telegram-Bot-Api-Secret-Token header or basic authorization from the URL; both methods are declared as security schemes. In response to a webhook, the bot can immediately call a method, and in the schema, this is a union of all allowed methods with a method field. Methods whose names start with get, as well as setWebhook, deleteWebhook, close, and logOut, cannot be called this way.
23 links describe where the result of one operation is passed. The file_id of an animation from a message can be passed to sendAnimation, and the file_path from getFile can be split by a slash into two parts of the downloadFile address. For splitting, Telegram introduced its own x-split-parameters extension — the only non-standard field in the entire file.
What to Consider When Generating a Client
The updated corefork page features three sections not yet present on the main domain. All three concern discrepancies between the schema and server behavior.
64-bit identifiers are strings. Bot API returns custom emoji, gift, callback query, and inline query identifiers as strings, and you must also pass them as strings. In the schema, for example, CallbackQuery.id, Sticker.custom_emoji_id, and Gift.id have the type string. Numeric user and chat identifiers remain int64 integers, although according to the documentation, they have no more than 52 significant bits.
Text length limit is counted after markup parsing. The maxLength for message text is 4096, but the server counts characters without HTML or Markdown markup. The schema validator counts them based on the raw string. The server will accept text of 4100 characters with tags, but a strict validator will reject it, so for fields sent with parse_mode, you should disable length validation by the schema.
Errors are in a separate file. Next to the schema, errors.json has appeared: for each error, it lists the methods that can return it. The file contains version 10.3, MTProto layer 227, and 945 error descriptions: 901 with code 400, 31 with code 500, 12 with code 403, and one with 429. 343 MTProto errors are separately mapped. The documentation states that error texts can change at any time, so the list is suitable for reference but not for comparing strings in code.
Version 3.2 of the standard was released a year ago. It's best to check whether a specific generator supports mediaTypes in components and its other new features before migrating a working library to the schema.
Where the File Is Located and Since When
The schema is only served from corefork.telegram.org. The $self field within it points to core.telegram.org/bots/api.json, but on 13 October, this address, like errors.json on the main domain, leads to a "Page not found" error. The main HTML documentation does not yet mention the schema.
There is no publication date in the server response: it does not return a Last-Modified header, the file is cached for five minutes, and it is blocked from indexing by the X-Robots-Tag: noindex header. The first copy in the web archive is dated 9 October 2026, 10:16 UTC.
The schema header states that both the documentation and the schema are generated by a tool published with the Bot API server's source code. As of 13 October, the link points to a non-existent folder: the tdlib/telegram-bot-api repository does not contain a generator directory. The last commit there is dated 25 August, a day before which the server version was updated to 10.3.
What Was Used Before
The Bot API previously lacked an official machine-readable schema, and the community had to assemble one from the HTML page. The most well-known example is telegram-bot-api-spec: a script that daily parses the documentation and publishes JSON with methods, fields, and subtypes. Its current version for Bot API 10.3 has 185 methods and 400 objects. Similar parsers and generators can be found in tg-bot-api, and an archive of schemas for older versions is stored in telegram-bot-api-versions.
HTML parsing relies on prose: 'Optional' at the beginning of a field description, the word 'or' between types, and the order of tables. Changes to the documentation's layout can break such a parser without a single change to the API itself. The official file delegates this work to Telegram: discriminator fields of union types, field optionality, length limits, and error codes are now defined in the schema instead of being inferred from the text.




