> For clean Markdown of any page, append `.md` to the page URL. > For a complete documentation index, see https://docs.sarvam.ai/llms.txt. > For full documentation content in one file, see https://docs.sarvam.ai/llms-full.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.sarvam.ai/_mcp/server. # API reference — Sarvam Vision > The InvokeEndpoint request and response contract for a self-hosted Sarvam Vision endpoint on SageMaker: content types, custom-attribute options, limits, the JSON response envelope, and error codes. The contract for invoking a self-hosted **Sarvam Vision** endpoint. You send the raw document bytes as the request body and pass options as **custom attributes**. ## `InvokeEndpoint` | Field | Value | | ---------------- | ------------------------------------------------------------------------- | | **Operation** | `sagemaker-runtime:InvokeEndpoint` (sync) · `InvokeEndpointAsync` (async) | | **Request body** | the raw document bytes | | **Content-Type** | must match the bytes (magic-byte verified) — see below | | **Accept** | `application/json` (default) or `application/zip` (bundle) | ### Supported content types | Content-Type | File type | | ----------------------------------------------------- | ------------- | | `application/pdf` | PDF | | `image/png` | PNG image | | `image/jpeg` (or `image/jpg`) | JPEG image | | `application/zip` (or `application/x-zip-compressed`) | ZIP of images | An omitted type, `application/octet-stream`, or `text/plain` is treated as PDF and the bytes are sniffed. A `Content-Type` that doesn't match the bytes is rejected with `400 INVALID_INPUT`. > **Warning** > > **TIFF, WebP, BMP, and GIF are not supported** — they're rejected with `415 UNSUPPORTED_MEDIA_TYPE`. Convert to PNG, JPEG, or PDF first. ### Limits | Limit | Value | Error if exceeded | | ------------------------------ | ---------------- | ----------------------------------------------------- | | File size (container hard cap) | 200 MB | `413 PAYLOAD_TOO_LARGE` | | File size (sync endpoint) | \~6 MB (AWS cap) | AWS-side rejection before the container | | File size (async endpoint) | 50 MB | AWS-side / job failure | | Pages per sync request | 5 (recommended) | risk of the 60 s `InvokeEndpoint` timeout beyond this | | Pages per document (hard cap) | 500 | `413 PAYLOAD_TOO_LARGE` | ### Options — custom attributes Pass options in the `X-Amzn-SageMaker-Custom-Attributes` header (sync) or the `CustomAttributes` parameter (async), as `key=value,key=value` or a JSON object. | Attribute | Values | Default | Notes | | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------ | | `language` | `hi-IN`, `en-IN`, `bn-IN`, `gu-IN`, `kn-IN`, `ml-IN`, `mr-IN`, `or-IN`, `pa-IN`, `ta-IN`, `te-IN`, `ur-IN`, `as-IN`, `bodo-IN`, `doi-IN`, `ks-IN`, `kok-IN`, `mai-IN`, `mni-IN`, `ne-IN`, `sa-IN`, `sat-IN`, `sd-IN` | `hi-IN` | case-insensitive; anything else → `400 UNSUPPORTED_LANGUAGE` | | `output_format` | `md` \| `html` \| `json` | `md` | `json` adds structured `result.pages[]` | | `output` | `text` \| `zip` | `text` | response representation (see below) | | `filename` | e.g. `invoice.pdf` | derived from Content-Type | appears in logs and results | ## Response The default response is a **JSON envelope** (`Content-Type: application/json`): ```json { "schema_version": "1.0", "status": "completed", "job_id": "20260724_...", "result": { "format": "md", "text": "…merged document text…", "summary": { "total": 1, "succeeded": 1, "failed": 0 } }, "warnings": [] } ``` With `output_format=json`, `result.pages[]` is added — per page `page_num`, `width`, `height`, `unit`, `origin`, and `blocks[]` with `id`, `type` (layout tag), `reading_order`, `bbox`, `text`, `layout_confidence`, and `ocr_confidence`. Set `output=zip` (or send `Accept: application/zip`) to get a **zip bundle** instead: the merged document at the root (`{name}.md` / `.html`, always present) plus `metadata/page_NNN.json` per page. > **Note** > > The response header `X-Amzn-SageMaker-Custom-Attributes` echoes `job_id`, `schema_version`, and `api_version`. **Log the `job_id`** — support can trace any request with it. > **Warning** > > The sync endpoint is for **small documents (up to 5 pages) at low concurrency**. It must finish inside AWS's **60-second** timeout, so keep sync requests to **5 pages or fewer** and, on the recommended single-GPU instance (`ml.g6e.xlarge`), only **1–2 documents in flight** or requests will time out. For anything larger than 5 pages, higher concurrency, or bulk work, use an **async** endpoint or **batch transform** — see [Deploy Sarvam Vision](/api/self-hosted/sagemaker/deploy-vision#prefer-async-for-documents). ## Errors Every non-2xx is delivered as **HTTP 424** through `InvokeEndpoint` — branch on `OriginalStatusCode` plus `error.code` / `error.detail_code`, never on the HTTP status. See [Error handling on SageMaker](/api/self-hosted/sagemaker/errors) for the collapse rule and the shared envelope. Errors always come back as the same JSON envelope — never HTML, never a bare string. The **error** envelope uses `schema_version: "2.0"` (a successful response is `"1.0"` — a known inconsistency). `error` carries `code` (the class), `detail_code` (the specific reason), `message`, `retryable`, and `request_id` — plus `retry_after` on an overload `503`: ```json { "schema_version": "2.0", "status": "error", "error": { "code": "invalid_request_error", "detail_code": "UNSUPPORTED_MEDIA_TYPE", "message": "content type 'image/tiff' is not supported; supported: application/pdf, image/png, image/jpeg, application/zip …", "retryable": false, "request_id": "20260729_…" } } ``` ### Client errors — fix the request, don't retry `error.code` is `invalid_request_error` and `retryable` is `false`; the `error.detail_code` names the specific reason. | `OriginalStatusCode` | `error.detail_code` | Meaning | | :------------------: | ------------------------ | ----------------------------------------------------------------------------------------------------- | | 400 | `INVALID_INPUT` | empty body, corrupt/truncated or password-protected PDF, bytes don't match `Content-Type`, zero pages | | 400 | `UNSUPPORTED_LANGUAGE` | `language` not in the list above (e.g. `"unsupported language 'fr-FR'"`) | | 413 | `PAYLOAD_TOO_LARGE` | over 200 MB or over 500 pages — split the document | | 415 | `UNSUPPORTED_MEDIA_TYPE` | TIFF/WebP/BMP/GIF or another unsupported type — convert to PDF/PNG/JPEG | ### Overload — back off and retry `error.code` is `service_overloaded`, `retryable` is `true`, and the body carries `retry_after` (seconds). The container sheds immediately rather than queueing. ```json { "schema_version": "2.0", "status": "error", "error": { "code": "service_overloaded", "detail_code": "SERVICE_UNAVAILABLE", "message": "server at capacity, retry later", "retryable": true, "request_id": "20260729_…", "retry_after": 5 } } ``` ### Other server errors — retryable `retryable` is `true`; back off and retry, and report `error.request_id` if one file fails persistently. | `OriginalStatusCode` | `error.detail_code` | Meaning | | :------------------: | ---------------------- | --------------------------------------------------------------------------- | | 500 | `INTERNAL_ERROR` | processing failed (rare) — resubmit | | 503 | `INSUFFICIENT_STORAGE` | instance disk guard tripped — sustained → raise instance volume size | | 504 | `PROCESSING_TIMEOUT` | document exceeded the per-job wait budget — raise timeouts (async) or split | Rule of thumb: **`4xx` = fix the request; `5xx` = retry with backoff.** The `retryable` flag in every error body encodes exactly this. #### [Deploy a Sarvam Vision endpoint](/api/self-hosted/sagemaker/deploy-vision) Step-by-step real-time, async, and batch deployment with boto3. > The InvokeEndpoint request and response contract for a self-hosted Sarvam Vision endpoint on SageMaker: content types, custom-attribute options, limits, the JSON response envelope, and error codes.