Developer documentation

Build on our API

An OpenAI-compatible endpoint you can point an existing SDK at, and a write-only link for delivering environment variables into a project. If you already call OpenAI, moving across is one line.

Getting started

Our gateway speaks the same wire format as OpenAI, so you do not need a new SDK or a new mental model. Install the official client, point its baseURL at us, and use the key we issued you in place of an OpenAI key.

  1. 1Ask us for an API key. It starts with vii_live_ and is shown to you once.
  2. 2Set baseURL to https://visionitinfra.com/v1 in your OpenAI client.
  3. 3Call the models your key is enabled for. That is the whole integration.
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.VISIONIT_API_KEY,   // vii_live_...
  baseURL: 'https://visionitinfra.com/v1',                     // the only line that changes
});

const reply = await client.chat.completions.create({
  model: 'gpt-4.1-mini',
  messages: [{ role: 'user', content: 'Write one line about exams.' }],
});

console.log(reply.choices[0].message.content);

Authentication

Every request carries your key as a bearer token. There is nothing else to sign and no timestamp to compute.

Authorization: Bearer vii_live_xxxxxxxxxxxxxxxx

Keep it server-side

A key spends real credit on your plan. Never ship one in a browser bundle, a mobile app, or a public repository — anyone who reads it can spend your balance. If one leaks, tell us and we will revoke it; revocation takes effect on the next request.

We store only a hash of your key, so we cannot email it back to you. A lost key is replaced, not recovered.

Chat completions

POST/v1/chat/completions

Takes and returns exactly what OpenAI's endpoint does. Anything the official SDK sends is passed through, and the response is returned untouched — including usage, so your own token accounting still works.

FieldTypeNotes
modelstringRequired. Must be enabled on your key — see Models.
messagesarrayRequired. The standard role/content shape.
streambooleanOptional. See Streaming.
max_tokensnumberOptional, but it makes our credit hold more accurate.
temperature, top_p, …variousPassed through unchanged.

Streaming

Set stream: true and the reply arrives as server-sent events, token by token, exactly as it would from OpenAI. Our proxy does not buffer, so the first token reaches you as soon as it exists.

const stream = await client.chat.completions.create({
  model: 'gpt-4.1-mini',
  messages: [{ role: 'user', content: 'Explain photosynthesis.' }],
  stream: true,
});

for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
}

You do not need to ask for usage reporting — we add it to the upstream request ourselves so streamed calls are metered like any other. If you disconnect mid-stream, the work has already been done upstream and is still billed.

Models

GET/v1/models

Returns the models your key is enabled for. Each key carries its own list, so this is the authoritative answer to “what can I call?” — a model outside it is refused with a 403.

curl https://visionitinfra.com/v1/models \
  -H "Authorization: Bearer $VISIONIT_API_KEY"

Need one that is not on your list? Ask us — the cheaper models cost a fraction of the larger ones, so the right choice is usually a pricing conversation as much as a technical one.

Errors

Errors come back in OpenAI's own shape, so your SDK's existing error handling reads them without changes.

{
  "error": {
    "message": "This plan has no credit left. Top it up to keep going.",
    "type": "insufficient_quota",
    "param": null,
    "code": null
  }
}
StatusMeaningWhat to do
401The key is missing, unknown or revoked.Check the Authorization header. Ask us for a new key if yours was revoked.
402The plan is out of credit.Nothing was sent upstream and nothing was charged. Top up and retry.
403That model is not enabled on your key.Call GET /v1/models to see what is.
429Too many requests for this key.Back off and retry. Your per-minute limit is set per key.
502We could not reach the model provider.Transient. Retry with backoff.

A 402 costs you nothing

The credit check runs before anything is forwarded, so a refused request never reaches the provider and never appears on your bill.

Usage and credit

Your plan carries a token balance, visible any time under Billing in your portal, along with what has been used this period.

Balance is drawn down per request based on what the call actually consumed — prompt tokens and completion tokens, priced by the model you chose. A short prompt on a small model costs a fraction of a long one on a large model, so choosing the smallest model that does the job is the single biggest lever on how far a top-up goes.

When the balance runs out

Requests are refused with a 402 until the plan is topped up. Nothing is silently cut off mid-conversation and no overage is billed — you simply stop, and start again when the next top-up is paid.

Environment delivery

Every project in the portal can issue a delivery link — a single URL you can post a .env to. The variables land in the project encrypted, without anything needing a login, which means a build agent or an assistant can deliver credentials without being given an account.

POST/api/v1/env-ingest/{token}
curl -X POST "https://visionitinfra.com/api/v1/env-ingest/vii_env_xxxx" \
  -H "Content-Type: text/plain" \
  --data-binary @.env.production

JSON works too, if that suits your tooling better:

{ "content": "DATABASE_URL=postgres://...\nNODE_ENV=production" }

A link can only write

It cannot read back what is already stored, and it is pinned to one project and one named set when it is created. A link that ends up in a build log can add variables but can never leak the ones already there. Links are revocable and can be given an expiry.

Each delivery replaces the whole set rather than merging into it, so variables you removed do not linger. The response tells you which keys landed — never their values.

Something missing, or an endpoint behaving differently from this page? Tell us — we would rather fix the docs than have you guess.