Documentation

One request shape. One decision shape.

The request and decision shapes the CenovaGate gateway uses, with a worked example you can validate.

Open console
Contract version 2026-09-22.v1
Preview

Every request you send and every decision we return follow the two shapes below. They borrow familiar chat-completion ideas — a model name, a list of messages and a few parameters — but they are our own shapes, not a drop-in replacement for another provider's API yet. The version above changes whenever a field changes meaning.

Drop-in chat completions

Already using an OpenAI-compatible client? Point its base URL at https://your-cenovagate-domain/api/public/gateway/v1 and use your CenovaGate key. Requests and replies keep the familiar shape, with an extra cenovagate block carrying the request id, the decision and the estimated cost. Streaming is not available on this endpoint yet, so send stream: false or leave it out.

cURL

curl https://your-cenovagate-domain/api/public/gateway/v1/chat/completions \
  -H "Authorization: Bearer $CENOVAGATE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-4.1-mini","messages":[{"role":"system","content":"You are a concise assistant."},{"role":"user","content":"Summarise in one sentence: the invoice export stops at 500 rows."}],"temperature":0.2,"max_tokens":300}'

JavaScript (fetch)

const response = await fetch("https://your-cenovagate-domain/api/public/gateway/v1/chat/completions", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CENOVAGATE_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    "model": "gpt-4.1-mini",
    "messages": [
      {
        "role": "system",
        "content": "You are a concise assistant."
      },
      {
        "role": "user",
        "content": "Summarise in one sentence: the invoice export stops at 500 rows."
      }
    ],
    "temperature": 0.2,
    "max_tokens": 300
  }),
});

const result = await response.json();
console.log(result.choices[0].message.content);
console.log(result.cenovagate); // request id, decision and estimated cost

OpenAI SDK

import OpenAI from "openai";

// Only the base URL and key change — the request stays the same.
const client = new OpenAI({
  apiKey: process.env.CENOVAGATE_API_KEY,
  baseURL: "https://your-cenovagate-domain/api/public/gateway/v1",
});

const completion = await client.chat.completions.create({
  "model": "gpt-4.1-mini",
  "messages": [
    {
      "role": "system",
      "content": "You are a concise assistant."
    },
    {
      "role": "user",
      "content": "Summarise in one sentence: the invoice export stops at 500 rows."
    }
  ],
  "temperature": 0.2,
  "max_tokens": 300
});

Request fields

What you send to the gateway.

What you send to the gateway.
FieldTypeRequiredWhat it means
contractVersionstringRequiredVersion of this contract the caller was built against.
organisationIduuidRequiredThe organisation the request belongs to.
applicationIduuidRequiredThe application sending the request.
environmentIduuidRequiredThe environment, for example Production.
apiKeyPrefixstringRequiredShort prefix of the API key. Never send the full key or any provider credential in the payload.
requestedModelstringRequiredThe model the caller asked for. Routing may choose another one.
messagesarrayRequiredChat messages with role and content, 1 to 200 entries.
parametersobjectOptionaltemperature, topP, maxOutputTokens, stream, stop. Unknown parameters are rejected.
metadataobjectOptionalYour own labels, up to 20 entries and 4096 characters.
requestedAtISO 8601RequiredWhen the caller created the request.

Decision fields

What the gateway returns about the choice it made.

What the gateway returns about the choice it made.
FieldTypeRequiredWhat it means
contractVersionstringRequiredVersion of this contract the decision was produced with.
requestIduuidRequiredIdentifier for this request, used in the request log.
decisionenumRequiredOne of BYPASS, CACHE, COMPRESS, CHEAP_MODEL, PREMIUM_MODEL, HUMAN_REVIEW, BLOCK.
selectedModelstring or nullRequiredThe model actually used, or null when nothing was sent to a provider.
cacheStatusenumRequiredOne of miss, exact_hit, semantic_hit, bypassed.
tokensRemovedintegerRequiredTokens removed by compression before sending.
baselineCostnumberRequiredEstimated cost of sending the request unchanged to the requested model.
estimatedCostnumberRequiredEstimated cost after the decision was applied.
savingnumberRequiredBaseline cost minus estimated cost. May be negative.
latencyMsintegerRequiredTotal time the gateway took, in milliseconds.
reasonstringRequiredPlain-language explanation of why this decision was made.
decidedAtISO 8601RequiredWhen the decision was made.

Try an example

Copy the example request, change anything you like, then check it. Valid payloads return an example decision; invalid ones list exactly which field is wrong.

Nothing is sent anywhere — the same rules that run on the gateway run here in your browser.

Check the request to see the decision it would produce.

Key status responses

Send your key as Authorization: Bearer cg_…. The gateway answers with a stable code you can branch on. Full key values are never echoed back or written to logs — only the public prefix.

Authentication error codes, their HTTP status and what they mean.
CodeHTTP statusWhat it means
missing_authorization401Provide your API key as an Authorization: Bearer header.
malformed_authorization401The Authorization header must use the Bearer scheme.
malformed_key401The API key format is not valid. Keys look like cg_<environment>_<prefix>_<secret>.
invalid_key401This API key is not recognised.
revoked_key403This API key has been revoked. Create a new key to continue.
expired_key401This API key has expired. Create a new key to continue.
environment_mismatch403This API key belongs to a different environment than the one requested.
insufficient_permission403This API key does not have the permission required for this request.
too_many_failed_attempts429Too many failed authentication attempts. Wait a moment before trying again.