Documentation

Frontière API reference

The Frontière 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.

Base URL
https://getfrontiereai.eu/api/v1

Two endpoints:

POST /chat/completionsRun a model (streaming supported)
GET /modelsList 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.

Header
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-specific library needed.

curl
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"}]
  }'
Python
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)
JavaScript / TypeScript
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);

Chat completions

POST
https://getfrontiereai.eu/api/v1/chat/completions

Send a conversation, get the model's reply. Request body fields:

FieldTypeDescription
modelstring — requiredA live model ID from the catalog, e.g. glm-5.2 (see Models below).
messagesarray — requiredThe conversation so far: a list of {role, content} objects with roles system, user and assistant, in OpenAI format.
streambooleantrue streams the reply as server-sent events (see Streaming).
max_tokensintegerCap 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, …variousStandard 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:

200 — application/json
{
  "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.

Python — stream
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 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

GET
https://getfrontiereai.eu/api/v1/models

The catalog is served live by GET /api/v1/models — public, no key required. Each entry carries the OpenAI fields (id, object) plus three Frontière-specific ones: status ("live" or "coming-soon"), sovereign (boolean) and note (usage caveat, when one applies).

200 — application/json
{
  "object": "list",
  "data": [
    {
      "id": "glm-5.2",
      "object": "model",
      "label": "GLM-5.2 (Zhipu/Z.ai)",
      "provider": "scaleway",
      "status": "live",
      "sovereign": true,
      "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.

Modelmodel IDHostingStatus
Qwen3 235B (instruct)qwen3-235bEU sovereignlive
Qwen3.5 397B (multimodal)qwen3.5-397bEU sovereignlive
GLM-5.2 (Zhipu/Z.ai)glm-5.2EU sovereignlive
Llama 3.3 70Bllama-3.3-70bEU sovereignlive
Qwen3.6 27B (multimodal)qwen3.6-27bEU sovereignlive
Qwen3.5 9B (fast, budget)qwen3.5-9bEU sovereignlive
Qwen3 32Bqwen3-32bEU sovereignlive
Qwen3 Coder 30Bqwen3-coder-30bEU sovereignlive
Qwen2.5-VL 72B (vision)qwen2.5-vl-72bEU sovereignlive
GPT-OSS 120B (OpenAI)gpt-oss-120bEU sovereignlive
GPT-OSS 20B (OpenAI)gpt-oss-20bEU sovereignlive
Mistral Small 3.2 24Bmistral-small-3.2-24bEU sovereignlive
Kimi K3 (2.8T parameters, 1M context)kimi-k3Fast access (US)live
Kimi K3 — EU sovereign variantkimi-k3-souverainEU sovereignComing soon
DeepSeek V4 Flash (1M context)deepseek-v4-flashFast access (US)Coming soon
DeepSeek V4 Flash — EU sovereign variantdeepseek-v4-flash-souverainEU sovereignComing soon

Model notes

  • glm-5.2Reasoning model — thinks before answering. Omit max_tokens or allow at least ~1,000.
  • kimi-k3Reasoning model. First call after a quiet period can take a few minutes to warm up — then it responds in seconds.

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:

402 — application/json
{
  "error": {
    "message": "Insufficient credit balance. Top up your account from the dashboard.",
    "type": "insufficient_credit"
  }
}
StatustypeMeaning
400invalid_requestThe body is not valid JSON or the model field is missing.
401invalid_api_keyMissing, malformed or revoked API key in the Authorization header.
402insufficient_creditYour prepaid balance is at zero. Top up from the dashboard to resume.
404model_not_foundThe model ID is not in the catalog — list valid IDs via GET /api/v1/models.
409model_not_liveThe model exists but is still coming soon. Pick a live model.
502upstream_errorThe provider returned an unreadable response. Retry; report it if it persists.
503provider_not_configuredNo 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 is prepaid: you top up a balance (from €20, 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.

FAQ

Can I use the official OpenAI SDK?

Yes. The API implements the OpenAI chat-completions contract: point base_url at the Frontière 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 €20, paste two lines — the whole catalog behind one key.

Create an account