GatewayDocsOpen workspace ↗
Developer preview · Synthetic data only Launch status ↗
Documentation/Examples

JavaScript & TypeScript

Call the gateway from a Node.js server with fetch or the official OpenAI SDK.

Environment

This example uses Node.js with built-in fetch and no SDK. Configure GATEWAY_API_KEY in a server-side environment variable and optionally GATEWAY_BASE_URL. It calls the free sandbox-chat model; switch to a production alias from GET /v1/models when you use a production key.

A complete request

javascript
const baseURL = process.env.GATEWAY_BASE_URL ?? 'https://gateway.accountablehq.com';
const apiKey = process.env.GATEWAY_API_KEY;
if (!apiKey) throw new Error('Set GATEWAY_API_KEY in your environment');

const response = await fetch(`${baseURL}/v1/chat/completions`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'javascript-001',
  },
  body: JSON.stringify({
    model: 'sandbox-chat',
    messages: [{ role: 'user', content: 'Explain an AI gateway in one sentence.' }],
    max_tokens: 64,
  }),
});
const result = await response.json();
if (!response.ok) {
  throw new Error(`${response.status}: ${result.error?.code ?? 'unknown_error'}`);
}
console.log(result.choices[0].message.content);
console.log({ requestId: result.id, usage: result.usage, cost: result.gateway.charged_usd });

With the official OpenAI SDK

javascript
import OpenAI from 'openai';

const client = new OpenAI({
  baseURL: 'https://gateway.accountablehq.com/v1',
  apiKey: process.env.GATEWAY_API_KEY,
  maxRetries: 0, // retry deliberately with an Idempotency-Key instead
});

const completion = await client.chat.completions.create(
  {
    model: 'sandbox-chat', // later: a production alias such as 'gpt-6-luna'
    messages: [{ role: 'user', content: 'Explain an AI gateway in one sentence.' }],
    max_tokens: 64,
  },
  { headers: { 'Idempotency-Key': crypto.randomUUID() } },
);
console.log(completion.choices[0].message.content);

Automatic SDK retries are turned off on purpose. A timeout does not prove the model did not run, so a blind retry can be billed twice. Retry only with the same Idempotency-Key; the gateway refuses a duplicate while the first attempt is pending or succeeded, and accepts the same key again after a failure that cost nothing. See idempotency.

Adapt for your service

  • Discover the catalog before choosing a model in another environment.
  • Generate and persist a non-sensitive logical request ID for each job; the fixed example idempotency key is only for a single run.
  • Capture status and request IDs without logging authorization headers or sensitive content.
  • Do not treat a network exception as proof that the provider did not run.
  • Bound concurrency and implement outcome-aware retries.

Keep the key out of the browser

Run this integration behind your own authenticated backend. The Gateway API has no cross-origin browser support intended for exposing secrets directly. Do not use a public frontend environment variable or ship the key in a client bundle.

Search documentation

Search all 25 guides and references.