API Documentation
Docs & Integrations
faborapi is a low-cost AI API platform: one sk-fabor- key gives you 40 models from Anthropic, OpenAI, Google and xAI, for up to 71% less. Fully OpenAI-compatible — pay per token from your prepaid balance.
Base URL
https://faborapi.com/v1Get an API key →Authentication
Send your key in either header: Authorization: Bearer sk-fabor-… or x-api-key: sk-fabor-….
Your full key is shown only once, when you create it. We store only a fingerprint, so a lost key cannot be recovered: create a new one.
A revoked key is refused immediately with a 401 error.
Endpoints
POST /v1/chat/completions — chat completion, standard or streaming (OpenAI format). Requires a key.
GET /v1/models — list of available models. No key required.
No other endpoints are available yet (no embeddings, images or audio).
Choosing a model
The model you want is named in the model field of the JSON body of each request — nothing else is needed:
POST https://faborapi.com/v1/chat/completions
Authorization: Bearer $FABOR_API_KEY
Content-Type: application/json
{
"model": "claude-sonnet-4-5",
"messages": [
{"role": "user", "content": "Hello!"}
]
}Use the exact model ID from the Models & prices list below — character for character. Each one has a copy button, so you never have to type it.
No provider or group to pick. Behind the scenes models belong to groups (Anthropic, OpenAI, Gemini, Grok), but you never choose one: we route your request to the right group automatically based on the model name.
Unknown or disabled name → 404. A typo like claud-sonnet-4-5, or a model that was disabled, is refused with:
{
"error": {
"message": "Model 'claud-sonnet-4-5' not found",
"type": "invalid_request_error"
}
}Same name everywhere. In Cursor, VS Code (Continue or Roo Code) or any other tool, the “model name / model ID” field takes exactly the same value as the model field here — see the Editor setup section.
One key gives access to every model in the catalog. You only pay for the model you actually call, at the price shown in the list.
Quickstart
curl https://faborapi.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $FABOR_API_KEY" \
-d '{
"model": "claude-sonnet-4-5",
"messages": [{"role": "user", "content": "Hello!"}]
}'The response is the standard OpenAI chat.completion object, including a usage field with token counts.
Streaming
Add "stream": true to receive server-sent events. The last chunk before [DONE] always contains usage (we enable it for you).
curl https://faborapi.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $FABOR_API_KEY" \
-d '{
"model": "claude-sonnet-4-5",
"stream": true,
"messages": [{"role": "user", "content": "Hello!"}]
}'data: {"object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":""},"finish_reason":"stop"}]}
data: {"object":"chat.completion.chunk","choices":[],"usage":{"prompt_tokens":281,"completion_tokens":9,"prompt_tokens_details":{"cached_tokens":60,"cache_creation_tokens":3}}}
data: [DONE]Files (PDF, images, documents)
There are two ways to send a file together with your message. Both produce the same result — pick whichever fits your workflow.
Option 1 — Inline (single call). Encode the file as base64 and put it directly in the message content. One request to POST /v1/chat/completions, no upload step. Best for one-off requests.
Option 2 — Upload once, reuse. Upload the file with POST /v1/files (multipart, max 20 MB, private to your account, free storage), then reference its id in any message. faborapi injects the file content before calling the model. Best when the same file is used across several requests.
Option 1: send the file inline
curl https://faborapi.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $FABOR_API_KEY" \
-d '{
"model": "claude-sonnet-4-5",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Turn this document into a 10-question quiz."},
{"type": "file", "file": {"filename": "course.pdf", "file_data": "data:application/pdf;base64,JVBERi0x..."}}
]
}]
}'Option 2: upload once, then reference the file_id
curl https://faborapi.com/v1/files \
-H "Authorization: Bearer $FABOR_API_KEY" \
-F purpose="user_data" \
-F file="@course.pdf"
# → {"id": "file-8f3c...", "object": "file", "filename": "course.pdf", "bytes": 482113, ...}curl https://faborapi.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $FABOR_API_KEY" \
-d '{
"model": "claude-sonnet-4-5",
"messages": [{
"role": "user",
"content": [
{"type": "file", "file": {"file_id": "file-8f3c..."}},
{"type": "text", "text": "Turn this document into a 10-question quiz."}
]
}]
}'List your files with GET /v1/files, delete with DELETE /v1/files/{id}. All three content shapes are accepted:
// Document (PDF, DOCX, TXT...) — inline base64
{"type": "file", "file": {"filename": "course.pdf", "file_data": "data:application/pdf;base64,JVBERi0x..."}}
// Image — inline base64
{"type": "image_url", "image_url": {"url": "data:image/png;base64,iVBORw0..."}}
// After an upload — reference the file_id (faborapi injects the content)
{"type": "file", "file": {"file_id": "file-8f3c..."}}The model must accept files. Recent GPT, Claude, Gemini and Grok models read PDFs and images; a text-only model returns an upstream error, which is not charged.
File contents count as input tokens for the model you call.
Models & prices
curl https://faborapi.com/v1/modelsLoading models…
Billing
Each successful request is charged from the token counts returned in usage, in four parts:
- Input — prompt tokens not served from cache.
- Output — completion tokens, including reasoning tokens of thinking models.
- Cache read —
cached_tokens. - Cache write —
cache_creation_tokens.
For models with a long-request tier, the whole request is priced at the multiplier shown when prompt tokens exceed the threshold.
Token counts can be higher than your text alone: some models add hidden system tokens and reasoning tokens. These are counted as reported.
The cost is deducted after the response. A request is refused (402) when your balance is 0 or lower. Failed requests cost nothing.
Every request appears on the Usage page.
Errors
All errors use the same JSON shape:
{
"error": {
"message": "Insufficient balance. Please top up your faborapi account.",
"type": "insufficient_quota"
}
}Errors returned by faborapi
| HTTP | type | message | Meaning |
|---|---|---|---|
400 | invalid_request_error | Invalid JSON body · Missing 'model' | The request body is not valid JSON, or the model field is missing. |
401 | authentication_error | Invalid API key · Invalid or revoked API key | No key, a malformed key, an unknown key, or a revoked key. |
402 | insufficient_quota | Insufficient balance. Please top up your faborapi account. | Your balance is 0 or lower. Top up to continue. |
404 | invalid_request_error | Model '<id>' not found | The model does not exist in the catalog or is disabled. |
502 | server_error | Upstream unreachable | The model provider could not be reached. Retry later. |
503 | server_error | Model temporarily unavailable | The model exists but is not available right now. |
Errors passed through from the model provider
When the provider rejects a request, we return its HTTP status code with "type": "upstream_error" and its message when it sends one (otherwise Upstream error).
Typical cases: 404 when a model is not currently served, 429 when the provider rate-limits, 400/502 when a parameter is rejected.
These requests are not charged. faborapi applies no rate limit of its own.
Editor setup
- 1Open Cursor → Settings (⌘/Ctrl + ,) → Models.
- 2In “OpenAI API Key”, paste your sk-fabor-… key.
- 3Enable “Override OpenAI Base URL” and paste the Base URL below.
- 4Add the model name (e.g. claude-sonnet-4-5) and enable it.
Loading models…
Pick any model from the list, copy its exact name, and paste it into the editor's "Model name / Model ID" field.
Setup based on each editor's OpenAI-compatible settings; menu names may differ between versions.