---
title: "Utility model APIs | Tarka Docs"
description: "Use Tarka utility models through canonical v1 REST and native gRPC."
url: "https://tarkahq.com/docs/inference/utility-models/"
---

Available Inference · Utility models

# Utility model APIs

Detect document structure, extract text, transcribe and translate audio, synthesize speech, and create consent-backed voices through the public API or a Tarka Agent Host.

Provisioning and management **Use the console or the Control API.**

Create and scope API keys, select model access, and inspect usage in the console or through the Control API. Runtime inference requests go to the Inference API.

[Open console](https://tarkahq.com/console) [Control API reference](https://tarkahq.com/docs/control-api/)

**Use model discovery as the source of truth.**

Public utility requests require a key with the `utilities` scope and explicit access to the requested alias. `GET /v1/models` returns the aliases available to that key.

Choose a surface

## Canonical REST, native gRPC, and Agent Host

Canonical `/v1` REST and native gRPC reach the same service. The old `/v2` REST prefix is a deprecated alias with identical request fields.

| Surface | Base address | Authentication | Use it for |
| --- | --- | --- | --- |
| **Public REST** | `https://tarka.rest/v1` | Bearer API key | OpenAI-compatible clients and utility routes |
| **Native gRPC** | `grpc.tarka.rest:443` | `authorization` metadata | Typed clients and server streaming |
| **Agent Host v1** | `http://tarka/v1` | Automatically authorized within the host | Host-local requests without a public network round trip |
| **Deprecated REST alias** | `https://tarka.rest/v2` | Bearer API key | Temporary compatibility for existing integrations |

**Keep public API keys server-side.**

Never embed a `tk_live_...` key in browser code. The `http://tarka` address resolves only inside a Tarka Agent Host and is not a public fallback.

REST reference

## Canonical v1 endpoints

Prefix each path with `/v1`. Model listing and retrieval are available at `GET /v1/models` and `GET /v1/models/{model}`. The deprecated `/v2` prefix remains an alias.

POST `/ocr`

Extract text from one or more images · **v1 canonical**

POST `/document/layout`

Detect ordered document regions and geometry · **Tarka v1 extension**

POST `/chat/completions`

Run OCR through an OpenAI-compatible multimodal message · **v1 canonical**

POST `/audio/transcriptions`

Transcribe audio in its source language · **v1 canonical**

POST `/audio/translations`

Transcribe audio and translate it to English · **v1 canonical**

POST `/audio/speech`

Generate audio from text · **v1 canonical**

POST `/audio/voice-clones`

Create a consent-backed custom voice · **v1 canonical**

GET `/audio/voice-clones/{voice_id}`

Read custom voice status · **v1 canonical**

DELETE `/audio/voice-clones/{voice_id}`

Delete a custom voice · **v1 canonical**

### Discover available aliases

Shell `GET /v1/models`

```
curl "https://tarka.rest/v1/models" \
  -H "Authorization: Bearer $TARKA_API_KEY"
```

### Currently available utility aliases

| Modality | Alias | Designed for | Status |
| --- | --- | --- | --- |
| **Speech to text** | `whisper-large-v3` | Multilingual transcription and English translation | Available |
| **Speech to text** | `whisper-nepali-medium` | Nepali-specialized speech transcription | Available |
| **Speech to text** | `qwen3-asr` | Multilingual transcription with Qwen3-ASR 1.7B | Available |
| **OCR** | `glm-ocr` | General document text and structured extraction | Available |
| **OCR** | `glm-ocr-nepali` | Nepali and Devanagari document text | Available |
| **OCR** | `paddleocr-vl-1.6` | Page-level document parsing with Markdown and structured blocks | Available |
| **Document layout** | `pp-doclayout-v3` | Fast document-region detection, geometry, and reading order | Available |
| **Text to speech** | `nepali-parler-tts` | Nepali speech with descriptive voice instructions | Available |
| **TTS + voice cloning** | `qwen3-tts` | Text to speech with consent-backed voice cloning | Available |
| **Text to speech** | `kokoro` | Fast English speech with named built-in voices | Available |
| **Text to speech** | `piper` | Efficient English speech with a fixed voice | Available |

Availability can be narrower for an individual organization or key. If an alias does not appear in `GET /v1/models`, do not route requests to it.

Available · canonical v1

## OCR with the dedicated endpoint

Send one `image` or an `images` array to `POST /ocr`. Non-streaming requests return an `ocr.completion`; `stream: true` returns server-sent events ending in `data: [DONE]`.

`model` string · required

Use `glm-ocr` for general extraction, `glm-ocr-nepali` for Nepali and Devanagari text, or `paddleocr-vl-1.6` for page-level document parsing and Markdown.

`image` string · conditionally required

One base64 value or base64 data URI. Use this or `images`, not both.

`images` string\[\] · conditionally required

Up to 32 images in request order. Use this or `image`.

`prompt` string · optional

Extraction instructions such as reading order or output structure.

`stream` boolean · default false

Return incremental server-sent events when true.

`max_tokens` integer · optional

Maximum output tokens.

`temperature` number · default 0

Controls output randomness.

`output_format` string · default markdown

Choose the portable top-level `text` representation: `text`, `markdown`, or a serialized `json` page document.

`include` string\[\] · optional

Add `blocks` to return typed page blocks or `layout` to include the underlying layout result. These are additive Tarka extensions.

`layout_shape` string · default auto

Geometry for Paddle blocks: `auto`, `box`, `quadrilateral`, or `polygon`.

### Canonical request

Shell `POST /v1/ocr`

```
curl "https://tarka.rest/v1/ocr" \
  -H "Authorization: Bearer $TARKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "paddleocr-vl-1.6",
    "image": "data:image/png;base64,iVBORw0KGgoAAA...",
    "output_format": "markdown",
    "include": ["blocks", "layout"],
    "layout_shape": "auto"
  }'
```

### Response

JSON `200 OK`

```
{
  "id": "ocr-01K3...",
  "object": "ocr.completion",
  "created": 1787596800,
  "model": "paddleocr-vl-1.6",
  "text": "# Quarterly report\n\nRevenue increased by 12%.",
  "pages": [{
    "index": 0,
    "width": 1600,
    "height": 2200,
    "text": "Quarterly report\n\nRevenue increased by 12%.",
    "markdown": "# Quarterly report\n\nRevenue increased by 12%.",
    "blocks": [{
      "id": "block-0",
      "label": "doc_title",
      "reading_order": 0,
      "bbox": {"x_min": 112, "y_min": 84, "x_max": 946, "y_max": 180},
      "polygon": [{"x": 112, "y": 84}, {"x": 946, "y": 84}, {"x": 946, "y": 180}, {"x": 112, "y": 180}],
      "confidence": 0.98,
      "content": "# Quarterly report"
    }]
  }],
  "usage": {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0}
}
```

### Deprecated v2 alias

Shell `POST /v2/ocr`

```
curl "https://tarka.rest/v2/ocr" \
  -H "Authorization: Bearer $TARKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "glm-ocr-nepali",
    "image": "data:image/png;base64,iVBORw0KGgoAAA..."
  }'
```

**Images must be inline.**

OCR accepts base64 image data and does not fetch remote HTTP or HTTPS image URLs.

Tarka extension · canonical v1

## Document layout without recognition

Call `POST /document/layout` with `pp-doclayout-v3` when your pipeline needs semantic regions, coordinates, and reading order but not generated text. This extension follows the same authentication, discovery, metering, and error conventions as the OpenAI-compatible routes.

`model` string · required

Use `pp-doclayout-v3`.

`image` string · required

One inline base64 image or base64 data URI. Remote URLs are rejected.

`threshold` number · optional

Confidence cutoff from `0` through `1`.

`shape` string · default auto

`auto`, `box`, `quadrilateral`, or `polygon`.

`labels` string\[\] · optional

Return only matching semantic labels, such as `text`, `table`, or `formula`.

### Layout request

Shell `POST /v1/document/layout`

```
curl "https://tarka.rest/v1/document/layout" \
  -H "Authorization: Bearer $TARKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "pp-doclayout-v3",
    "image": "data:image/png;base64,iVBORw0KGgoAAA...",
    "threshold": 0.3,
    "shape": "polygon",
    "labels": ["doc_title", "text", "table", "formula"]
  }'
```

### Ordered regions

JSON `200 OK`

```
{
  "id": "layout-01K3...",
  "object": "document.layout",
  "created": 1787596800,
  "model": "pp-doclayout-v3",
  "width": 1600,
  "height": 2200,
  "regions": [{
    "id": "region-0",
    "label": "doc_title",
    "class_id": 0,
    "score": 0.98,
    "bbox": {"x_min": 112, "y_min": 84, "x_max": 946, "y_max": 180},
    "polygon": [{"x": 112, "y": 84}, {"x": 946, "y": 88}, {"x": 942, "y": 180}, {"x": 116, "y": 176}],
    "reading_order": 0
  }],
  "usage": {"prompt_tokens": 0, "completion_tokens": 0, "total_tokens": 0}
}
```

**Do not call both routes unless you need two independent passes.**

`paddleocr-vl-1.6` already runs PP-DocLayoutV3 inside its page-level OCR pipeline. Use the standalone layout route for geometry-only workflows or custom region routing.

OpenAI-compatible OCR

## OCR through Chat Completions

Use the same `POST /chat/completions` route as a language model, select an OCR alias, and include an inline image in a standard multimodal user message. The response is a normal `chat.completion`.

### Request

Shell `POST /v1/chat/completions`

```
curl "https://tarka.rest/v1/chat/completions" \
  -H "Authorization: Bearer $TARKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "glm-ocr-nepali",
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "Extract the Nepali text in reading order."},
        {"type": "image_url", "image_url": {
          "url": "data:image/png;base64,iVBORw0KGgoAAA..."
        }}
      ]
    }],
    "temperature": 0
  }'
```

### Response

JSON `200 OK`

```
{
  "id": "chatcmpl-01K3...",
  "object": "chat.completion",
  "created": 1787596800,
  "model": "glm-ocr-nepali",
  "choices": [{
    "index": 0,
    "message": {"role": "assistant", "content": "बाढी राहत केन्द्र"},
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 412,
    "completion_tokens": 18,
    "total_tokens": 430
  }
}
```

- The content part type is `image_url`, but its `url` value must be an inline base64 data URI.
- Set `stream: true` to receive `chat.completion.chunk` events followed by `data: [DONE]`.
- OCR through Chat Completions still requires the `utilities` scope; an `inference`-only key is rejected.
- The deprecated `/v2/chat/completions` alias accepts the same request body.

Available · canonical v1

## Speech to text and translation

Upload audio as multipart form data. Transcriptions preserve the source language. Use `whisper-nepali-medium` for Nepali-specialized transcription; English translation is available with `whisper-large-v3`.

`file` file · required

The audio file to process.

`model` string · required

Use `whisper-large-v3`, `whisper-nepali-medium`, or `qwen3-asr` for transcription. Only `whisper-large-v3` supports translation.

`language` string · transcription only

ISO-639-1 source-language hint. Pass `ne` for Nepali audio.

`prompt` string · optional

Vocabulary, names, or style context.

`response_format` string · default json

`json`, `text`, `srt`, `verbose_json`, or `vtt`.

`temperature` number · optional

Controls decoding randomness. Use `0` for deterministic decoding.

`timestamp_granularities[]` string\[\] · optional

`segment` or `word` timestamps.

### Transcription

Shell `POST /v1/audio/transcriptions`

```
curl "https://tarka.rest/v1/audio/transcriptions" \
  -H "Authorization: Bearer $TARKA_API_KEY" \
  -F "file=@./meeting-nepali.wav" \
  -F "model=whisper-nepali-medium" \
  -F "language=ne" \
  -F "response_format=json"
```

### Translation

Shell `POST /v1/audio/translations`

```
curl "https://tarka.rest/v1/audio/translations" \
  -H "Authorization: Bearer $TARKA_API_KEY" \
  -F "file=@./interview-nepali.mp3" \
  -F "model=whisper-large-v3" \
  -F "response_format=json"
```

JSON `200 OK`

```
{
  "text": "नमस्ते, हामी राहत सामग्री लिएर आउँदैछौँ।"
}
```

Available · canonical v1

## Text to speech

Generate binary audio with `POST /audio/speech`. Pick an alias based on language and voice behavior.

`model` string · required

`nepali-parler-tts`, `kokoro`, `piper`, or a cloning-capable alias.

`input` string · required

The text to synthesize.

`voice` string · required

A delivery description for Parler, a named built-in voice for Kokoro, `default` for Piper, or a `voice_...` clone ID for Qwen3-TTS.

`response_format` string · default mp3

`mp3`, `opus`, `aac`, `flac`, `wav`, or `pcm`.

`speed` number · default 1

Playback speed from `0.25` to `4`.

`instructions` string · optional

Additional model-specific speaking instructions.

`stream_format` string · optional

Requested streaming representation where supported.

Shell `POST /v1/audio/speech · binary response`

```
curl "https://tarka.rest/v1/audio/speech" \
  -H "Authorization: Bearer $TARKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nepali-parler-tts",
    "input": "नमस्ते नेपाल",
    "voice": "A clear, calm Nepali speaker",
    "response_format": "wav",
    "speed": 1
  }' \
  --output speech.wav
```

### Kokoro with a named voice

Shell `POST /v1/audio/speech · binary response`

```
curl "https://tarka.rest/v1/audio/speech" \
  -H "Authorization: Bearer $TARKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "kokoro",
    "input": "Tarka utility inference is ready.",
    "voice": "af_heart",
    "response_format": "wav",
    "speed": 1
  }' \
  --output kokoro.wav
```

**Voice values are model-specific.**

Do not send a delivery description, built-in voice name, or clone ID to a model that does not support that voice type. A clone ID can only be used with the model that created it.

Available · canonical v1

## Voice cloning

Create a consent-backed voice resource with `qwen3-tts`, then use its identifier with the same model at `/audio/speech`. The clone is available when the response status is `ready`.

**Consent is required.**

Only upload a speaker sample when you have permission to create and use that voice. Tarka records the consent name and date with the clone.

`model` string · required

Use `qwen3-tts`.

`name` string · required

Your display name for the voice.

`sample` file · required

A clean recording of the consenting speaker.

`consent_signed_by` string · required

The consenting speaker's legal name.

`consent_date` date · required

The ISO-8601 consent date.

### Create a clone

Shell `POST /v1/audio/voice-clones`

```
curl "https://tarka.rest/v1/audio/voice-clones" \
  -H "Authorization: Bearer $TARKA_API_KEY" \
  -F "model=qwen3-tts" \
  -F "name=Product narrator" \
  -F "sample=@./consented-sample.wav" \
  -F "consent_signed_by=Example Person" \
  -F "consent_date=2026-08-28"
```

### Response

JSON `202 Accepted`

```
{
  "id": "voice_0123456789abcdef0123456789abcdef",
  "object": "voice.clone",
  "model": "qwen3-tts",
  "name": "Product narrator",
  "status": "ready"
}
```

### Generate speech with the clone

Shell `POST /v1/audio/speech`

```
curl "https://tarka.rest/v1/audio/speech" \
  -H "Authorization: Bearer $TARKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen3-tts",
    "input": "This was generated with the consented reference voice.",
    "voice": "voice_0123456789abcdef0123456789abcdef",
    "response_format": "wav"
  }' \
  --output cloned-voice.wav
```

### Read or delete a clone

Shell `GET · DELETE`

```
curl "https://tarka.rest/v1/audio/voice-clones/voice_0123456789abcdef0123456789abcdef" \
  -H "Authorization: Bearer $TARKA_API_KEY"

curl -X DELETE "https://tarka.rest/v1/audio/voice-clones/voice_0123456789abcdef0123456789abcdef" \
  -H "Authorization: Bearer $TARKA_API_KEY"
```

Lifecycle statuses are `pending`, `processing`, `ready`, and `failed`.

Native API

## gRPC and protobuf

Connect to `grpc.tarka.rest:443` over TLS and send the public API key as `authorization: Bearer ...` metadata. The service is `tarka.inference.v2.InferenceService`.

| RPC | Purpose |
| --- | --- |
| `ListModels` | List aliases available to the API key |
| `RetrieveModel` | Retrieve one available alias |
| `CreateOCR / StreamOCR` | Extract image text as one response or a server stream |
| `CreateDocumentLayout` | Detect semantic regions, confidence, geometry, and reading order |
| `CreateChatCompletion / StreamChatCompletion` | Use the chat contract, including OCR aliases |
| `CreateTranscription` | Transcribe uploaded audio |
| `CreateTranslation` | Translate uploaded audio to English |
| `CreateSpeech` | Receive generated audio as a server stream |
| `CreateVoiceClone / GetVoiceClone / DeleteVoiceClone` | Manage consent-backed voice resources |

### Discover models

grpcurl `ListModels`

```
grpcurl \
  -H "authorization: Bearer $TARKA_API_KEY" \
  -d '{}' \
  grpc.tarka.rest:443 \
  tarka.inference.v2.InferenceService/ListModels
```

### Run OCR

grpcurl `CreateOCR`

```
grpcurl \
  -H "authorization: Bearer $TARKA_API_KEY" \
  -d '{
    "model": "glm-ocr-nepali",
    "image": "data:image/png;base64,iVBORw0KGgoAAA...",
    "prompt": "Extract the Nepali text."
  }' \
  grpc.tarka.rest:443 \
  tarka.inference.v2.InferenceService/CreateOCR
```

### Detect layout

grpcurl `CreateDocumentLayout`

```
grpcurl \
  -H "authorization: Bearer $TARKA_API_KEY" \
  -d '{
    "model": "pp-doclayout-v3",
    "image": "data:image/png;base64,iVBORw0KGgoAAA...",
    "shape": "polygon"
  }' \
  grpc.tarka.rest:443 \
  tarka.inference.v2.InferenceService/CreateDocumentLayout
```

Generate typed clients from the public [protobuf definition](https://github.com/TarkaHQ/api/blob/main/proto/tarka/inference/v2/inference.proto). The package remains `tarka.inference.v2` for gRPC wire compatibility. Canonical REST follows the [v1 OpenAPI contract](https://github.com/TarkaHQ/api/blob/main/openapi/tarka-inference-v1.openapi.json).

Agent Host

## Call utilities over the host-local v1 endpoint

Inside a Tarka Agent Host, replace the public base URL with `http://tarka/v1` and omit the bearer header. Requests are authorized automatically and limited to the chat and utility aliases selected for that host.

Shell `POST http://tarka/v1/ocr`

```
curl "http://tarka/v1/ocr" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "glm-ocr-nepali",
    "image": "data:image/png;base64,iVBORw0KGgoAAA..."
  }'
```

Reliability

## Errors, limits, and retries

REST failures use a top-level OpenAI-shaped `error` object. gRPC clients receive the corresponding gRPC status code.

JSON `4xx`

```
{
  "error": {
    "message": "The requested model is not available for this API key.",
    "type": "invalid_request_error",
    "param": "model",
    "code": "model_not_allowed"
  }
}
```

| Status | Meaning | Client action |
| --- | --- | --- |
| `400` | Invalid field, format, modality, or image | Correct the request; do not retry unchanged |
| `401` | Missing, invalid, or revoked public key | Replace the key |
| `403` | Missing `utilities` scope or model access | Update the key in the console or Control API |
| `404` | Unknown model or voice resource | Refresh discovery or check the identifier |
| `429` | Concurrency, rate, or organization limit reached | Retry with exponential backoff and jitter |
| `5xx` | Temporary service or model failure | Retry safe requests with bounded backoff |

- Do not retry malformed requests or permission failures unchanged.
- For interrupted streams, treat the output as incomplete and retry only if your application can tolerate duplicate work.
- Keep uploaded images and audio within the limits returned by your organization policy.
