Menu
Saanora Platform documentation
Send a record, such as a support ticket, an agent conversation or an invoice, together with typed questions about it. Clara returns a probability for every option you defined, for every question, in one call. You call it over HTTPS with one API key and pay from prepaid credit.
What the API does
You describe a decision as questions with fixed options. Clara reads the record and answers each question with probabilities over those options. It never writes free text: every answer is one of your options, and the probabilities always sum to 1. That makes the result safe to branch on in code.
There are three question types:
| Type | Use it for | You define (criteria) | You get back |
|---|---|---|---|
noul | Yes/no questions | Optional: {"true": ..., "false": ...} (or yes/no keys) describing each side. Optional threshold on the question, a number from 0 to 1. | noul: the probability of yes. With a threshold, also threshold and decision (true when noul is at least the threshold). |
choice | Picking one option from a set | An object of option id → short description, 2 to 255 options. | choice (the most likely option id), probabilities for every option and confidence (0 for a uniform spread, 1 for certain). |
score | Rating on an ordered scale | An array of levels, lowest first, at least 2. | score (the expected level index), probabilities and legend keyed by level index, and confidence (the most likely level's probability). |
A typical integration acts on its own when a probability is high, sends the middle band to a person and declines when it is low. One request can carry 1 to 32 questions on Tier 1 and 64 from Tier 2.
Your first request
You need an account, credit and an API key. The Quickstart covers all three. Then keep the key in an environment variable on your server:
export SAANORA_API_KEY="sk_sa_..."This request asks two questions about one customer message: a yes/no question with a threshold, and a choice between three options.
curl https://api.saanora.com/v1/decisions \
-H "Authorization: Bearer $SAANORA_API_KEY" \
-H "Content-Type: application/json" \
--max-time 120 \
-d '{
"model": "clara-1",
"state": "Order A-1042, delivered Oct 5. Customer writes: the blender arrived with a cracked jar. I want my money back, not a new one.",
"questions": {
"damaged": {
"type": "noul",
"instructions": "Does the customer say the item arrived damaged?",
"threshold": 0.9
},
"wants": {
"type": "choice",
"instructions": "What does the customer want?",
"criteria": {
"refund": "Their money back",
"replacement": "A new item sent to them",
"other": "Anything else"
}
}
}
}'The response carries one answer per question, keyed by the ids you chose (damaged, wants):
{
"id": "dec_3b9e71c04f2a8d65e1c07b94",
"object": "decision",
"created": 1792491003,
"model": "clara-1",
"mode": "fast",
"answers": {
"damaged": { "type": "noul", "noul": 0.98, "threshold": 0.9, "decision": true },
"wants": {
"type": "choice",
"choice": "refund",
"probabilities": { "refund": 0.94, "replacement": 0.04, "other": 0.02 },
"confidence": 0.91
}
},
"usage": { "input_tokens": 170, "decisions": 2, "cost_usd": 0.000085 },
"latency_ms": 88.7
}| Field | Meaning |
|---|---|
id | The decision id, starting with dec_. |
object | Always "decision". |
created | When the decision was made, in Unix seconds. |
model, mode | The model that answered and the mode it ran in: fast (the default) or consistent. |
answers | One answer per question, in the shape for its type. Here damaged.noul is 0.98, above the 0.9 threshold, so decision is true. wants.choice is refund with probability 0.94 out of three options, so confidence is (0.94 − 1/3) / (1 − 1/3) = 0.91. |
usage.input_tokens | Billed input tokens. The same number counts toward your tokens-per-minute limit. |
usage.decisions | The number of questions answered. |
usage.cost_usd | Exactly what was deducted from your credit. |
latency_ms | Time spent in the model, in milliseconds. The saanora-processing-ms header has the total time in the platform. |
503 model_warming_up, never charged, with a Retry-After header saying how many seconds to wait. Retry after that wait, and keep a client timeout of 120 seconds. Later requests are fast. The retry loop on Errors handles it for you.How a request flows
Every call to POST /v1/decisions (or POST /v1/systemone) goes through the same six steps. Credit moves at two of them: a hold before the model runs and the exact charge after it.
- 01API keyIdentifies your project and organization
- 02RequestValidated and checked against your limits
- 03HoldWorst-case cost reserved from credit
- 04ModelClara answers every question
- 05Exact chargeOnly the tokens read are billed
- 06ResponseAnswers, usage and headers
| Step | What happens | If it fails |
|---|---|---|
| 1. API key | The gateway reads the key from Authorization: Bearer sk_sa_... (or X-API-Key) and finds its project and organization. Key lookups are cached for 60 seconds, so a revoked key stops working within 60 seconds. | 401 missing_api_key, 401 invalid_api_key, 503 auth_unavailable; 402 insufficient_credit on Tier 0, which is sign-up only (API access starts at Tier 1) |
| 2. Request | The body must be valid JSON of at most 1 MB with a model, a state and valid questions within your tier's question limit. Then your organization's requests-per-minute and tokens-per-minute limits and the project's monthly spend limit are checked. | 413 request_too_large; 400 invalid_json, missing_model, missing_state, missing_questions or wrong_endpoint; 404 model_not_found; 422 too_many_questions, invalid_question_type, invalid_criteria or invalid_mode; 429 rate_limit_exceeded (with Retry-After); 429 project_spend_limit; 503 catalog_unavailable |
| 3. Hold | A hold covering the worst-case cost of the request is placed on your organization's credit. If the credit cannot cover it, nothing runs. | 402 insufficient_credit, 503 billing_unavailable |
| 4. Model | Clara reads the record and answers every question, in fast or consistent mode. | 503 model_warming_up while consistent mode starts after a quiet period (with Retry-After), 502 model_unavailable, 400 or 422 invalid_request when the model rejects the request |
| 5. Exact charge | Only the exact cost is deducted: billed input tokens at the model's input price. Output costs $0 and there is no per-decision fee. The rest of the hold returns to your balance. | Not charged if the model step failed. |
| 6. Response | You receive the answers and usage, plus headers: x-request-id, your remaining requests and tokens (x-ratelimit-*) and saanora-processing-ms. | Errors carry x-request-id too. |
402 insufficient_credit while your balance is still above what it would finally have cost: keep some headroom.Core objects
| Object | What it is | Good to know |
|---|---|---|
| Organization | Owns the credit, the members and the rate-limit tier. Every user gets a personal organization when they sign up. | Invite teammates by email. Each member has one role: owner, admin, developer, billing or reader. An organization always keeps at least one owner. |
| Project | Groups API keys, usage and an optional monthly spend limit (UTC month). New organizations start with a Default project. | Projects share the organization's credit and rate limits. Use one per environment or product. Archiving a project revokes its keys. |
| API key | A secret starting with sk_sa_ that authenticates requests. It belongs to exactly one project. | Shown once when created and stored only as a SHA-256 hash. Keep it on your server. A revoked key stops working within 60 seconds. |
| Model | What answers the request, chosen per request with the model field. | All models use the same keys, credit and limits. GET /v1/models lists the live ones. |
| Credit | The organization's prepaid balance in US dollars. | Top-ups start at $5. Credit never expires and is shared by all projects. Polar is the merchant of record and handles checkout, taxes, receipts and invoices. |
| Tier | The organization's limits: requests per minute, tokens per minute and questions per request. | New organizations start on Tier 0, which is sign-up only: no API access. Your first top-up, from $5, moves you to Tier 1 at once (300 requests and 300K tokens per minute, 32 questions per request). Higher tiers apply automatically the moment both your total paid and the days since your first payment reach the next tier's bar. |
state and questions you send are processed in memory and never written to the database, so they are never used for training. Saanora stores only request metadata such as time, project, key, model, token count, cost and request id. See Data handling.Base URL and endpoints
All endpoints are served from https://api.saanora.com over HTTPS. Requests and responses are JSON.
| Endpoint | Use it for |
|---|---|
POST /v1/decisions | Ask a model questions about a record. model is required. |
POST /v1/systemone | The same request body for clients written for the open System One format, such as JevBench. model is optional and defaults to clara-1. |
GET /v1/models | List the models your key can call right now. |
Conventions
- Authentication: send
Authorization: Bearer sk_sa_....X-API-Key: sk_sa_...is also accepted. See Authentication. - Size: request bodies up to 1 MB. The record (
state) is a string or a JSON object (objects are rendered compactly) of up to 16K tokens; longer records are shortened in the middle. - Mode: set
"mode": "consistent"in the body or?mode=consistenton the URL. The default isfast. - Request ids: every response, including errors, has an
x-request-idheader. Include it when you contact support. - Errors: one shape for every error. Branch on
error.code;paramnames the offending field when there is one. See Errors.
{
"error": {
"type": "authentication_error",
"code": "invalid_api_key",
"message": "invalid or revoked API key",
"param": null
},
"request_id": "req_5c1e9a0b7d3f42e8a61b9c04"
}Models
| Model | What it does | Status | Input / 1M | Output / 1M |
|---|---|---|---|---|
Clara clara-1 | Typed decisions: a probability for every option you define | Live | $0.50 | $0 |
Mark mark-1 | Language model behind Saanora Chat | Coming soon | at launch | at launch |
Clara (clara-1) is Saanora's frontier decision model. It scores 93.55% on AgentDecisionBench tool routing and 94.9% on a held-out customer-service yes/no set, answers five questions about one record in about 0.1 s, and returns 0% malformed answers. It works in English only.
Mark (mark-1), the language model behind Saanora Chat, is coming soon. Until it opens, requests to it return 404 model_not_found.
To see which models your key can call, list them:
curl https://api.saanora.com/v1/models \
-H "Authorization: Bearer $SAANORA_API_KEY"{
"object": "list",
"data": [
{ "id": "clara-1", "object": "model", "owned_by": "saanora", "kind": "decision", "status": "live" }
]
}Benchmarks, specifications and known limitations are on Models. Before you automate on Clara's answers, check them against a few hundred of your own labelled records.
What a request costs
Clara costs $0.50 per 1M input tokens. Output is $0 and there is no per-decision fee, so a request costs usage.input_tokens × $0.50 / 1,000,000. The example above read 170 tokens and cost $0.000085. The smallest top-up, $5, buys 10M input tokens, about 58,000 requests like it.
The mode changes what is billed:
fast(the default) reads the record once for all questions: you pay for the record plus each question once. Lowest latency and cost.consistentreads the record again with each question, so its answers hold steadier when options change or a question is reworded. It bills the tokens it reads, roughly the record times the number of questions, and they count toward your tokens-per-minute limit. On JevBench-mini it scores 83.6 against 81.8 forfast.
Where to go next
| If you want to | Read |
|---|---|
| Make your first request step by step | Quickstart |
| Send, store, rotate or revoke API keys | Authentication |
| Look up every field, header and answer shape | API reference |
| Compare models, benchmarks and limitations | Models |
| Copy a complete recipe for triage, routing, moderation or invoices | Guides |
| Write better questions, pick thresholds and choose a mode | Best practices |
| Handle an error code or retry safely | Errors |
| See your limits and how tiers rise | Rate limits |
| Invite your team, separate environments, cap spend | Organizations and projects |
| Add credit, find invoices, understand charges | Billing and credit |
| Know exactly what is stored about each request | Data handling |
x-request-id of any request you have a question about.