Skip to main content
POST
/
api
/
v1
/
chat
/
completions
OpenAI-Compatible Chat Completions
curl --request POST \
  --url https://api.example.com/api/v1/chat/completions \
  --header 'Content-Type: application/json' \
  --data '
{
  "model": "<string>",
  "messages": [
    {}
  ],
  "stream": true,
  "temperature": 123,
  "conversation_id": "<string>",
  "skills": [
    "<string>"
  ],
  "metadata": {}
}
'
Theo implements the OpenAI Chat Completions wire protocol at POST /api/v1/chat/completions. Any application that uses the OpenAI SDK can point baseURL at https://api.hitheo.ai/v1, swap in a Theo API key, and keep working — the endpoint accepts the same { model, messages, stream, temperature, ... } shape and returns the same chat.completion / chat.completion.chunk objects.
The response shape is identical to OpenAI. The routing underneath is Theo — intent classification, model selection, and automatic failover. Pass model: "theo-1-auto" to let Theo pick the best engine per request.

Base URL

https://hitheo.ai/api/v1

Authentication

Uses the standard Bearer-token header. Your Theo API key replaces your OpenAI key.
Authorization: Bearer theo_sk_...

Drop-in Example (OpenAI SDK)

import OpenAI from "openai";

const theo = new OpenAI({
  apiKey: process.env.THEO_API_KEY,
  baseURL: "https://api.hitheo.ai/v1",
});

const res = await theo.chat.completions.create({
  model: "theo-1-auto",
  messages: [
    { role: "system", content: "You are a helpful assistant." },
    { role: "user", content: "Write me a haiku about Miami." },
  ],
});

console.log(res.choices[0].message.content);

Streaming

Set stream: true to receive an SSE stream of chat.completion.chunk objects terminated by data: [DONE], exactly as OpenAI does.
const stream = await theo.chat.completions.create({
  model: "theo-1-auto",
  messages: [{ role: "user", content: "Stream me a short poem." }],
  stream: true,
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}

Supported model Values

Pass any Theo-branded model ID. theo-1-auto is recommended so Theo’s intent classifier picks the best engine per request; pass a specific engine if you want to pin the routing.
Model IDTheo ModeBest For
theo-1-autoautoLet Theo pick the right engine per prompt
theo-1-flashfastQuick responses, short chats, classification
theo-1-reasonthinkDeep reasoning, analysis, planning
theo-1-codecodeCode generation and review
theo-1-createimageImage generation
theo-1-motionvideoVideo generation
theo-1-researchresearchMulti-step web research with citations
theo-1-roastroastUnfiltered humor and sharp critique
theo-1-genuigenuiGenerative UI components
theo-1-analyzedomain_analysisDomain-specific analysis for business operations, finance, and compliance
theo-1-extractdata_extractionOCR and structured data extraction
theo-1-visionvisionMultimodal image analysis
Unknown model strings fall back to auto and Theo routes the request like any other prompt.

Request Body

The body is the standard OpenAI Chat Completion shape. Fields not listed below are accepted but ignored (e.g. top_p, n, max_tokens, user).
model
string
default:"theo-1-auto"
A Theo model ID. See the table above for valid values.
messages
object[]
required
The conversation so far. Each message has { role, content }. Supported roles: system, user, assistant. tool messages are accepted but ignored (Theo owns tool-call state internally).The last user message is treated as the prompt. All system messages are merged into a single system prompt that overrides Theo’s default persona. Prior user/assistant turns are injected as conversation context.
stream
boolean
default:"false"
When true, returns an SSE stream of chat.completion.chunk objects terminated by data: [DONE].
temperature
number
Sampling temperature (0–2).
conversation_id
string
Theo-specific. Attach this completion to an existing Theo conversation so its memory persists across channels. Omit to send a stateless request.
skills
string[]
Theo-specific. Activate skills by slug for this request. Merged with the user’s installed skills.
metadata
object
Theo-specific. Arbitrary key-value data attached to the audit log.

Response

A standard OpenAI chat.completion (or chat.completion.chunk for streaming). Theo-specific metadata is returned under a theo_metadata extension so it doesn’t collide with existing OpenAI client expectations.
{
  "id": "chatcmpl_...",
  "object": "chat.completion",
  "created": 1715872800,
  "model": "theo-1-flash",
  "choices": [
    {
      "index": 0,
      "message": { "role": "assistant", "content": "Neon waves on sand..." },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 24,
    "completion_tokens": 38,
    "total_tokens": 62
  },
  "theo_metadata": {
    "mode": "auto",
    "resolved_mode": "fast",
    "tools_used": [],
    "artifacts": [],
    "engine": "theo-core"
  }
}

When to use /v1/completions instead

  • You need a single-turn prompt string instead of a message array.
  • You want the richer native Theo response (follow-ups, artifacts, tool traces) instead of the OpenAI shape.
  • You want to control persona or response_style per request.
See Create Completion for the native endpoint.

Errors

Returns the same error envelope as every other v1 endpoint:
{
  "error": {
    "message": "Validation failed: messages must contain at least one message.",
    "type": "invalid_request_error",
    "code": "validation_error"
  }
}
StatusCodeDescription
400validation_errormessages is missing, empty, or malformed
400empty_promptmessages contained only system/tool messages
401invalid_api_keyMissing or invalid Authorization: Bearer theo_sk_...
402insufficient_creditsAccount balance is too low for the pre-flight reservation
404not_foundconversation_id not found
429rate_limit_exceededCheck Retry-After
500server_errorInternal error