API reference

Change the base URL. Keep your code.

Tīrtha speaks three dialects: OpenAI Chat, Anthropic Messages, and OpenAI Responses. Plain text, tools, and streaming work on all three. Below are copy-paste examples, the full config reference, and the error codes.

Quickstart

One base URL, one key.

Any OpenAI-compatible client works. Point it at the Tīrtha base URL, use your key, and set the model to tirtha/verified. The gateway chooses the tier for you.

# curl curl https://api.tirtha.ai/v1/chat/completions \ -H "Authorization: Bearer sk-tirtha-…" \ -H "Content-Type: application/json" \ -d '{ "model": "tirtha/verified", "messages": [{"role":"user","content":"Write a function that reverses a string."}] }'
# python, the openai sdk from openai import OpenAI client = OpenAI(base_url="https://api.tirtha.ai/v1", api_key="sk-tirtha-…") r = client.chat.completions.create( model="tirtha/verified", messages=[{"role":"user","content":"Write a function that reverses a string."}], ) print(r.choices[0].message.content)
Chat completions

The primary path.

POST /v1/chat/completions. Standard OpenAI request and response shapes. System prompts and multi-turn history are passed through. The response is the OpenAI shape you already parse.

# -> 200 { "id": "chatcmpl-…", "object": "chat.completion", "choices": [{ "index": 0, "message": {"role":"assistant","content":"def reverse(s): return s[::-1]"}, "finish_reason": "stop" }], "usage": {"prompt_tokens":18,"completion_tokens":9,"total_tokens":27} }

Note: temperature is fixed at 0 and model is chosen by the gateway, so both are ignored if you send them. See the config reference below for the full honored-versus-ignored list.

Streaming

Server-sent events, usage on the last chunk.

Set stream: true. To get token usage in the stream, set stream_options: {"include_usage": true} and read it from the final chunk.

curl https://api.tirtha.ai/v1/chat/completions \ -H "Authorization: Bearer sk-tirtha-…" \ -d '{ "model":"tirtha/verified", "stream":true, "stream_options":{"include_usage":true}, "messages":[{"role":"user","content":"…"}] }' # SSE frames data: {"choices":[{"delta":{"content":"def "}}]} data: {"choices":[{"delta":{"content":"reverse"}}]} data: {"choices":[{"delta":{}}],"usage":{"total_tokens":27}} data: [DONE]
Tool calling

OpenAI wire format, checked before it is served.

Send tools and, if you want, tool_choice. Tool calls come back in the OpenAI tool_calls shape, identical across all three dialects. Every tool call passes an internal check before it reaches you.

{ "model": "tirtha/verified", "messages": [{"role":"user","content":"What is the weather in Paris tomorrow?"}], "tools": [{"type":"function","function":{ "name":"get_forecast", "parameters":{"type":"object","properties":{"city":{"type":"string"},"day":{"type":"string"}}} }}] } # -> assistant turn "tool_calls": [{"id":"call_1","type":"function", "function":{"name":"get_forecast","arguments":"{\"city\":\"Paris\",\"day\":\"tomorrow\"}"}}]
Dialects

Same engine, three front doors.

Point Claude Code at Messages, point Codex at Responses, point everything else at Chat. Tools and streaming work on all three.

DialectEndpointFor
OpenAI ChatPOST /v1/chat/completionsThe default; most SDKs and tools
Anthropic MessagesPOST /v1/messagesClaude Code and Anthropic SDKs; system and history are native
OpenAI ResponsesPOST /v1/responsesCodex and the Responses SDK

The reply is translated back into the dialect you called, so your existing client parses it unchanged. Usage fields and stop reasons follow each dialect's own convention.

Verify

Ask if an answer is backed by its source.

POST /v1/verify. Not part of the OpenAI standard, so point at it directly. Give a source and a claim; get a verdict, a confidence, and a short reason. It is a consistency check against the source, not a fact-checker of the world.

curl https://api.tirtha.ai/v1/verify \ -H "Content-Type: application/json" \ -d '{ "source": "The trial reduced symptoms in 6 of 10 patients.", "claim": "The drug is effective." }' # -> 200 { "decision": "allow", # or "refuse" "confidence": 0.82, "reasoning": "6 of 10 responders supports a claim of effectiveness.", "usage": {"tokens_in":31,"tokens_out":14} }

Public, no key required, typically one to two seconds. Try it in the browser with no setup at tirtha.ai/verify.

Config reference

Every param, honored or dropped.

Standard OpenAI parameters

ParamHonoredDefaultNotes
messagesYesrequiredSystem prompt and full history passed through
tools, tool_choiceYesnoneTriggers the tool-calling path
streamYesfalseServer-sent events
stream_optionspartialnoneOnly include_usage is read
response_formatYesnone{"type":"json_object"} passed through
max_tokensYestier capCapped to the serving tier's limit
temperatureignored0Fixed at 0; determinism makes reuse safe
modelignoredtirtha/verifiedThe gateway selects the tier
top_pignored-Declared for spec; moot at temperature 0
stopsoon-Declared, not yet wired

Tīrtha extensions  (body.tirtha.*)

FieldTypeDefaultPurpose
modestringautoCare dial: auto · max · value · low. Request overrides key overrides account.
testsstringnoneChecks that must pass before an answer is trusted; failures escalate
domainstringkey defaultScope tag for reuse of solved work
subdomainstringkey defaultSub-scope tag
Errors

What comes back when it will not serve.

Errors follow the OpenAI error shape. Two behaviors are worth knowing: rate and quota return 429, and hitting your daily spend cap does not fail. It degrades to the lower cost path and tells you so in the response.

StatusTypeMeaning
401invalid_api_keyMissing or bad Bearer key
429rate_limit_errorPer-key rate exceeded. Honor Retry-After.
429quota_exceededMonthly quota exceeded
429server_busyConcurrency gate full; retry shortly
200meta.spend_capped:trueDaily spend cap reached; served on the lower cost path, never a silent switch
200meta.premium_limited:trueIncluded premium allowance reached; served on the lower cost path
{ "error": { "type":"rate_limit_error", "message":"Rate limit exceeded. Retry after 60s." } }
More

The rest of the story.

The server info card has the capabilities matrix, limits, cache policy, and the honesty block. Security has the data posture. Pricing has the tiers. Found a wrong answer? Report it and we send a receipt.