SaaufAI API reference

OpenAI-compatible Chat Completions and Responses, streaming, tools, images and thinking levels.

Base URL and authentication

The API speaks the OpenAI format, so most SDKs and tools work by changing the base URL.

Base URL
https://api.saauf.xyz/v1

Send your key as a Bearer token: Authorization: Bearer YOUR_KEY.

The API is described in an OpenAPI 3.1 spec at /openapi.json, for code generators and AI agents; /llms.txt sums up the site for agents.

Chat Completions

POST /v1/chat/completions works with every API model. Use the model id from its page in Models.

Python
from openai import OpenAI

client = OpenAI(base_url="https://api.saauf.xyz/v1", api_key="YOUR_KEY")
reply = client.chat.completions.create(
    model="glm-5.3",
    messages=[{"role": "user", "content": "Write a haiku about tea."}],
)
print(reply.choices[0].message.content)
JavaScript
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://api.saauf.xyz/v1", apiKey: process.env.SAAUFAI_KEY });
const reply = await client.chat.completions.create({
  model: "glm-5.3",
  messages: [{ role: "user", content: "Write a haiku about tea." }],
});
console.log(reply.choices[0].message.content);

Streaming

Set "stream": true to receive the answer as server-sent events, chunk by chunk, ending with data: [DONE].

Python
stream = client.chat.completions.create(model="glm-5.3", messages=[{"role": "user", "content": "Count to five."}], stream=True)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")

Tools and images

Tools (function calling) use the standard tools and tool_calls fields. Models that accept images take them as image_url content parts. A model's page lists what it accepts and can do.

Image generation

Image models take POST /v1/images/generations with model, prompt, n (1–4) and size, and answer with base64 images. Each image is charged at the model's image price. At busy times, premium image models and Flux 2 Klein may be answered by Recraft v4.1 Flash; the answer's model then says so, and you're charged that model's price.

Embeddings

Embedding models take POST /v1/embeddings with model and input (a string or up to 100 strings), plus optional dimensions, input_type (query or passage, for models that treat searches and documents differently; documents by default) and encoding_format (float or base64), and answer in OpenAI's format. Input tokens are charged at the model's input price; when the upstream doesn't count them, about four characters count as one token.

Decisions

Decision models answer typed questions about a text instead of writing one. They take POST /v1/decisions with model, state (a string or an array of strings, up to 200,000 characters) and questions (up to 64, by id). Each question has a type and instructions: noul answers with the probability of yes, and choice picks one of 2 to 64 options you describe in criteria. Input tokens are charged at the model's input price; answers cost nothing. Safeguards read the state and the questions.

The OpenAI Decisions format works too, on any decision model: send input instead of state, and questions as an array of named predicate, choice (with choices) or score (with levels) questions. You get answers back as an array in that format. Only GPT 6 Luna Decisions takes score questions.

curl
curl https://api.saauf.xyz/v1/decisions -H "Authorization: Bearer $SAAUFAI_KEY" -H "Content-Type: application/json" \
  -d '{"model": "d3", "state": "The kettle arrived broken. I want my money back.",
       "questions": {
         "refund": {"type": "noul", "instructions": "Does the customer ask for a refund?"},
         "tone": {"type": "choice", "instructions": "What is the tone?",
                  "criteria": {"angry": "Upset or hostile.", "neutral": "Calm and matter of fact."}}}}'

Speech to text

Transcription models take POST /v1/audio/transcriptions as a multipart form with file (up to 25 MB; mp3, mp4, m4a, wav, webm, ogg, flac) and model, plus optional language, prompt, temperature, timestamp_granularities[] (segment, word) and response_format (json, text, srt, vtt or verbose_json). Audio is charged per minute at the model's audio price, by the length the upstream reports.

curl
curl https://api.saauf.xyz/v1/audio/transcriptions -H "Authorization: Bearer $SAAUFAI_KEY" \
  -F model=whisper-large-v3 -F file=@meeting.mp3

Text to speech

Speech models take POST /v1/audio/speech with model, input (up to 4096 characters), voice and optional response_format (wav by default; Orpheus takes only wav) and speed, and answer with the audio. Text is charged per input character at the model's price per 1M characters. A model's page lists its voices.

curl
curl https://api.saauf.xyz/v1/audio/speech -H "Authorization: Bearer $SAAUFAI_KEY" -H "Content-Type: application/json" \
  -d '{"model":"orpheus-v1-english","voice":"autumn","input":"Hello from SaaufAI.","response_format":"wav"}' -o hello.wav

Thinking levels

For reasoning models, pick how much they think with reasoning_effort (none, low, medium, high), or add the level to the model id, like glm-5.3:low, for clients that can't send extra fields. Less thinking answers faster and costs less.

Responses API

Some models also take POST /v1/responses (the OpenAI Responses format); their page says so. Other models answer that endpoint with an unsupported_endpoint error.

List models

curl
curl https://api.saauf.xyz/v1/models -H "Authorization: Bearer $SAAUFAI_KEY"

Returns the models your key may use, plus :level variants for models with thinking levels.

Pollinations models

With a connected Pollinations account (see Connections), use its models through the same API with ids starting pollinations/. They're paid from your Pollen, never from SaaufAI credit.

API and Playground prompts and replies aren't stored. SaaufAI keeps only metadata such as time, model, token counts and status. Each model's own provider terms also apply; see Disclosures and privacy.