Bodhan.AI APIs

API Reference

All four models sit behind https://api.bodhan.ai. The /v1 routes take OpenAI-style requests, so an existing SDK only needs a new base_url.

Authentication

Send your key as a bearer token on every request. Keys live in the dashboard; if you do not have an account yet, create one.

Speech to Text API

POSThttps://api.bodhan.ai/v1/audio/transcriptionsmultipart/form-data

Turns speech into text in 25 Indian languages and English. The transcript comes back in the language that was spoken.

  • Send the audio as multipart/form-data. WAV is the documented format; FLAC, OGG and MP3 are also accepted.
  • Each request takes up to 30 seconds of audio; longer audio is rejected.
  • Billing is per second of audio, so trim silence before you send it.

Authentication

  • Authorization: Bearer <YOUR_BODHAN_KEY> header (required)

Request

Body (multipart/form-data)

  • file (file, required) — The audio to transcribe.

  • model (string, required) — indic-transcribe.

  • language (enum, optional) — Language of the audio. Omit it and the vendor auto-detects, but naming it is the difference between a correct transcription and a garbled one for non-English audio, so pass it whenever you know it.

    Available options:

    Code Language Code Language
    as Assamese mai Maithili
    bhb Bhili ml Malayalam
    bho Bhojpuri mni Manipuri
    bn Bengali mr Marathi
    brx Bodo ne Nepali
    doi Dogri or Odia
    en English (Indian and global) pa Punjabi
    gu Gujarati sa Sanskrit
    hi Hindi sat Santali
    kn Kannada sd Sindhi
    kok Konkani ta Tamil
    ks Kashmiri te Telugu
    ur Urdu

Response

200

  • text (string, required) — The transcript.

415

The audio's duration could not be measured, so the request cannot be metered and was not transcribed. Send WAV, the documented format; FLAC, OGG and MP3 are also accepted. Containers such as M4A, AAC, WebM and AMR are refused with this status.

Translation API

POSThttps://api.bodhan.ai/v1/chat/completionsapplication/json

Translates text between English and 22 Indian languages, in native or Roman script. You send the text and the two language codes; the gateway writes the prompt.

  • One user message, whose content is the text itself. Do not put an instruction in it.
  • Decoding is fixed on the server. temperature, max_tokens, stream and the other generation settings are rejected with 422 rather than ignored.

Authentication

  • Authorization: Bearer <YOUR_BODHAN_KEY> header (required)

Request

Body (application/json)

  • model (string, required) — indic-translate.

  • messages (array, required) — Exactly one message, "role": "user", with the text to translate as its content. No system message.

  • source_language_code (enum, required) — Language of the text.

  • target_language_code (enum, required) — Language to translate into. Any pair works, Indic to Indic included. Available options for both:

    Code Language Code Language Code Language
    as Assamese kn Kannada or Odia
    bn Bengali kok Konkani pa Punjabi
    brx Bodo ks Kashmiri sa Sanskrit
    doi Dogri mai Maithili sat Santali
    en English ml Malayalam sd Sindhi
    gu Gujarati mni Manipuri ta Tamil
    hi Hindi mr Marathi te Telugu
    ne Nepali ur Urdu
  • target_script (enum, optional) — native (default) or roman. Roman is the target language written in Latin letters, not a translation into English, so it is rejected when target_language_code is en.

Response

200

A standard chat completion.

  • choices[0].message.content (string) — The translation.
  • choices[0].finish_reason (string) — stop when the translation is complete. length means it was cut off; the text reads fluently and simply stops, so check this field. Split the text and send the parts.
  • usage (object) — Token counts. Only output tokens are billed.

422

A generation setting was sent; the message shape is off (a system message, more than one message, array content, empty text); a language code is not in the table; or target_script is roman with target_language_code en.

Text to Speech API

POSThttps://api.bodhan.ai/v1/audio/speechapplication/json

Reads text aloud in 22 Indian languages and English, in 45 voices. The response is a WAV file.

  • The language, and optionally a speaking style, go in instructions as a JSON string. Any voice can read any language.
  • Keep each request to a sentence or two, about 30 seconds of speech. Longer text is not split for you.
  • The response is audio/wav, PCM16 at 24 kHz, mono.

Authentication

  • Authorization: Bearer <YOUR_BODHAN_KEY> header (required)

Request

Body (application/json)

  • model (string, required) — indic-speak.

  • input (string, required) — The text to read. Numbers, dates and currency are read out in the language given.

  • voice (enum, required) — The speaker, by name. The 45 voices are grouped below by the language each was recorded in, but any voice can read any of the languages. Available options:

    Code Language Female Male
    as Assamese Prastuti Ankur
    bn Bengali Ishita Sourav
    brx Bodo Gwrbw Sansuma
    doi Dogri Preeti Sham
    gu Gujarati Dhara Parth
    hi Hindi Kavya, Suhani Amit
    kn Kannada Deepika Adarsh
    kok Konkani Anjali Sandeep
    ks Kashmiri Zoon Ishfaq
    mai Maithili Vaidehi Madhukar
    ml Malayalam Lakshmi Kiran
    mni Manipuri Thoibi Chaoba
    mr Marathi Anagha Chinmay
    ne Nepali Srijana Sagar
    or Odia Itishree Akash
    pa Punjabi Kaur Manpreet
    sa Sanskrit Bharati Aryaman
    sat Santali Phulmani Sibu
    sd Sindhi Moomal Rano
    ta Tamil Anitha Arun
    te Telugu Sravani Vamsi
    ur Urdu Saba Zaid
  • instructions (string, required) — A JSON string with lang and, if you want one, style: "{\"lang\": \"hi\", \"style\": \"news\"}".

    • lang (required) — Language of the text. Available options:

      Code Language Code Language
      as Assamese mni Manipuri
      bn Bengali mr Marathi
      brx Bodo ne Nepali
      doi Dogri or Odia
      en English pa Punjabi
      gu Gujarati sa Sanskrit
      hi Hindi sat Santali
      kn Kannada sd Sindhi
      kok Konkani ta Tamil
      ks Kashmiri te Telugu
      mai Maithili ur Urdu
      ml Malayalam
    • style (optional) — Delivery. Leave it out for the voice's neutral reading. Available options: AIR style news, Customer Care, TV style news, advertisements, anger, children's stories, disgust, educational lecture, fear, happy, news, sad, single person narration audiobook, surprise.

Response

200

  • The WAV audio itself, with Content-Type: audio/wav. PCM16, 24 kHz, mono.

422

input was empty, voice, lang or style was not one of the values above, or instructions had no lang. The message names the unknown value and lists what is accepted.

Document OCR API

POSThttps://api.bodhan.ai/v1/chat/completionsapplication/json

Extracts text and layout from a document image using Indic-OCR, served as the model indic-ocr. The page is returned as reading-ordered Markdown, alongside the layout blocks it was assembled from. Output is in the script of the input document.

The API follows the OpenAI chat completions format, and the transcribed page arrives in choices[0].message.content. Layout information is returned in an additional top-level blocks field.

Note:

  • Send a whole document page image. The model detects layout and crops blocks itself; pre-cropping is unnecessary.
  • We support PNG and JPEG only. PDFs are not supported.
  • The image is sent inline as a base64 data URI, in a single user message. We support one image per request; there is no page or batch parameter.
  • The request carries no prompt customization support.
  • There is no language field. The script is inferred from the image itself.
  • A single call returns both layout detection and transcription.

Authentication

  • Authorization: Bearer <YOUR_BODHAN_KEY> header (required)

Request

Body (application/json)

  • model (string, required): Must be "indic-ocr".
  • messages (array, required): Exactly one user message whose content is an array holding a single image_url part. The image is a data URI: "data:image/png;base64,<base64-encoded bytes>".
  • table_format (enum, optional): How tables are rendered. "html" (default) preserves table structure, including merged cells; "markdown" emits a GitHub-style pipe table. See Tables below.
  • max_tokens (integer, optional): Transcription limit per block, not per page. Defaults to 2048. Raise it for pages containing large tables; see Truncation below.

Response

200

Successful Response

A standard chat.completion object with one additional top-level field, blocks.

  • id (string): Request identifier.
  • created (integer): Unix timestamp.
  • model (string): "indic-ocr".
  • object (string): "chat.completion".
  • choices (array): Exactly one choice.
    • finish_reason (string): "stop".
    • index (integer): 0.
    • message.role (string): "assistant".
    • message.content (string): The full page as reading-ordered Markdown.
  • usage (object): prompt_tokens, completion_tokens and total_tokens, summed across every block on the page.
  • blocks (array): The detected layout blocks, in reading order.

blocks is present at top-level, not inside choices.

Block object

  • order (integer): Reading-order index, from 0.
  • label (string): The block's layout role, e.g. Paragraph, Section-title. See Layout labels below.
  • type (string): A coarser grouping of label, e.g. Text, Title, SectionHeader, Caption, Table, Picture.
  • bbox_xyxy (array of 4 numbers): Bounding box as [x_min, y_min, x_max, y_max], in pixels of the image you uploaded, origin at the top-left.
  • conf (number): Layout detection confidence, 0.0 to 1.0. This scores block detection, not transcription accuracy.
  • text (string): The block's transcribed text, or "" for blocks that carry none.

Layout labels

label is drawn from a fixed 37-class taxonomy:

Advertisement Equation Infobox Sub-section-title
Answer Expression List Sub-sub-section-title
Author Flag MCQ Table
Chapter-end-section Folio Page-number Table-caption
Chapter-title Footer Paragraph Table-of-contents
Chart Footnote Placeholder-text Title
Code Header Question Website-link
Contact-info Image Reference
Dateline Image-caption Section-title
Diagram Index Solved-example

Some blocks are detected but not transcribed. They are returned with text: "" and keep their place in reading order, so bounding boxes stay available even where there is no text:

  • Pictorial regions, such as Image, Chart, Diagram and figures.
  • Page furniture, such as Header, Footer and Advertisement.

Markdown output

message.content is the blocks' text joined in reading order, separated by blank lines:

  • Headings are not marked up. A Section-title appears as a plain paragraph, not as ##. Document structure is available from blocks[].label, not from the Markdown.
  • Mathematics is LaTeX, using $...$ inline and $$...$$ for display equations. Indic script inside a formula is wrapped in \text{...}.
  • Words split across a line break are rejoined, so exam-\nple is emitted as example.
  • Tables appear as HTML or Markdown according to table_format.
  • Pictorial blocks will not be shown in the Markdown, though they remain in blocks.

Tables

table_format trades structural fidelity against size:

html (default) markdown
Merged cells preserved via rowspan / colspan flattened into separate columns
In-cell line breaks <br/> removed

Use the default html when a table has merged or multi-level headers, and markdown when the table is simple and you want output that reads well as plain text.

Because HTML is substantially larger, a long table is the most common reason to exceed max_tokens. A 50-row dense table may need max_tokens of 4096 as HTML, but fits the 2048 default as Markdown.

Truncation

max_tokens applies per block, so the default of 2048 is ample for ordinary prose.

Large tables are the realistic exception. If any block exceeds the limit, the request fails with 502 and the page is not returned.

In that case, please raise max_tokens and retry. For documents known to contain large tables, raise it up front rather than after a failure.

Errors

401

Missing, invalid, or expired API key.

{
  "error": {
    "message": "Authentication Error, No api key passed in.",
    "type": "auth_error",
    "code": "401"
  }
}

502

The page could not be transcribed. Either a block exceeded max_tokens (see Truncation), or the image could not be decoded. The detail field distinguishes the two.