Documentation
Frontière AI API reference
The Frontière AI API is an OpenAI-compatible gateway to a curated catalog of powerful open-source models hosted in Europe. Point your existing SDK or HTTP client at the base URL below, authenticate with an API key from your dashboard, and every live model is available through the same endpoint — each one labeled EU sovereign or fast access, so you always know which jurisdiction serves your data.
Overview
The API implements the OpenAI chat-completions contract. If your code already talks to OpenAI — through the official Python or JavaScript SDK, LangChain, or a plain HTTP client — you only change two things: the base URL and the key. One key unlocks the whole catalog.
Machine-readable OpenAPI spec: /openapi.json (OpenAPI 3.1).
https://getfrontiereai.eu/api/v1Two endpoints:
POST /chat/completions | Run a model (streaming supported) |
GET /models | List the catalog — public, no key required |
Authentication
Every call to the chat endpoint carries your API key in the Authorization header. Keys are created in the dashboard under API keys — the full value (sk-front-…) is shown once at creation, then only its prefix. Create one key per environment or app; each can be revoked independently without touching the others.
Authorization: Bearer sk-front-…Keep keys server-side (environment variables, a secret manager) — never in client-side code or a public repository. If a key leaks, revoke it from the dashboard and create a new one; the old one stops working immediately.
Quickstart
The same call in three languages. The Python and JavaScript examples use the official OpenAI SDK (pip install openai / npm install openai) — no Frontière AI-specific library needed.
curl https://getfrontiereai.eu/api/v1/chat/completions \
-H "Authorization: Bearer $FRONTIERE_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "glm-5.2",
"messages": [{"role": "user", "content": "Bonjour"}]
}'import os
from openai import OpenAI
client = OpenAI(
base_url="https://getfrontiereai.eu/api/v1",
api_key=os.environ["FRONTIERE_KEY"],
)
reply = client.chat.completions.create(
model="glm-5.2",
messages=[{"role": "user", "content": "Bonjour"}],
)
print(reply.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://getfrontiereai.eu/api/v1",
apiKey: process.env.FRONTIERE_KEY,
});
const reply = await client.chat.completions.create({
model: "glm-5.2",
messages: [{ role: "user", content: "Bonjour" }],
});
console.log(reply.choices[0].message.content);Trying a model without writing code
Your dashboard includes a console: a chat window onto the same catalog, over the same EU routing, at the same per-token price. It is there to answer “which model should I use, with which system prompt and which parameters?” before you wire anything up — every reply shows the model, the token counts and the exact amount debited.
Once a prompt behaves the way you want, the console turns the current model, parameters and prompt into a ready-to-paste curl, Python or JavaScript call against this API. Conversations are held in your browser, not on our servers, unless you explicitly sync a thread to your account.
Chat completions
https://getfrontiereai.eu/api/v1/chat/completionsSend a conversation, get the model's reply. Request body fields:
| Field | Type | Description |
|---|---|---|
model | string — required | A live model ID from the catalog, e.g. glm-5.2 (see Models below). |
messages | array — required | The conversation so far: a list of {role, content} objects with roles system, user and assistant, in OpenAI format. |
stream | boolean | true streams the reply as server-sent events (see Streaming). |
max_tokens | integer | Cap on completion tokens. On reasoning models, thinking counts against it — omit it or allow at least ~1,000 (see Reasoning models). |
temperature, top_p, stop, … | various | Standard OpenAI sampling parameters, forwarded unchanged to the provider serving the model. |
The request body is forwarded to the provider hosting the model, so the standard OpenAI parameters behave exactly as documented by OpenAI. Fields a given provider does not support are ignored by that provider.
The response is a standard chat.completion object. The usage block is what your balance is billed against — token-exact, including reasoning tokens on reasoning models:
{
"id": "chatcmpl-…",
"object": "chat.completion",
"model": "glm-5.2",
"choices": [
{
"index": 0,
"message": { "role": "assistant", "content": "Bonjour ! Comment puis-je aider ?" },
"finish_reason": "stop"
}
],
"usage": { "prompt_tokens": 9, "completion_tokens": 42, "total_tokens": 51 }
}Streaming
Set "stream": true and the reply arrives as server-sent events — data: chunks with the incremental delta, terminated by data: [DONE]. This is the same wire format as OpenAI, so SDK streaming helpers work unchanged.
stream = client.chat.completions.create(
model="llama-3.3-70b",
messages=[{"role": "user", "content": "Bonjour"}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")Frontière AI always enables stream_options.include_usage upstream: the final data chunk before [DONE] carries the usage object (and an empty choices array). That chunk is how streamed calls are billed exactly — don't be surprised by it if you parse the stream by hand.
Models
https://getfrontiereai.eu/api/v1/modelsThe catalog is served live by GET /api/v1/models — public, no key required. It lists live models only, so anything you discover there is callable right now; add ?include=all to also get the coming-soon entries. Each entry carries the OpenAI fields (id, object, created, owned_by), context_length and pricing (client price in EUR per million tokens, input and output) when verified, plus four Frontière AI-specific ones: status ("live" or "coming-soon"), sovereign (boolean), tool_calling (boolean, present only where we measured it with a real call — filter on it before building an agent) and note (usage caveat, when one applies).
{
"object": "list",
"data": [
{
"id": "glm-5.2",
"object": "model",
"created": 1786022547,
"owned_by": "Zhipu / Z.ai",
"label": "GLM-5.2 (Zhipu/Z.ai)",
"provider": "scaleway",
"status": "live",
"sovereign": true,
"tool_calling": true,
"pricing": {
"currency": "EUR",
"input_per_million": 2.52,
"output_per_million": 7.7
},
"note": "Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000."
}
]
}sovereign: true means the company operating the infrastructure has no non-EU capital or jurisdictional control (the SecNumCloud principle) — OVHcloud, Scaleway, or dedicated EU servers. Models served through US infrastructure (even in an EU region) are labeled fast access, never sovereign, so you can filter per call with full information.
| Model | model ID | Hosting | Status |
|---|---|---|---|
| Qwen3 235B (instruct) | qwen3-235b | EU sovereign | live |
| Qwen3.5 397B (multimodal) | qwen3.5-397b | EU sovereign | live |
| GLM-5.2 (Zhipu/Z.ai) | glm-5.2 | EU sovereign | live |
| DeepSeek V4 Flash 0731 (1M context) | deepseek-v4-flash-0731 | EU sovereign | live |
| Llama 3.3 70B | llama-3.3-70b | EU sovereign | live |
| Qwen3.6 27B (multimodal) | qwen3.6-27b | EU sovereign | live |
| Qwen3.5 9B (fast, budget) | qwen3.5-9b | EU sovereign | live |
| Qwen3 32B | qwen3-32b | EU sovereign | live |
| Qwen3 Coder 30B | qwen3-coder-30b | EU sovereign | live |
| Qwen2.5-VL 72B (vision) | qwen2.5-vl-72b | EU sovereign | live |
| GPT-OSS 120B (OpenAI) | gpt-oss-120b | EU sovereign | live |
| GPT-OSS 20B (OpenAI) | gpt-oss-20b | EU sovereign | live |
| Mistral Small 3.2 24B | mistral-small-3.2-24b | EU sovereign | live |
| Kimi K3 (2.8T parameters, 1M context) | kimi-k3 | Fast access (US) | live |
| Kimi K3 — EU sovereign variant | kimi-k3-souverain | EU sovereign | Coming soon |
| Muse Spark 1.1 (1M context) | muse-spark-1.1 | Fast access (US) | live |
| Muse Spark 1.2 (1M context) | muse-spark-1.2 | Fast access (US) | live |
| GLM-5.3 Flash (Zhipu/Z.ai) | glm-5.3-flash | Fast access (US) | live |
| Qwen3.8 Max (2.4T, 1M context) | qwen3.8-max | Fast access (US) | live |
| Qwen3.8 27B (multimodal) | qwen3.8-27b | EU sovereign | live |
| Qwen3.8 Flash (Qwen) | qwen3.8-flash | Fast access (US) | live |
| DeepSeek R1 (671B MoE) | deepseek-r1 | Fast access (US) | live |
| DeepSeek V4 Pro (345B MoE) | deepseek-v4-pro | Fast access (US) | live |
| DeepSeek R1 (Distill Qwen 32B) | deepseek-r1-distill-qwen-32b | Fast access (US) | live |
| DeepSeek R1 (Distill Qwen 14B) | deepseek-r1-distill-qwen-14b | Fast access (US) | live |
| GLM-5.3 (Zhipu/Z.ai) | glm-5.3 | Fast access (US) | live |
| Gemma 3 27B (Google) | gemma-3-27b | Fast access (US) | live |
| DeepSeek V4.1 Flash (552B MoE, 1M context) | deepseek-v4.1-flash | Fast access (US) | live |
Model notes
glm-5.2— Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.deepseek-v4-flash-0731— Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.qwen2.5-vl-72b— Vision model — its provider rejects tool calls with a 400, so it cannot back an agent. Use it for image understanding, not for function calling.kimi-k3— Reasoning model. First call after a quiet period can take a few minutes to warm up — then it responds in seconds.muse-spark-1.1— Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.muse-spark-1.2— Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.glm-5.3-flash— Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.qwen3.8-27b— Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.deepseek-r1— Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.deepseek-r1-distill-qwen-32b— Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.deepseek-r1-distill-qwen-14b— Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.glm-5.3— Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.deepseek-v4.1-flash— Multimodal reasoning model (text + images). First call after a quiet period can take a while to warm up. Omit max_tokens or allow plenty of headroom for the chain of thought.
Per-token prices for every live model are listed on the model catalog. Calling a coming-soon model returns HTTP 409 — and records your interest: asking for a model is the best way to vote for its priority. Unknown model IDs return 404 with a pointer back to the catalog.
Errors
Errors are JSON, OpenAI-style — an error object with a human-readable message and a stable type you can branch on:
{
"error": {
"message": "Insufficient credit balance. Top up your account from the dashboard.",
"type": "insufficient_credit"
}
}| Status | type | Meaning |
|---|---|---|
| 400 | invalid_request | The body is not valid JSON or the model field is missing. |
| 401 | invalid_api_key | Missing, malformed or revoked API key in the Authorization header. |
| 402 | insufficient_credit | Your prepaid balance is at zero. Top up from the dashboard to resume. |
| 404 | model_not_found | The model ID is not in the catalog — list valid IDs via GET /api/v1/models. |
| 409 | model_not_live | The model exists but is still coming soon. Pick a live model. |
| 502 | upstream_error | The provider returned an unreadable response. Retry; report it if it persists. |
| 503 | provider_not_configured | No provider credentials for this model on this instance. |
Provider-side errors (rate limits, overloaded model, invalid parameter for that provider) are relayed as-is with their upstream status code and body — what you would get calling the provider directly.
Credit & billing
Frontière AI is prepaid: you top up a balance (from €10, via Stripe, in the dashboard) and every successful call draws it down. No subscription, no card on file, no invoice at the end of the month — when the balance reaches zero, calls return 402 and nothing else happens.
Billing is token-exact, computed from the usage object the provider reports for your call: prompt tokens at the model's input rate, completion tokens (including reasoning tokens) at the output rate. When a provider serves part of your prompt from its cache and reports it (usage.prompt_tokens_details.cached_tokens), those tokens are billed at the model's cheaper cache rate.
Your dashboard shows the balance, a per-call billing history (tokens in/out and price per call), and top-up history. The price of each call is charged at the moment the provider returns its usage — streamed calls included, via the final usage chunk.
Reasoning models
glm-5.2 and kimi-k3 think before they answer: the thinking consumes completion tokens (billed as output) before any visible text is produced. With a small max_tokens the entire budget can go to reasoning — the reply then comes back with content: null and finish_reason "length", which looks like an empty answer. Omit max_tokens or allow at least ~1,000.
kimi-k3 additionally scales to zero between uses: the first call after a quiet period can take a few minutes to warm up, then it answers in seconds. It is served through US infrastructure and labeled fast access — check the sovereign field if jurisdiction matters for your workload.
Reasoning also takes wall-clock time: on a substantial prompt, glm-5.2 can think for several minutes before the full reply is ready. Set your HTTP client's timeout generously (many tools default to well under a minute — Make.com's HTTP module, for instance, cuts at 40 seconds unless you raise it), or better, use streaming: the first chunk arrives in under a second and the connection stays active throughout.
Embeddings
POST /api/v1/embeddings turns text into vectors, same authentication and same prepaid billing as chat. The request body follows OpenAI's: model, and input as a string or an array of strings. The response is an object of type list whose data carries one embedding per input, in the order you sent them.
curl https://getfrontiereai.eu/api/v1/embeddings \
-H "Authorization: Bearer $FRONTIERE_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "bge-m3",
"input": ["Premier document", "Second document"]
}'Embedding models live in their own catalog — a chat model sent here answers 404, and an embedding model sent to /chat/completions does too. GET /api/v1/models?kind=embedding returns only the valid ones; every entry in the catalog also carries a kind field ("chat" or "embedding") so a single call can tell them apart.
| Model | Dimensions | Context |
|---|---|---|
bge-m3 | 1024 | 8192 |
bge-multilingual-gemma2 | 3584 | 8192 |
qwen3-embedding-8b | 4096 | 40960 |
Pick by dimensions before you index anything: the vector length is part of your storage schema, and changing model later means recomputing every vector you hold. Billing counts input tokens only — an embedding produces no output tokens, so there is no output rate.
MCP server
Frontière AI exposes a Model Context Protocol (MCP) endpoint that gives AI agents (Claude Code, Codex, Cursor, Roo Code, Continue, etc.) full programmatic access to the Frontière AI API. Any MCP-compatible client connects with a single URL and can browse the catalog, run inference, create embeddings, and check account balance — all over standardized JSON-RPC 2.0.
Connect your agent's MCP client to the endpoint URL below. The endpoint uses stateless HTTP: each POST request is a self-contained JSON-RPC 2.0 call with a synchronous response — no SSE streams, no session state. Authentication is done by sending your API key as an Authorization header on each request (e.g. Authorization: Bearer sk-front-...). Read-only tools (catalog queries) work without a key; inference and balance tools require one.
The MCP server exposes eight tools: three for catalog discovery (list_models, get_model, search_models — no auth required) and five for authenticated operations (chat_completion forwards a chat request to the gateway with full token billing, create_embedding generates vectors from text, check_balance returns your current credit balance, and web_search / web_fetch give the agent live web access through an EU search provider). A dedicated page covers setup and per-tool detail.
https://getfrontiereai.eu/api/mcpTransport: POST with application/json — JSON-RPC 2.0, stateless (no SSE, no sessions).
Available tools
| Tool | Description |
|---|---|
list_models | List all models with optional filters: filter (live/coming-soon/sovereign), provider, kind (chat/embedding), includeComingSoon |
get_model | Get detailed info for a single model by slug: pricing, vendor, license, parameters, sovereignty, compliance data |
search_models | Search models by keyword across slug, name, vendor, provider, and modality |
chat_completion | Run inference on any live model. Supports temperature, max_tokens, tool calling. Usage billed per token (same pricing as the REST API) |
create_embedding | Generate text embeddings for RAG/semantic search. Supports string or array input. Usage billed per token |
check_balance | Check current prepaid credit balance in EUR (no parameters needed) |
web_search | Live web search (Linkup, EU) returning up to 8 results with the full page text of each — covered by our search quota, not billed against your balance |
web_fetch | Read one web page as clean markdown (Linkup, EU) — follow up on a search result URL |
Integrations
Anything that speaks the OpenAI protocol works by changing the base URL and the key — SDKs, LangChain, agent frameworks, no-code tools. Some platforms need a few specific steps, and agents in particular need tool calling, which we measured model by model:
Integrations: agent platforms, tool-calling matrix, known gaps →
FAQ
Can I try a model without writing any code?
Yes — the dashboard includes a web console that talks to the same catalog over the same EU routing, at the same per-token price as the API. Use it to settle on a model, a system prompt and parameters, then have it generate the equivalent curl, Python or JavaScript call. Conversations stay in your browser unless you explicitly sync a thread to your account.
Can I use the official OpenAI SDK?
Yes. The API implements the OpenAI chat-completions contract: point base_url at the Frontière AI API and pass your key as api_key — the official Python and JavaScript SDKs, and tools built on them, work unchanged.
What happens when my credit reaches zero?
Calls return HTTP 402 (insufficient_credit) and stop being served. Nothing else happens — no overdraft, no automatic charge. Top up from the dashboard to resume.
How do I know whether a model is EU sovereign?
Every model carries a sovereign boolean in GET /api/v1/models and a badge on the catalog. sovereign: true means no non-EU capital or jurisdictional control over the operator (SecNumCloud principle); models served through US infrastructure are always labeled fast access, never sovereign.
Why did my reply come back empty?
You most likely called a reasoning model (glm-5.2, kimi-k3) with a small max_tokens: the whole budget went to thinking and content came back null with finish_reason "length". Omit max_tokens or allow at least ~1,000.
Ready to make your first call?
Create an account, top up from €10, paste two lines — the whole catalog behind one key.
Create an account