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

Python

Make a request with Python’s standard library or the official OpenAI SDK.

Environment

This example uses urllib.request, json, and os; no SDK is required. Set the Gateway key outside the source file. It calls the free sandbox-chat model. The fixed idempotency key is for one sample request; generate a new opaque ID per real logical job.

A complete request

python
import json
import os
import urllib.request
import urllib.error

base_url = os.environ.get("GATEWAY_BASE_URL", "https://gateway.accountablehq.com")
api_key = os.environ["GATEWAY_API_KEY"]
payload = {
    "model": "sandbox-chat",
    "messages": [{"role": "user", "content": "Explain an AI gateway in one sentence."}],
    "max_tokens": 64,
}
request = urllib.request.Request(
    f"{base_url}/v1/chat/completions",
    data=json.dumps(payload).encode("utf-8"),
    headers={
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
        "Idempotency-Key": "python-001",
    },
    method="POST",
)
try:
    with urllib.request.urlopen(request, timeout=620) as response:
        result = json.load(response)
except urllib.error.HTTPError as error:
    result = json.load(error)
    raise RuntimeError(f"{error.code}: {result.get('error', {}).get('code')}") from None
print(result["choices"][0]["message"]["content"])
print({"request_id": result["id"], "usage": result["usage"], "cost": result["gateway"]["charged_usd"]})

With the official OpenAI SDK

python
import os
import uuid
from openai import OpenAI

client = OpenAI(
    base_url="https://gateway.accountablehq.com/v1",
    api_key=os.environ["GATEWAY_API_KEY"],
    max_retries=0,  # retry deliberately with an Idempotency-Key instead
)

completion = 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,
    extra_headers={"Idempotency-Key": str(uuid.uuid4())},
)
print(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.

Handle network failures separately

HTTPError contains a structured gateway error. A network error or timeout might arrive without any HTTP response; the provider may still have executed. Preserve the logical request ID and reconcile instead of blindly submitting a new generation.

The timeout is a client waiting limit, not provider cancellation. Do not automatically print response content in production logs; this example prints a fictional answer to make the local test easy to inspect.

Next steps

Read responses and usage for parsing fields and credits and reservations for accounting. Use a model returned by your key’s catalog when you move from a sandbox key to a production key.

Search documentation

Search all 25 guides and references.