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.
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.
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.
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 |
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.
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.
/ocrExtract text from one or more images · v1 canonical
/document/layoutDetect ordered document regions and geometry · Tarka v1 extension
/chat/completionsRun OCR through an OpenAI-compatible multimodal message · v1 canonical
/audio/transcriptionsTranscribe audio in its source language · v1 canonical
/audio/translationsTranscribe audio and translate it to English · v1 canonical
/audio/speechGenerate audio from text · v1 canonical
/audio/voice-clonesCreate a consent-backed custom voice · v1 canonical
/audio/voice-clones/{voice_id}Read custom voice status · v1 canonical
/audio/voice-clones/{voice_id}Delete a custom voice · v1 canonical
Discover available aliases
GET /v1/modelscurl "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.
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].
modelstring · requiredUse 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.
imagestring · conditionally requiredOne base64 value or base64 data URI. Use this or images, not both.
imagesstring[] · conditionally requiredUp to 32 images in request order. Use this or image.
promptstring · optionalExtraction instructions such as reading order or output structure.
streamboolean · default falseReturn incremental server-sent events when true.
max_tokensinteger · optionalMaximum output tokens.
temperaturenumber · default 0Controls output randomness.
output_formatstring · default markdownChoose the portable top-level text representation: text, markdown, or a serialized json page document.
includestring[] · optionalAdd blocks to return typed page blocks or layout to include the underlying layout result. These are additive Tarka extensions.
layout_shapestring · default autoGeometry for Paddle blocks: auto, box, quadrilateral, or polygon.
Canonical request
POST /v1/ocrcurl "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
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
POST /v2/ocrcurl "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..."
}'OCR accepts base64 image data and does not fetch remote HTTP or HTTPS image URLs.
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.
modelstring · requiredUse pp-doclayout-v3.
imagestring · requiredOne inline base64 image or base64 data URI. Remote URLs are rejected.
thresholdnumber · optionalConfidence cutoff from 0 through 1.
shapestring · default autoauto, box, quadrilateral, or polygon.
labelsstring[] · optionalReturn only matching semantic labels, such as text, table, or formula.
Layout request
POST /v1/document/layoutcurl "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
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}
}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.
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
POST /v1/chat/completionscurl "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
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 itsurlvalue must be an inline base64 data URI. - Set
stream: trueto receivechat.completion.chunkevents followed bydata: [DONE]. - OCR through Chat Completions still requires the
utilitiesscope; aninference-only key is rejected. - The deprecated
/v2/chat/completionsalias accepts the same request body.
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.
filefile · requiredThe audio file to process.
modelstring · requiredUse whisper-large-v3, whisper-nepali-medium, or qwen3-asr for transcription. Only whisper-large-v3 supports translation.
languagestring · transcription onlyISO-639-1 source-language hint. Pass ne for Nepali audio.
promptstring · optionalVocabulary, names, or style context.
response_formatstring · default jsonjson, text, srt, verbose_json, or vtt.
temperaturenumber · optionalControls decoding randomness. Use 0 for deterministic decoding.
timestamp_granularities[]string[] · optionalsegment or word timestamps.
Transcription
POST /v1/audio/transcriptionscurl "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
POST /v1/audio/translationscurl "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"200 OK{
"text": "नमस्ते, हामी राहत सामग्री लिएर आउँदैछौँ।"
}Text to speech
Generate binary audio with POST /audio/speech. Pick an alias based on language and voice behavior.
modelstring · requirednepali-parler-tts, kokoro, piper, or a cloning-capable alias.
inputstring · requiredThe text to synthesize.
voicestring · requiredA delivery description for Parler, a named built-in voice for Kokoro, default for Piper, or a voice_... clone ID for Qwen3-TTS.
response_formatstring · default mp3mp3, opus, aac, flac, wav, or pcm.
speednumber · default 1Playback speed from 0.25 to 4.
instructionsstring · optionalAdditional model-specific speaking instructions.
stream_formatstring · optionalRequested streaming representation where supported.
POST /v1/audio/speech · binary responsecurl "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.wavKokoro with a named voice
POST /v1/audio/speech · binary responsecurl "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.wavDo 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.
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.
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.
modelstring · requiredUse qwen3-tts.
namestring · requiredYour display name for the voice.
samplefile · requiredA clean recording of the consenting speaker.
consent_signed_bystring · requiredThe consenting speaker's legal name.
consent_datedate · requiredThe ISO-8601 consent date.
Create a clone
POST /v1/audio/voice-clonescurl "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
202 Accepted{
"id": "voice_0123456789abcdef0123456789abcdef",
"object": "voice.clone",
"model": "qwen3-tts",
"name": "Product narrator",
"status": "ready"
}Generate speech with the clone
POST /v1/audio/speechcurl "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.wavRead or delete a clone
GET · DELETEcurl "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.
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
ListModelsgrpcurl \
-H "authorization: Bearer $TARKA_API_KEY" \
-d '{}' \
grpc.tarka.rest:443 \
tarka.inference.v2.InferenceService/ListModelsRun OCR
CreateOCRgrpcurl \
-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/CreateOCRDetect layout
CreateDocumentLayoutgrpcurl \
-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/CreateDocumentLayoutGenerate typed clients from the public protobuf definition. The package remains tarka.inference.v2 for gRPC wire compatibility. Canonical REST follows the v1 OpenAPI contract.
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.
POST http://tarka/v1/ocrcurl "http://tarka/v1/ocr" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-ocr-nepali",
"image": "data:image/png;base64,iVBORw0KGgoAAA..."
}'Errors, limits, and retries
REST failures use a top-level OpenAI-shaped error object. gRPC clients receive the corresponding gRPC status code.
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.