API Documentation

Complete reference for the PrivatAI REST API. Simple, privacy-friendly, and powerful.

Introduction

The PrivatAI API provides access to LLM models (e.g. gpt-oss-120b, GLM-5.2), hosted in the EU with full GDPR compliance. All requests are transmitted over HTTPS and your prompts are not stored.

🔒 Privacy: We do not store prompts or responses. Only usage counters for billing.

Base URL

https://privatai.com/api/v1

OpenAI and Grok compatible: In your client, set only the base URL to https://privatai.com/api/v1 (e.g. OPENAI_API_BASE).

Authentication

Authenticate with your API key in the Authorization header:

http
Authorization: Bearer privat_xxxxxxxxxxxxxxxxxxxx

Find your API key in the dashboard after logging in and payment.

Chat Completion

POST /api/v1/chat/completions

Generates a response to your message. OpenAI-compatible format; by default a single JSON response, or streaming via Server-Sent Events when stream: true.

Request Body

Parameter Type Description
messages array Required. Array of messages (role, content)
model string Optional. Model key (e.g. gpt-oss-120b). If omitted: gpt-oss-120b for paid accounts. See GET /api/v1/models
stream boolean Optional, default false. If true: SSE stream
temperature, top_p, max_tokens, frequency_penalty, presence_penalty, stop, seed Optional. Standard OpenAI params. max_tokens is tier-capped (Essential 8,192, Professional 32,768).

Simple Request

bash
curl -X POST https://privatai.com/api/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-oss-120b", "messages": [{"role": "user", "content": "What is machine learning?"}]}'

With tools (function calling)

bash
curl -X POST https://privatai.com/api/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "messages": [
    {"role": "user", "content": "What is the weather in Berlin?"}
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get the current weather for a city",
        "parameters": {
          "type": "object",
          "properties": {
            "location": {"type": "string"}
          },
          "required": ["location"]
        }
      }
    }
  ],
  "tool_choice": "auto",
  "stream": false
}'

Conversation (Multi-Turn)

bash
curl -X POST https://privatai.com/api/v1/chat/completions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "messages": [
    {"role": "user", "content": "What is the capital of France?"},
    {"role": "assistant", "content": "The capital of France is Paris."},
    {"role": "user", "content": "What is the population?"}
  ]
}'

Response (SSE Stream, OpenAI format)

The response is streamed as Server-Sent Events in OpenAI format:

text/event-stream
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","created":...,"model":"...","choices":[{"index":0,"delta":{"content":"The"},"finish_reason":null}]}
data: {"id":"chatcmpl-...","choices":[{"index":0,"delta":{"content":" capital"},"finish_reason":null}]}
data: {"id":"chatcmpl-...","choices":[{"index":0,"delta":{"content":" of"},"finish_reason":null}]}
data: {"id":"chatcmpl-...","choices":[{"index":0,"delta":{"content":" France"},"finish_reason":null}]}
data: {"id":"chatcmpl-...","choices":[{"index":0,"delta":{"content":" is"},"finish_reason":null}]}
data: {"id":"chatcmpl-...","choices":[{"index":0,"delta":{"content":" Paris"},"finish_reason":null}]}
data: {"id":"chatcmpl-...","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":15,"completion_tokens":7,"total_tokens":22}}

Thinking models (Reasoning)

Models like gpt-oss-120b and GLM-5.2 are thinking models. When streaming, they may send delta.reasoning (reasoning trace) before or interleaved with delta.content (answer).

Handling: Accumulate delta.reasoning for the reasoning (e.g. to display or debug) and delta.content for the final user-facing answer.

json
{"choices":[{"index":0,"delta":{"reasoning":"Let me analyze..."}}]}
{"choices":[{"index":0,"delta":{"content":"The answer is Paris."}}]}

Check Usage

GET /api/v1/usage

Returns your current usage.

bash
curl https://privatai.com/api/v1/usage \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

json
{
  "tokens_used": 15420,
  "prompt_tokens": 5200,
  "completion_tokens": 10220,
  "requests": 89,
  "last_used": "2026-07-02T14:30:00"
}

List Models

GET /api/v1/models

Returns available models (OpenAI-compatible). GLM-5.2 only appears with a Professional plan.

bash
curl https://privatai.com/api/v1/models \
  -H "Authorization: Bearer YOUR_API_KEY"

Python Example

python
import requests
import json

API_KEY = "YOUR_API_KEY"
URL = "https://privatai.com/api/v1/chat/completions"

def chat(messages):
    response = requests.post(
        URL,
        headers={
            "Authorization": f"Bearer {API_KEY}",
            "Content-Type": "application/json"
        },
        json={"messages": messages},
        stream=True
    )

    for line in response.iter_lines():
        if line.startswith(b"data: "):
            data = json.loads(line[6:])
            if data.get("choices") and data["choices"][0].get("delta", {}).get("content"):
                print(data["choices"][0]["delta"]["content"], end="", flush=True)
            if data.get("choices") and data["choices"][0].get("finish_reason"):
                print()
                return data.get("usage")

chat([{"role": "user", "content": "Explain quantum computing in simple terms."}])

JavaScript Example

javascript
const API_KEY = 'YOUR_API_KEY';

async function chat(messages) {
  const response = await fetch('https://privatai.com/api/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ messages })
  });

  const reader = response.body.getReader();
  const decoder = new TextDecoder();

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;

    const chunk = decoder.decode(value);
    for (const line of chunk.split('\n')) {
      if (line.startsWith('data: ')) {
        const data = JSON.parse(line.slice(6));
        if (data.choices && data.choices[0]?.delta?.content) process.stdout.write(data.choices[0].delta.content);
        if (data.choices && data.choices[0]?.finish_reason) console.log();
      }
    }
  }
}

chat([{ role: 'user', content: 'What is the meaning of life?' }]);

Error Handling

The API returns standard HTTP status codes:

Code Meaning
200 Success
400 Bad request (e.g. missing messages)
401 Invalid or missing API key
402 Subscription inactive or budget not initialized — check/renew your plan
403 Model requires the Professional plan (e.g. GLM-5.2)
429 Rate limit or monthly allowance exceeded
500 Server error

Rate Limits

The API caps requests per minute by plan (per API key). Exceeding the limit returns HTTP 429. In addition, each plan includes a monthly usage allowance; once it is used up, the API also returns HTTP 429 until the next billing cycle. Web chat on the site is rate-limited separately.

Plan Requests / min Max tokens / response Volume / month (approx.) Models
Trial64.096Standard model
Essential308.192~ 20M tokensStandard model (gpt-oss-120b)
Professional6032.768~ 40M tokensStandard model (gpt-oss-120b)
~ 4M tokensFlagship model (GLM-5.2)
⏱️ The request limit is per API key — on HTTP 429, wait briefly and retry with backoff. The monthly volume is approximate: it depends on the model and your input/output ratio; the higher-tier flagship model consumes the allowance faster. See your live usage in the dashboard.