Skip to main content
Docs
  1. Documentation
  2. BRANE AIF
  3. API reference

API reference

Brane AIF Developer API

Updated24 July 2026Applies toBrane AIF 1.4.xPrint version

1. Overview

The Box exposes an OpenAI-compatible gateway at /api/v1. Any tool that speaks the OpenAI Chat Completions protocol — IDE extensions (Continue, Cline), SDKs (openai, @ai-sdk/openai-compatible), n8n, custom apps — can use the Box as its model provider.

Tip

The difference from a normal provider

Every request runs through Guardian. The Box decides locally whether a request stays on-premise or goes to a cloud model, and strips PII before anything leaves. You get the OpenAI wire format — the Box keeps data sovereignty.

2. Base URL

https://<your-box-domain>/api/v1

All endpoints below are relative to this base URL (/api/v1/chat/completions, /api/v1/models, etc.).

3. Authentication

Bearer token on every request:

Authorization: Bearer brn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Issue a key in the admin dashboard under Admin → API Keys (/admin/api-keys). Keys are scoped (chat:completions), can carry a per-key rate limit, and can be revoked at any time. The plaintext key is shown once on creation — store it securely.

Warning

Legacy bearer

A legacy global bearer (AI_BOX_API_SECRET) is still accepted for existing n8n setups, but managed per-user keys are strongly preferred — revocable, rate-limited, attributable.

4. List models — GET /v1/models

Lists the models the Box exposes. Most SDKs and IDE extensions call this on setup to validate the key and populate a model picker.

curl https://<your-box>/api/v1/models \
  -H "Authorization: Bearer $BRANE_KEY"
{
  "object": "list",
  "data": [
    { "id": "vllm:gemma-4-26b-nvfp4", "object": "model", "created": 1750000000, "owned_by": "local" },
    { "id": "openrouter:anthropic/claude-sonnet-4.5", "object": "model", "created": 1750000000, "owned_by": "openrouter" }
  ]
}

The visible set respects the admin ZDR filter and OpenRouter allowlist. owned_by: "local" marks on-premise vLLM models. Note: the routing mode is not applied here — in local-only mode cloud models may be listed even though every request executes locally.

5. Chat completions — POST /v1/chat/completions

Standard OpenAI Chat Completions. Supports messages and stream with text content. temperature, max_tokens and top_p are accepted but currently not forwarded to the model; image input (image_url) is not yet available (both on the roadmap).

curl https://<your-box>/api/v1/chat/completions \
  -H "Authorization: Bearer $BRANE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "vllm:gemma-4-26b-nvfp4",
    "messages": [{ "role": "user", "content": "Refactor this function: ..." }],
    "stream": true
  }'

Streaming returns Server-Sent Events in chat.completion.chunk format, terminated by data: [DONE]. Non-streaming returns a single chat.completion object. The usage field currently uses Vercel AI SDK field names (inputTokens/outputTokens), not the OpenAI format (prompt_tokens/completion_tokens).

6. Sovereignty behaviour

Note

Read this before integrating

The gateway is OpenAI-compatible at the wire level, but Guardian changes two things you must understand.

1. The model field is informational only

Guardian picks the actual model solely from the Box's routing mode (local-only, local-preferred, …) and the content of the request: locally the configured box model, in the cloud the admin-configured cloud model. Your requested model is never targeted directly — not even when routing goes to the cloud. The model field in the response names what actually executed; x_brane.model_requested and the X-Brane-Overridden headers reveal a divergence.

2. PII is redacted before cloud

When Guardian routes to a cloud model and the PII policy is anonymize, personal data is replaced with tokens (<PERSON_1>, <EMAIL_1>) before the request leaves the Box, and restored in the response. The cloud model never sees real data. In local-only mode nothing leaves the Box at all — no redaction needed.

Warning

For code / IDE use

Prefer running the Box in local-only mode. Source code and large auto-assembled context carry secrets (API keys, hostnames, connection strings) that statistical PII detection does not reliably catch. local-only removes that risk entirely — nothing leaves the Box.

7. IDE integration

Continue.dev (VS Code / JetBrains)

~/.continue/config.json:

{
  "models": [
    {
      "title": "Brane AIF (sovereign)",
      "provider": "openai",
      "model": "vllm:gemma-4-26b-nvfp4",
      "apiBase": "https://<your-box>/api/v1",
      "apiKey": "brn_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }
  ]
}

provider: "openai" plus a custom apiBase points Continue at the Box. Chat, explain, and refactor work today.

Cline / Roo

Select the „OpenAI Compatible“ provider, set the Base URL to https://<your-box>/api/v1 and paste the key.

8. Current limitations

Honest scope of what the gateway does not do yet:

Capability Status
Chat (ask, explain, refactor) available
GET /v1/models discovery available
Tool / function calling (tools, tool_calls) not yet — required for agentic coding (Cline agent mode, Continue agent)
Inline autocomplete (FIM /v1/completions) not yet
Embeddings (/v1/embeddings, @codebase) not yet
Streaming usage / stream_options not emitted
temperature / max_tokens / top_p / max_completion_tokens accepted, currently not forwarded to the model

Note

Outlook

For agentic coding and inline completion, the planned direction is a transparent proxy to the on-prem vLLM /v1 surface (roadmap).

9. Errors

OpenAI-style error envelope:

{ "error": { "message": "Invalid API Key", "type": "auth_error" } }
Status type Cause
400 invalid_request_error Malformed body / malformed known fields (unknown top-level fields are silently ignored)
401 auth_error Missing or invalid key
403 auth_error Key lacks the chat:completions scope
403 user_disabled User has been disabled
429 rate_limit_error Per-key rate limit exceeded (Retry-After: 60). The IP-based gateway limit also answers 429, but with a simplified envelope ({"error": "…"}) and a dynamic Retry-After
500 server_error Internal failure (details are logged server-side, never returned)

Questions about integrating?

Our team helps you connect your tools.

Contact support