Build with AI that refuses to be weaponized.
Full API access to Thaura: chat, vision, document parsing, and speech-to-text. Ethics, not extraction. It never trains on your data, and never will.

Quick Start Guide
Get up and running with the Thaura API in minutes
Authentication
All requests must include an Authorization header with your API key:
Authorization: Bearer YOUR_API_KEYAPI Access
Create your API key in the app: open your account menu (your name, at the bottom of the sidebar) → API → API Keys.
Prepaid Billing
Pay only for what you use, charged exactly: $0.50 per million input tokens and $2.00 per million output tokens, with nothing rounded up and no minimum charge (a call with 52 input and 18 output tokens costs $0.000062). Audio transcription is $0.006 per audio minute, charged by the millisecond. Add funds from your account menu → API → Billing.
While a request runs, the most it can cost is held on your balance: its input plus max_tokens of output (32,000 when you don't set it). When it ends you pay for the tokens it used and the rest is released. A request your balance can't cover is refused with 402 insufficient_balance, so on a small balance set a lower max_tokens. There is no minimum balance.
A request you cancel, or whose connection closes, before the model starts answering costs nothing. Once the model has started answering, its input and the output written until then are billed, streamed or not.
Inference Endpoint
Simplified Attachments
Now supports sending attachments as simple base64 strings! No need for complex object structures.
/v1/chat/completionsRequest Parameters:
messagesMessage array. Can include custom system prompts via system role messages. Default: "You are Thaura, an ethical AI assistant."modelModel to use: only "thaura" is supported for chat (default: "thaura"). Other names return 400 invalid_model. Note that /v1/models also lists "thaura-whisper", which is the transcription model for /v1/audio/transcriptions and is not valid here, so pin your client to "thaura" rather than letting it pick from the model list.streamEnable SSE streaming (default: false). Recommended for long requests: the model may think before it answers, and a stream keeps the connection open while it does.temperatureControl response creativity (0.0-2.0, default: 0.7). While the model thinks before it answers (max_tokens of 16,000 or more, or unset, with no JSON response_format and no stop), temperature is held at 1.0.attachmentsFile attachments: simple base64 string or array (images, PDFs, audio)max_tokensMaximum tokens to generate (deprecated name, still fully supported). Capped at 32000. If both this and max_completion_tokens are sent, max_completion_tokens wins. At 16,000 or more, or when unset, the model may think before it answers, and that hidden reasoning counts toward this limit.max_completion_tokensMaximum tokens to generate. The current OpenAI SDK sends this name; it takes precedence over max_tokens. Capped at 32000. At 16,000 or more, or when unset, the model may think before it answers, and that hidden reasoning counts toward this limit.response_formatControl output format (e.g., JSON-only responses)toolsArray of function/tool definitions with JSON schemas for function calling. Parallel tool calls, 30+ tool payloads, nested/enum/array argument schemas and strict:true schemas are all supported. When the model calls a tool, finish_reason is "tool_calls"; when streaming, each tool_calls delta carries an index so the OpenAI SDK can reassemble it.tool_choice"auto" (default: the model calls a tool when it needs one) or "none" (ordinary prose, never a tool call). "required" and naming a specific function are not supported yet and return 400 unsupported_parameter; to steer the model toward one tool, send only that tool in tools.parallel_tool_callsEnable/disable parallel function calling (boolean)stopUp to 4 sequences where the model stops generating (string or array). The stop text is not included in the output.seedInteger for best-effort deterministic sampling: the same seed and parameters usually return the same output, but it isn't guaranteed.Parameters accepted but ignored
top_p, frequency_penalty, presence_penalty, logit_bias, n and user are accepted for OpenAI SDK compatibility and then discarded — Thaura pins its own sampling so the API never quietly produces worse output than the product. Sending them is safe; changing them has no effect. Only temperature (held at 1.0 while the model thinks), stop and seed actually influence sampling.
Parameters that are rejected
The legacy functions and function_call parameters are not supported and return 400 unsupported_parameter. Use tools and tool_choice instead — they are OpenAI's current function-calling API, and every modern client and SDK sends them by default.
Rate limits
- • 60 requests per minute per API key
- • 8 concurrent requests per API key
- • Over either limit returns 429 — retry after a moment. Agent frameworks spend several requests per user turn (one per tool round), so budget for that when sizing concurrency. Need more? Contact us and we will raise the ceiling on your key.
Limits
- • Context window: 128,000 tokens per request, prompt and output together. max_tokens is lowered to fit what the prompt leaves; a prompt that leaves no room for an answer returns 400 context_length_exceeded.
- • Output: up to 32,000 tokens per response, which is also the default when max_tokens isn't set.
- • Attachments: up to 20 per message (images, PDFs and audio together).
- • Request size: up to 50 MB of JSON per chat request, base64 files included (413 past it).
- • Speech-to-text: files up to 50 MB and 60 minutes long.
/v1/audio/transcriptionsSpeech-to-text: upload an audio file as multipart form data, get the transcript back. Billed per audio minute. Full examples in the Speech-to-Text tab below.
Response Formats
Non-Streaming Response (Thaura Format):
{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1234567890,
"model": "thaura",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "The AI response text..."
},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 52,
"completion_tokens": 18,
"total_tokens": 70
}
}Streaming Response (Thaura SSE Format):
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1234567890,"model":"thaura","choices":[{"index":0,"delta":{"content":"Response "},"finish_reason":null}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1234567890,"model":"thaura","choices":[{"index":0,"delta":{"content":"text..."},"finish_reason":null}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1234567890,"model":"thaura","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]Streaming with Token Usage:
Token usage comes in its own chunk just before data: [DONE], with an empty choices array (the OpenAI shape), so read choices[0] only when choices isn't empty. It's on by default; send stream_options: {"include_usage": false} to turn it off.
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1234567890,"model":"thaura","choices":[{"index":0,"delta":{"content":"text"},"finish_reason":null}]}
...
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1234567890,"model":"thaura","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":1234567890,"model":"thaura","choices":[],"usage":{"prompt_tokens":52,"completion_tokens":18,"total_tokens":70}}
data: [DONE]Error Response:
{
"error": {
"message": "tool_choice \"required\" is not supported ...",
"type": "invalid_request_error",
"param": "tool_choice",
"code": "unsupported_parameter"
}
}Status codes:
400invalid_messages, invalid_model, unsupported_parameter, invalid_json_schema, invalid_type, invalid_value, integer_below_min_value, array_above_max_length, missing_required_parameter— The request is malformed or asks for something unsupported: a bad messages array, a model other than thaura, the legacy functions parameters, tool_choice "required" or a named function, or an invalid JSON schema.400context_length_exceeded— The prompt is too long for the 128,000-token window, or carries more images than one request can.400too_many_attachments, invalid_attachments, invalid_image— More than 20 attachments in a message, an attachment that can't be read, or an image that can't be decoded.401unauthorized— The API key is missing or invalid.402insufficient_balance— Your balance can't cover this request's maximum cost. Add funds, or lower max_tokens.403key_scope— This key can't be used on this endpoint.404model_not_found— Unknown transcription model (chat answers an unknown model with 400 invalid_model).413file_too_large— The request body, or the audio file, is over 50 MB.429rate_limit_exceeded, concurrency_limit_exceeded— More than 60 requests a minute, or 8 at once, on this key. Retry after a moment.500internal_error, transcription_failed— Something failed on our side. Retry the request.503service_unavailable, upstream_rate_limited— The model is temporarily unavailable or busy. Retry after retry_after_seconds.504upstream_timeout— The model took too long to answer. Retry the request.
Once a stream has started, an error arrives as a data: {"error": …} chunk with the same type and code, followed by data: [DONE].
Code Examples
Ready-to-use examples for common use cases
Simple Question
Basic API call with a simple question
curl -X POST https://backend.thaura.ai/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "system", "content": "You are an ethical AI assistant"},
{"role": "user", "content": "What is 2+2?"}
],
"stream": true
}'Start Building with Ethical AI Today
Create your API key in the app from your account menu → API, and start building with Thaura AI.