Developer API

Every Sataves model and tool, with one API key

Access listed models, AI Studio services, website tools and supported Civitai resources and Hugging Face Spaces from your code. OpenAI- and Anthropic-compatible endpoints connect to developer tools; check the endpoint capabilities and limitations below.

Base URLhttps://sataveslabs.com/v1

Overview

693AI models
429chat & agent models
105image & video models
92speech models

One key, beyond the model catalog

One API key connects model calls, AI Studio workflows, supported website tools, virtual numbers and the Hub.

AI Studio services
25
Hugging Face Spaces
1,515,116
Indexed Civitai models
42,013

Discover Hugging Face Spaces and resolve Civitai resources through the API. Run compatible resources after access, availability and pricing checks.

Catalog counts are separate from API model counts; not every indexed resource has a supported execution API. Hub catalog snapshot: .

  • Chat & agents: POST /v1/chat/completions and /v1/responses (OpenAI formats) and POST /v1/messages (Anthropic format) with tools (function calling), image input and streaming; plus /v1/audio/speech and /v1/audio/transcriptions for speech.
  • AI Studio services: Image and video generation, text to speech, speech to text, OCR, summaries, translation, rewriting, music and embeddings.
  • Tools & jobs: Link downloads, video translation and dubbing, subtitles, format conversion, image and font tools, network tools and search.
  • Civitai & Hugging Face: Resolve supported Civitai resources and Hugging Face Spaces; execution requires access and compatibility checks.
  • Information: Models, availability, prices, status, balance and per-key usage — all through the API.

Each API request is charged to your account balance exactly like the same job on the website. There is no separate API subscription or fee.

Compatibility & limits

EndpointSupported features
Chat CompletionsModel-supported text, images and function tools; buffered streaming
MessagesAnthropic message and tool round trips; buffered streaming
ResponsesStateless: send history with each request. Hosted tools are not executed.
Structured outputJSON Schema output is unsupported and rejected explicitly.
SpeechAAC, FLAC and PCM are unsupported; check the route contract for supported output formats.

Tutorials are integration examples, not certification of every SDK version. max_output_tokens is the effective API ceiling; provider_max_output_tokens is the model capacity. Requests above the API ceiling return 400.

/v1/status reports API/catalog availability; it does not test live provider health or provider credit.

Model rates use current USD policy. tiers and adjustments describe usage bands, fees, discounts and limits. Other services require their own service quote. Text-request holds account for input, tools, media and maximum output; unused reservations are released.

purchase_outcome_unknown means the number purchase is unresolved. Do not retry with a new key: its reservation remains until reconciliation. Reuse the same Idempotency-Key to recover a recorded order; contact support when the provider outcome remains unknown.

Quickstart

  1. Sign in and create a key under Account → API keys. The key is shown only once.
  2. Put it in the SATAVES_API_KEY environment variable (never in browser code or a public repository).
  3. Send your first request:
bash
export SATAVES_API_KEY="sk-sat-..."

curl https://sataveslabs.com/v1/chat/completions \
  -H "Authorization: Bearer $SATAVES_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4.1-mini",
    "messages": [{"role": "user", "content": "Write a haiku about the sea."}]
  }'

List the available models (no key needed):

bash
# Every model (public, no key needed)
curl https://sataveslabs.com/v1/models

# Only one kind: chat, ocr, image, video, tts, transcribe, embedding, music
curl "https://sataveslabs.com/v1/models?type=image"

# One model
curl https://sataveslabs.com/v1/models/anthropic/claude-sonnet-4.5

Authentication & scopes

Send the key in either header:

http
# OpenAI style (all endpoints)
Authorization: Bearer sk-sat-...

# Anthropic style (also accepted everywhere)
x-api-key: sk-sat-...

Choose a key's scopes when you create it; a request outside them gets 403. Account settings, sign-in, wallet top-ups, support and administration are not reachable with an API key. Virtual-number purchases require the numbers scope. A key cannot create other keys. Keys are accepted in headers, never session cookies or URL tokens.

ScopeGrants
modelsModels, prices, status, OpenAPI reference
chat/v1/chat/completions, /v1/messages
aiAI Studio: images, video, speech, OCR, text, music, embeddings, price quotes
toolsWebsite tools: downloads, converters, images, fonts, network, search
jobsCreate, poll and download background jobs
hubCivitai and Hugging Face
numbersBuy virtual numbers, receive SMS and manage your own orders
accountRead balance, ledger and API usage

Keys can expire, can be revoked at any time, and show when they were last used. Administrator accounts cannot create API keys.

Chat — OpenAI-compatible

POST /v1/chat/completions

Requests and responses use the Chat Completions format, with any chat model from /v1/models. Supported parameters:

  • model, messages (system, developer, user, assistant, tool)
  • tools, tool_choice (auto, none, required, named function)
  • stream, stream_options.include_usage
  • temperature, max_tokens / max_completion_tokens, reasoning_effort
  • Multi-part content: text, image_url (https or data:), file (PDF)

Not supported: response_format json_object/json_schema (refused with 400 — use tools for structured output; in LangChain pass method="function_calling") and n above 1. stop, top_p, seed and logprobs are ignored.

Streaming responses arrive as Server-Sent Events:

bash
curl https://sataveslabs.com/v1/chat/completions \
  -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -N -d '{
    "model": "anthropic/claude-sonnet-4.5",
    "stream": true,
    "stream_options": {"include_usage": true},
    "messages": [{"role": "user", "content": "Explain RAG in two sentences."}]
  }'

While a streamed answer is being produced the server sends keep-alive comments; the text then arrives in chunks once the model has answered. Non-streaming responses report the charge in billing and X-Api-Charged-* headers. Streamed charges appear in /v1/usage after completion; streaming headers cannot contain the final charge.

Image input for vision models:

python
client.chat.completions.create(
    model="anthropic/claude-sonnet-4.5",
    messages=[{"role": "user", "content": [
        {"type": "text", "text": "What is in this picture?"},
        {"type": "image_url", "image_url": {"url": "https://example.com/photo.jpg"}},
    ]}],
)

POST /v1/responses supports stateless text/image input and client-executed function/custom tools, including parallel calls. Send the full history with store=false. Hosted tools such as web_search are ignored; stored responses and server-side conversation state are unavailable.

python
# pip install openai
reply = client.responses.create(
    model="anthropic/claude-sonnet-4.5",
    store=False,
    instructions="You are a concise assistant.",
    input="Explain what a motion graphic is.",
)
print(reply.output_text)
# For tool loops, send the full input history plus output items and function_call_output.
# Stored conversations, previous_response_id and hosted tools are unavailable.

Messages — Anthropic-compatible

POST /v1/messages · POST /v1/messages/count_tokens

Supports system, text, image, document, tool_use and tool_result blocks, tools with input_schema, tool_choice, thinking and event streaming. Any chat model — Claude or not — works here. Anthropic SDKs take the base URL without /v1.

bash
curl https://sataveslabs.com/v1/messages \
  -H "x-api-key: $SATAVES_API_KEY" \
  -H "anthropic-version: 2023-06-01" -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-4.5",
    "max_tokens": 1024,
    "system": "You are a concise assistant.",
    "messages": [{"role": "user", "content": "Name three uses of embeddings."}]
  }'

Agent tools & SDKs

Use our models in coding tools and agent frameworks. Replace sk-sat-... with your key; choose a chat model with tools capability from the model list. Client versions differ; the SDK wire formats are tested, while each desktop harness still needs its own integration check.

Claude Code

Claude Code talks to the Anthropic-compatible endpoint. Give the base URL without /v1; Claude model names such as claude-sonnet-4-5-20250929 are mapped to the matching model automatically.

bash
export ANTHROPIC_BASE_URL="https://sataveslabs.com"
export ANTHROPIC_AUTH_TOKEN="sk-sat-..."
# Any chat model from /v1/models works, Claude or not:
export ANTHROPIC_MODEL="anthropic/claude-sonnet-4.5"
export ANTHROPIC_DEFAULT_SONNET_MODEL="anthropic/claude-sonnet-4.5"
export ANTHROPIC_DEFAULT_HAIKU_MODEL="anthropic/claude-haiku-4.5"
export ANTHROPIC_SMALL_FAST_MODEL="anthropic/claude-haiku-4.5"   # older Claude Code versions
claude

OpenAI Codex CLI

Add a custom provider that uses the stateless Responses wire format to ~/.codex/config.toml and keep the key in an environment variable.

toml
# ~/.codex/config.toml
model = "qwen/qwen3-coder"
model_provider = "sataves"

[model_providers.sataves]
name = "Sataves"
base_url = "https://sataveslabs.com/v1"
env_key = "SATAVES_API_KEY"
wire_api = "responses"

Cline / Roo Code / Kilo Code

Open Settings → API Provider, choose “OpenAI Compatible” and enter:

text
Base URL:  https://sataveslabs.com/v1
API Key:   sk-sat-...
Model ID:  anthropic/claude-sonnet-4.5
Supports images: on (for vision models)

Continue (VS Code / JetBrains)

Add the model to ~/.continue/config.yaml with the openai provider and our base URL.

yaml
models:
  - name: Claude Sonnet (Sataves)
    provider: openai
    model: anthropic/claude-sonnet-4.5
    apiBase: https://sataveslabs.com/v1
    apiKey: ${{ secrets.SATAVES_API_KEY }}
    roles: [chat, edit, apply]
  - name: Embeddings (Sataves)
    provider: openai
    model: openai/text-embedding-3-small
    apiBase: https://sataveslabs.com/v1
    apiKey: ${{ secrets.SATAVES_API_KEY }}
    roles: [embed]

Aider

Aider uses LiteLLM: put openai/ in front of the model id.

bash
export OPENAI_API_BASE="https://sataveslabs.com/v1"
export OPENAI_API_KEY="sk-sat-..."
aider --model openai/anthropic/claude-sonnet-4.5

OpenCode

Define an OpenAI-compatible provider in opencode.json.

json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "sataves": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Sataves",
      "options": { "baseURL": "https://sataveslabs.com/v1", "apiKey": "{env:SATAVES_API_KEY}" },
      "models": {
        "anthropic/claude-sonnet-4.5": { "name": "Claude Sonnet 4.5" },
        "qwen/qwen3-coder": { "name": "Qwen3 Coder" }
      }
    }
  }
}

LangChain / LangGraph

Point ChatOpenAI and OpenAIEmbeddings at our base URL; tools and LangGraph agents work unchanged.

python
# pip install langchain-openai
from langchain_openai import ChatOpenAI, OpenAIEmbeddings

llm = ChatOpenAI(base_url="https://sataveslabs.com/v1", api_key="sk-sat-...", model="anthropic/claude-sonnet-4.5")
embeddings = OpenAIEmbeddings(base_url="https://sataveslabs.com/v1", api_key="sk-sat-...",
                              model="openai/text-embedding-3-small", check_embedding_ctx_length=False)
print(llm.invoke("One sentence about Persian poetry.").content)

Vercel AI SDK

Create a provider with @ai-sdk/openai-compatible.

javascript
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { generateText } from "ai";

const sataves = createOpenAICompatible({
  name: "sataves", baseURL: "https://sataveslabs.com/v1", apiKey: process.env.SATAVES_API_KEY,
});
const { text } = await generateText({ model: sataves("anthropic/claude-sonnet-4.5"), prompt: "Hello!" });

Build your own tool-using agent

The agent loop: the model asks for a tool, you run it and send the result back until the model answers. You can also give the agent Sataves services (image generation, translation, …) as tools.

python
import json, os
from openai import OpenAI

client = OpenAI(base_url="https://sataveslabs.com/v1", api_key=os.environ["SATAVES_API_KEY"])

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]

def get_weather(city):
    return {"city": city, "temperature_c": 21, "sky": "clear"}

messages = [{"role": "user", "content": "Should I take an umbrella in Tehran today?"}]
while True:
    reply = client.chat.completions.create(model="anthropic/claude-sonnet-4.5", messages=messages, tools=tools)
    message = reply.choices[0].message
    messages.append(message.model_dump(exclude_none=True))
    if not message.tool_calls:
        print(message.content)
        break
    for call in message.tool_calls:
        result = get_weather(**json.loads(call.function.arguments))
        messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})

Embeddings

POST /v1/embeddings

Up to 100 inputs per request; optional dimensions, and encoding_format float or base64 (the official OpenAI SDK's default).

bash
curl https://sataveslabs.com/v1/embeddings \
  -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -d '{"model": "openai/text-embedding-3-small", "input": ["first text", "second text"]}'

AI Studio services

AI Studio services are the website's own endpoints under /api and accept the same key and the same model ids as /v1/models. Responses use the {ok, data} shape.

Image generation (with a price quote)

Image and video generation start with a quote: the exact price and spending ceiling are fixed before anything is charged.

bash
# 1) Ask for a price quote (nothing is charged)
curl https://sataveslabs.com/api/ai/generation/quote -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d '{
  "service": "ai:image", "model": "openai/gpt-image-1",
  "prompt": "A lighthouse at dawn, watercolor", "size": "1024x1024", "output_count": 1
}'
# -> {"ok": true, "data": {"quote_id": "...", "estimated_usd_micros": ..., "maximum_authorized_usd_micros": ...}}

# 2) Confirm it (add "accept_cost_estimate": true when the quote says requires_cost_estimate_acceptance)
curl -X POST https://sataveslabs.com/api/ai/generation/quotes/QUOTE_ID/confirm -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d '{}'

# 3) Generate with the same parameters and the quote id
curl https://sataveslabs.com/api/ai/image -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d '{
  "model": "openai/gpt-image-1", "prompt": "A lighthouse at dawn, watercolor",
  "size": "1024x1024", "output_count": 1, "quote_id": "QUOTE_ID"
}'
# -> {"ok": true, "data": {"image_url": "/api/ai/images/.../file", "billing": {...}}}

AI Color Studio

With the ai scope, upload a PNG, JPEG or WebP to POST /api/ai/color/assets (multipart file). Use its id as source. Choose mode colorize or recolor, with optional target, instructions, palette (hex colors) and reference asset id. Upload a mask with kind=mask: white selects the edited region; black preserves the original pixels. Mask dimensions must match the source.

Send the settings to POST /api/ai/color/quote; pricing uses the existing USD image policy and markup. Submit the returned id to POST /api/ai/color/generate, with accept_cost_estimate=true when required by the quote. Repeating that id retrieves the existing request without dispatching again. Check GET /api/ai/color/runs/{id} and GET /api/ai/color/runs for status and history. Assets and results belong to the authenticated account.

Video generation (asynchronous)

bash
# Quote and confirm exactly like images, with "service": "ai:video"
curl https://sataveslabs.com/api/ai/generation/quote -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d '{
  "service": "ai:video", "model": "google/veo-3.1-fast", "prompt": "Drone shot over a desert at sunset",
  "size": "1280x720", "aspect_ratio": "16:9", "duration_seconds": 8
}'
curl -X POST https://sataveslabs.com/api/ai/generation/quotes/QUOTE_ID/confirm -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d '{}'

curl https://sataveslabs.com/api/ai/video -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d '{
  "model": "google/veo-3.1-fast", "prompt": "Drone shot over a desert at sunset",
  "size": "1280x720", "aspect_ratio": "16:9", "duration_seconds": 8, "quote_id": "QUOTE_ID"
}'
# -> {"data": {"task_id": "...", "status": "processing"}}

# Poll, then download
curl https://sataveslabs.com/api/ai/video/status/TASK_ID -H "Authorization: Bearer $SATAVES_API_KEY"
curl -o video.mp4 https://sataveslabs.com/api/ai/video/content/TASK_ID -H "Authorization: Bearer $SATAVES_API_KEY"

Speech and transcription — OpenAI-compatible

POST /v1/audio/speech · POST /v1/audio/transcriptions

Works with the official OpenAI SDK. Speech comes back in the model's audio format (you can ask for mp3, wav or ogg); transcription returns json, text or verbose_json.

bash
# OpenAI-compatible: the response body is the audio file
curl https://sataveslabs.com/v1/audio/speech -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -d '{"model": "gemini-2.5-flash-tts", "input": "Hello from Sataves!", "voice": "Kore"}' -o hello.wav

curl https://sataveslabs.com/v1/audio/transcriptions -H "Authorization: Bearer $SATAVES_API_KEY" \
  -F "file=@meeting.mp3" -F "model=whisper-1" -F "response_format=json"

Speech, transcription and OCR with full options

bash
# Text to speech: list voices, then synthesize
curl "https://sataveslabs.com/api/ai/tts/model-voices?model=gemini-2.5-flash-tts" -H "Authorization: Bearer $SATAVES_API_KEY"
curl https://sataveslabs.com/api/ai/tts -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -d '{"model": "gemini-2.5-flash-tts", "text": "Hello from Sataves!", "voice": "Kore"}'
# -> {"data": {"audio_b64": "...", "format": "audio/wav", "audio_url": "/api/ai/audio/..."}}

# Speech to text (multipart upload)
curl https://sataveslabs.com/api/ai/transcribe -H "Authorization: Bearer $SATAVES_API_KEY" \
  -F "file=@meeting.mp3" -F "model=whisper-1"
# -> {"ok": true, "data": {"text": "...", "billing": {...}}}

# OCR on an image or PDF (any vision-capable model)
curl https://sataveslabs.com/api/ai/ocr -H "Authorization: Bearer $SATAVES_API_KEY" -F "file=@invoice.pdf" -F "model=anthropic/claude-sonnet-4.5"

Summaries, translation and rewriting

bash
curl https://sataveslabs.com/api/ai/summarize -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -d '{"text": "...long text...", "model": "openai/gpt-4.1-mini", "format": "key_points"}'

curl https://sataveslabs.com/api/ai/translate -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -d '{"text": "Good morning", "target": "Persian"}'

curl https://sataveslabs.com/api/ai/rewrite -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -d '{"text": "...", "model": "openai/gpt-4.1-mini"}'

Music

bash
# Music is generated into a private studio project
curl https://sataveslabs.com/api/studio/projects -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -d '{"title": "API music", "manifest": {"schema_version": 1, "assets": []}}'
# -> {"ok": true, "project": {"id": "PROJECT_ID", ...}}

curl https://sataveslabs.com/api/studio/projects/PROJECT_ID/creative/music -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -d '{"model": "google/lyria-3-clip-preview", "prompt": "Calm lo-fi beat with soft piano", "instrumental": true}'

# The new track appears in the project's media bin
curl https://sataveslabs.com/api/studio/projects/PROJECT_ID/assets -H "Authorization: Bearer $SATAVES_API_KEY"

Price lock (optional)

For text services, speech, OCR and studio generation you can lock the price first; without it the request still runs and is billed on actual usage.

bash
# Optional for text services, TTS, OCR and studio generation: lock the price first
curl https://sataveslabs.com/api/credits/studio/quote -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -d '{"path": "/ai/tts", "payload": {"model": "gemini-2.5-flash-tts", "text": "Hello", "voice": "Kore"}}'
curl -X POST https://sataveslabs.com/api/credits/studio/quotes/QUOTE_ID/confirm -H "Authorization: Bearer $SATAVES_API_KEY"

# Send the identical request with the quote headers
curl https://sataveslabs.com/api/ai/tts -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" \
  -H "X-Studio-Request: 1" -H "X-Studio-Quote-Id: QUOTE_ID" \
  -d '{"model": "gemini-2.5-flash-tts", "text": "Hello", "voice": "Kore"}'

A few models train on their inputs; the model list marks them with requires_training_consent. Send "training_consent": true to use them.

Motion graphics: create and download a GIF

python
import os, time, requests
root = "https://sataveslabs.com"
headers = {"Authorization": "Bearer " + os.environ["SATAVES_API_KEY"]}
def call(method, path, **kwargs):
    response = requests.request(method, root + path, headers=headers, timeout=300, **kwargs)
    response.raise_for_status()
    return response.json()["data"]
spec = {
    "mode": "template", "title": "Ideas in motion", "subtitle": "Your brand, animated",
    "primary": "#8b5cf6", "secondary": "#f472b6", "aspect": "16:9",
    "seconds": 4, "position": "bottom"
}
quote = call("POST", "/api/ai/motion/quote", json=spec)
# Local template is free. For mode=ai, review the returned quote then explicitly confirm it:
# call("POST", "/api/ai/generation/quotes/" + quote["quote"]["quote_id"] + "/confirm",
#      json={"accept_cost_estimate": True})
run = call("POST", "/api/ai/motion/generate", json={"id": quote["id"]})
while run["state"] not in ("completed", "failed", "render_failed", "uncertain"):
    time.sleep(5)
    run = call("GET", "/api/ai/motion/runs/" + run["id"])
if run["state"] == "completed":
    gif = requests.get(root + run["outputs"]["gif"], headers=headers, timeout=60)
    gif.raise_for_status()
    open("motion.gif", "wb").write(gif.content)
# An uncertain submission must never be blindly retried. Retry only local rendering when appropriate.

Website tools & background jobs

Website tools (format conversion, compression, image and PDF tools, fonts, QR, network and search) and long tasks (video translation and dubbing, subtitles, downloads) are available with the tools and jobs scopes. The full endpoint reference lists every path and input.

bash
# Long tasks (video translation, subtitles, downloads, conversions) run as jobs
curl https://sataveslabs.com/api/jobs -H "Authorization: Bearer $SATAVES_API_KEY"                      # your jobs
curl https://sataveslabs.com/api/jobs/JOB_ID -H "Authorization: Bearer $SATAVES_API_KEY"               # status and progress
curl -o result.zip https://sataveslabs.com/api/jobs/JOB_ID/file -H "Authorization: Bearer $SATAVES_API_KEY"

# Download from a link
curl https://sataveslabs.com/api/downloads/formats -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d '{"url": "https://www.youtube.com/watch?v=..."}'
curl https://sataveslabs.com/api/downloads/jobs -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d '{"url": "https://www.youtube.com/watch?v=...", "fmt": "best"}'
curl https://sataveslabs.com/api/downloads/jobs/JOB_ID -H "Authorization: Bearer $SATAVES_API_KEY"
curl -o video.mp4 https://sataveslabs.com/api/downloads/jobs/JOB_ID/file -H "Authorization: Bearer $SATAVES_API_KEY"

Media and image conversion

Discover targets and limits with GET /api/convert/formats. Send multipart/form-data fields file and target to POST /api/convert/media or POST /api/images/convert; a successful response is the output file. For background processing, use the existing tools job flow with media_convert or img_convert.

TypeOutputs
VideoMP4, MKV, WebM, MOV, AVI, MPEG / MPG, TS, M4V, 3GP
AudioMP3, M4A, WAV, OGG, FLAC, AAC, OPUS, AIFF, WMA
ImagesWebP, PNG, JPG, ICO, BMP, TIFF, GIF, AVIF, TGA, PPM, APNG
AnimationGIF, Animated WebP, APNG

Video animation exports are silent: input at most 60 seconds, output up to 960px wide at 12 fps. Image conversions to GIF, WebP or PNG/APNG preserve animation timing and looping; other targets save the first frame. Error responses are JSON; always inspect the response Content-Type.

Civitai & Hugging Face

Featured resources are listed at /v1/hub/catalog. Resolve supported Civitai models and Hugging Face Spaces by URL, then check compatibility and access before starting a background job. Indexed resources are not guaranteed executable; standalone Hugging Face model repositories are not Spaces.

bash
# Discover featured resources; this does not run inference
curl https://sataveslabs.com/v1/hub/catalog

# Resolve a supported resource and review availability first
curl https://sataveslabs.com/api/ai/hub/resolve -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d '{"url":"https://civitai.com/models/4201"}'

# Save the exact Civitai inputs you intend to submit
printf '%s' '{"model_name":"MODEL_NAME","model_urn":"VERIFIED_AIR_URN","prompt":"portrait, soft light"}' > civitai-input.json
curl https://sataveslabs.com/api/ai/hub/civitai/estimate -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d @civitai-input.json
# Review quote_id, estimated_micros, maximum_micros, expires_at and can_start.
# Amounts are micro-USD: 1000000 = $1. A quote reserves nothing yet.
# After approving the displayed price, set SATAVES_HUB_QUOTE_ID to that quote_id.
# jq is required. Keep the quoted inputs unchanged; reuse the retry key after a timeout.
jq --arg q "$SATAVES_HUB_QUOTE_ID" '. + {quote_id:$q,accept_cost_estimate:true,idempotency_key:"civitai-001"}' civitai-input.json > civitai-run.json
curl https://sataveslabs.com/api/ai/hub/civitai/runs -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d @civitai-run.json

# Hugging Face: discover the real endpoint, parameter names and schema hash
curl https://sataveslabs.com/api/ai/hub/research/discover -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d '{"kind":"space","repo_id":"SPACE_OWNER/SPACE_NAME"}'
printf '%s' '{"kind":"space","repo_id":"SPACE_OWNER/SPACE_NAME","endpoint":"ENDPOINT_FROM_DISCOVER","values":{"INPUT_NAME_FROM_DISCOVER":"a red fox"},"options":{},"schema_hash":"SCHEMA_HASH_FROM_DISCOVER","consent":true}' > space-input.json
curl https://sataveslabs.com/api/ai/hub/research/quote -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d @space-input.json
# Review this quote, then set SATAVES_HUB_QUOTE_ID to its quote_id.
jq --arg q "$SATAVES_HUB_QUOTE_ID" '. + {quote_id:$q,accept_cost_estimate:true,idempotency_key:"space-001"}' space-input.json > space-run.json
curl https://sataveslabs.com/api/ai/hub/research/runs -H "Authorization: Bearer $SATAVES_API_KEY" -H "Content-Type: application/json" -d @space-run.json

# Poll and download using the same account/key
curl https://sataveslabs.com/api/jobs/JOB_ID -H "Authorization: Bearer $SATAVES_API_KEY"
curl -O https://sataveslabs.com/api/ai/hub/runs/JOB_ID/files/FILE_NAME -H "Authorization: Bearer $SATAVES_API_KEY"
# Final result.billing reports charged_micros, refunded_micros,
# price_estimated and cost_basis. Async API usage updates after settlement.

Managed Space execution

Check GET /api/ai/hub/research/execution-options?repo_id=OWNER/SPACE for approved routes. execution_mode="host" uses the original host, with Sataves credentials only for an approved exact repository. "managed" starts a reviewed private copy on approved CPU/GPU hardware and pauses it after execution. Keep the same execution_mode in discover, quote and runs.

The embedded native interface uses the visitor’s browser account, independently of server billing. API runs require reserved USD credit; compute charges are estimates with the existing pricing markup. ZeroGPU quota, queues, provider credit, licenses, external secrets and source review can block execution. For hf_source_changed_review_required or hf_execution_plan_changed_requote, recheck compatibility and obtain a new quote before retrying.

Hub endpoints and execution flow

Use a key with hub scope; also enable jobs for polling and account for balance and usage. Runs require a verified account.

OperationEndpoint
Featured resourcesGET /v1/hub/catalog
Resolve resource and versionPOST /api/ai/hub/resolve
Estimate Civitai with selected settingsPOST /api/ai/hub/civitai/estimate
Submit Civitai runPOST /api/ai/hub/civitai/runs
Discover Space inputs and availabilityPOST /api/ai/hub/research/discover
Prepare SpacePOST /api/ai/hub/research/prepare
Upload input: multipart field filePOST /api/ai/hub/research/upload
Quote Space or hosted-model execution in USDPOST /api/ai/hub/research/quote
Submit Space runPOST /api/ai/hub/research/runs
Hub historyGET /api/ai/hub/research/runs
Poll job stateGET /api/jobs/{job_id}
Download output with the same keyGET /api/ai/hub/runs/{job_id}/files/{name}

For Spaces, use kind: space and obtain repo_id, endpoint name, inputs and that endpoint’s schema_hash from discover. consent accepts the resource terms. If its schema changes, rediscover and review the inputs. A sleeping Space or one without a compatible API may not run; prepare tracks readiness as a background job.

Pricing, cost limits and retries

Quote every run with the exact inputs. quote_id is bound to the account, resource, endpoint and settings, and expires. estimated_micros is the expected charge; maximum_micros is the customer's authorized limit. One million micro-USD equals $1. Submit quote_id and accept_cost_estimate: true when accepting an estimated price. Changed inputs require a new quote.

After execution, verified usage or the accepted estimate determines the charge; unused reserved funds are released. Public Spaces are not automatically free. Queue and HTTP waiting time are not GPU usage meters. Customer charges never exceed the approved limit. The final result identifies billing.price_estimated and billing.cost_basis.

Check current service policies in /v1/pricing under open-ai-hub and open-ai-hub:research. A public Space is not a promise of permanently free execution. Background charges may settle after submission; zero in the initial /v1/usage entry does not guarantee a free run. Reconcile final charges against job results and the account ledger.

202 means accepted, not successful generation. Keep the body idempotency_key when retrying the same submission, save the job ID and poll with a delay. Resolve access, changed-schema or unavailable-resource errors before resubmitting; uploaded inputs must belong to the same account.

Virtual numbers & SMS

Create a key with the numbers scope; existing keys do not gain this new permission automatically. Browse services and offers for countries, operators and stock, then confirm the website retail price when purchasing. Orders and SMS belong to the account behind the key.

OperationEndpoint
Capabilities and price unitsGET /api/numbers/capabilities
Service catalogGET /api/numbers/platforms
Countries, operators, stock and pricesGET /api/numbers/offers?platform=telegram&country=England
Purchase with a confirmed pricePOST /api/numbers/purchase
My order historyGET /api/numbers/orders
SMS code/text, status and expiryGET /api/numbers/orders/{key}/status
Cancel, ban or finishPOST /api/numbers/orders/{key}/cancel | ban | finish

For purchase, send platform, pid and sid from the chosen offer. With USD_CREDIT, price must equal price_usd_micros (1 USD = 1,000,000 micros). With TOMAN, price is the offer's Toman amount. Sufficient balance is required and the price is checked again at purchase.

Idempotency-Key is required for purchases (8–128 characters: letters, digits, _, ., : or -). Retry a disconnected request with the same key and body to avoid duplicate numbers and charges. Reusing a key with a different body returns 409. For purchase_in_progress or purchase_outcome_unknown, inspect your orders; do not blindly buy again with a new key.

python
import os, time, requests
root = "https://sataveslabs.com"
headers = {"Authorization": "Bearer " + os.environ["SATAVES_API_KEY"]}
def call(method, path, **kwargs):
    request_headers = kwargs.pop("headers", headers)
    r = requests.request(method, root + path, headers=request_headers, timeout=60, **kwargs)
    r.raise_for_status()
    result = r.json()
    if not result["ok"]:
        raise RuntimeError(result["data"].get("error", "request_failed"))
    return result["data"]

offers = call("GET", "/api/numbers/offers", params={"platform": "telegram"})
if offers.get("partial") or not offers["items"]:
    raise RuntimeError("Catalog warming or out of stock; retry browsing later")
offer = offers["items"][0]  # Select the country/operator you actually want.
assert offer["billing_currency"] == "USD_CREDIT"
price = offer["price_usd_micros"]
# Set a deliberate budget before running. This example buys a real number.
assert price <= int(os.environ["MAX_NUMBER_PRICE_MICROS"])
# Save this unique purchase id; reuse it and the SAME body on network retries.
purchase_id = os.environ["NUMBER_PURCHASE_ID"]  # e.g. telegram-order-20261025-001
body = {"pid": offer["pid"], "sid": offer["sid"], "platform": "telegram", "price": price}
purchase = call("POST", "/api/numbers/purchase", json=body,
                headers={**headers, "Idempotency-Key": purchase_id})
key = purchase["order"]["key"]
for _ in range(60):
    status = call("GET", "/api/numbers/orders/" + key + "/status")
    if status.get("code") or status["state"] in ("completed", "canceled", "banned"):
        print(status)  # code, sms text/sender, expiry and state when available
        break
    time.sleep(5)
# Actions, when appropriate (each can be refused by the provider):
# call("POST", "/api/numbers/orders/" + key + "/finish")
# call("POST", "/api/numbers/orders/" + key + "/cancel")
# call("POST", "/api/numbers/orders/" + key + "/ban")

Poll every 5 seconds. Cancellation or banning before a code arrives can refund only after provider confirmation; pending means confirmation is still outstanding. Finishing does not refund. Check ok:false results as well. API errors include 402 insufficient balance, 404 order not owned/found, 409 price change/code already received and 503 provider confirmation unavailable.

Current coverage is one-time activation numbers. Long-term rentals, paid re-buy of a specific number and upstream account settings are not exposed. The legacy repeat route returns repeat_not_supported; poll status for additional SMS. New purchase charges appear in X-Api-Charged-* headers and API usage; replaying a purchase adds no new charge.

Models & list prices

This table is read live from GET /v1/models. Prices are in USD: tokens per million, other units as named. Models with pricing.free have no usage charge. The exact charge of each request is returned with its response.

Loading live data…

Service prices & billing

  • A spending ceiling is held before each request; afterwards only actual usage is charged and the rest of the hold is released.
  • Confirmed failures release unused holds. An uncertain number purchase keeps its hold until reconciled; do not submit another purchase. If a client disconnects after generation starts, completed work can still be billed; check the ledger before retrying.
  • A charge never exceeds the confirmed ceiling.

Loading live data…

Account, balance & usage

bash
curl https://sataveslabs.com/v1/account -H "Authorization: Bearer $SATAVES_API_KEY"     # balance, this key, rate limits
curl "https://sataveslabs.com/v1/usage?days=7&key=current" -H "Authorization: Bearer $SATAVES_API_KEY"   # requests and charges
curl https://sataveslabs.com/v1/pricing                     # price list (public)
curl https://sataveslabs.com/v1/status                      # API status and model counts (public)

/v1/usage lists keyed requests and the charges reported by those requests; key can be all, current or a key id. Background work can settle later, so zero in a request log does not mean a job is free. Use the account ledger and job billing for final charges.

Full endpoint reference

Every endpoint an API key can call, with its scope. Exact inputs and outputs are in the OpenAPI document: /v1/openapi.json

Loading live data…

Errors & rate limits

json
// /v1/chat/completions, /v1/embeddings and other /v1 endpoints (OpenAI shape)
{"error": {"message": "Your balance is too low for this request.", "type": "insufficient_quota", "code": "insufficient_balance"}}

// /v1/messages (Anthropic shape)
{"type": "error", "error": {"type": "billing_error", "message": "Your balance is too low for this request."}}

// /api/... website endpoints
{"ok": false, "error": "generation_quote_required", "detail": "generation_quote_required"}
HTTPCodeMeaning
400invalid_request · unsupported_contentInvalid request or parameter
401invalid_api_key · missing_tokenKey invalid, revoked or expired
402insufficient_balanceBalance too low; top up your account
403api_key_scope_missing · api_key_endpoint_not_allowed · model_disabledThe key lacks the scope, or the endpoint is not open to keys
404model_not_foundThe model does not exist or is a different kind
409generation_quote_required · studio_quote_requiredA quote is required or does not match the request
429rate_limitedToo many requests; retry with backoff
502 / 503upstream_error · service_unavailableThe model did not answer; retry or pick another model

The default rate limit is 120 requests per minute on /v1 (your exact limits are in /v1/account). Retry 429 responses with exponential backoff.

Data & key safety

  • We do not offer models whose providers train on your requests, except models marked requires_training_consent, which run only when that request opts in.
  • Keep keys on servers only — never in mobile apps or browser code.
  • Use a separate key with the fewest scopes for each app, and revoke a leaked key immediately.