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.
https://sataveslabs.com/v1Resumen
Una clave, más allá del catálogo de modelos
Una clave API para modelos, flujos de AI Studio, herramientas web compatibles, números virtuales y el Hub.
- Servicios de AI Studio
- 25
- Spaces de Hugging Face
- 1.515.116
- Modelos de Civitai indexados
- 42.013
Descubre Spaces de Hugging Face y recursos de Civitai por API. Ejecuta recursos compatibles tras comprobar acceso, disponibilidad y precios.
Los recursos del Hub se cuentan aparte de los modelos API; no todos tienen una API de ejecución compatible. Fecha del catálogo del Hub: .
- 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
| Endpoint | Supported features |
|---|---|
| Chat Completions | Model-supported text, images and function tools; buffered streaming |
| Messages | Anthropic message and tool round trips; buffered streaming |
| Responses | Stateless: send history with each request. Hosted tools are not executed. |
| Structured output | JSON Schema output is unsupported and rejected explicitly. |
| Discurso | AAC, FLAC and PCM are unsupported; check the route contract for supported output formats. |
Tutorials are integration examples, not certification de 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
- Sign in and create a key under Account → API keys. The key is shown only once.
- Put it in the SATAVES_API_KEY environment variable (never in browser code or a public repository).
- Send your first request:
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):
# 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.5Authentication & scopes
Send the key in either header:
# 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.
| Alcance | Grants |
|---|---|
models | Models, prices, status, OpenAPI reference |
chat | /v1/chat/completions, /v1/messages |
ai | AI Studio: images, video, speech, OCR, text, music, embeddings, price quotes |
tools | Website tools: downloads, converters, images, fonts, network, search |
jobs | Create, poll and download background jobs |
hub | Civitai and Hugging Face |
numbers | Buy virtual numbers, receive SMS and manage your own orders |
account | Read 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_usagetemperature,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:
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:
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.
# 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.
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
Usar 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.
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
claudeOpenAI 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.
# ~/.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:
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.
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.
export OPENAI_API_BASE="https://sataveslabs.com/v1"
export OPENAI_API_KEY="sk-sat-..."
aider --model openai/anthropic/claude-sonnet-4.5OpenCode
Define an OpenAI-compatible provider in opencode.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.
# 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.
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.
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)})Incrustaciones
POST /v1/embeddings
Up to 100 inputs per request; optional dimensions, and encoding_format float or base64 (the official OpenAI SDK's default).
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.
# 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)
# 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.
# 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
# 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
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"}'Música
# 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.
# 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
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.
# 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.
| Tipo | Salidas |
|---|---|
| Video | MP4, MKV, WebM, MOV, AVI, MPEG / MPG, TS, M4V, 3GP |
| Audio | MP3, M4A, WAV, OGG, FLAC, AAC, OPUS, AIFF, WMA |
| Images | WebP, PNG, JPG, ICO, BMP, TIFF, GIF, AVIF, TGA, PPM, APNG |
| Animation | GIF, 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 y 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.
# 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 de 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
Usar a key with hub scope; also enable jobs for polling and account for balance and usage. Runs require a verified account.
| Operation | Endpoint |
|---|---|
| Featured resources | GET /v1/hub/catalog |
| Resolve resource and version | POST /api/ai/hub/resolve |
| Estimate Civitai with selected settings | POST /api/ai/hub/civitai/estimate |
| Submit Civitai run | POST /api/ai/hub/civitai/runs |
| Discover Space inputs and availability | POST /api/ai/hub/research/discover |
| Prepare Space | POST /api/ai/hub/research/prepare |
| Upload input: multipart field file | POST /api/ai/hub/research/upload |
| Quote Space or hosted-model execution in USD | POST /api/ai/hub/research/quote |
| Submit Space run | POST /api/ai/hub/research/runs |
| Hub history | GET /api/ai/hub/research/runs |
| Poll job state | GET /api/jobs/{job_id} |
| Download output with the same key | GET /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 de 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.
| Operation | Endpoint |
|---|---|
| Capabilities and price units | GET /api/numbers/capabilities |
| Service catalog | GET /api/numbers/platforms |
| Countries, operators, stock and prices | GET /api/numbers/offers?platform=telegram&country=England |
| Purchase with a confirmed price | POST /api/numbers/purchase |
| My order history | GET /api/numbers/orders |
| SMS code/text, status and expiry | GET /api/numbers/orders/{key}/status |
| Cancel, ban or finish | POST /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.
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 de 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 de 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 de 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
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
// /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"}| HTTP | Código | Meaning |
|---|---|---|
| 400 | invalid_request · unsupported_content | Invalid request or parameter |
| 401 | invalid_api_key · missing_token | Key invalid, revoked or expired |
| 402 | insufficient_balance | Balance too low; top up your account |
| 403 | api_key_scope_missing · api_key_endpoint_not_allowed · model_disabled | The key lacks the scope, or the endpoint is not open to keys |
| 404 | model_not_found | The model does not exist or is a different kind |
| 409 | generation_quote_required · studio_quote_required | A quote is required or does not match the request |
| 429 | rate_limited | Too many requests; retry with backoff |
| 502 / 503 | upstream_error · service_unavailable | The 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.
- Usar a separate key with the fewest scopes for each app, and revoke a leaked key immediately.