Start here · Step 10: First request
Your first Gatewayz API request in five minutes
Make your first Gatewayz API request: get a key, check model ids, call chat completions with curl or the OpenAI Python SDK, and read common errors.
Last updated · 8 min read · Gatewayz
A first Gatewayz API request is an HTTPS POST to https://api.gatewayz.ai/v1/chat/completions with your key in an Authorization: Bearer header and a JSON body naming a model, such as anthropic/claude-sonnet-4-6, and a list of messages. The response is a standard OpenAI-style chat completion.
What do I need before making a Gatewayz API request?
You need a Gatewayz API key, a terminal with curl, and optionally Python 3 with the OpenAI SDK installed. That is the whole list.
First, create an account and an API key at https://beta.gatewayz.ai. If you plan to experiment in a loop or run an agent, set a request cap on the key when you create it.
Next, put the key in an environment variable so your code and commands refer to the variable, never the key itself. Setting it in your shell profile or a local .env file that is excluded from version control keeps it out of source files:
export GATEWAYZ_API_KEY="paste-your-key-here"For the Python section, install the SDK:
pip install openaiAn API key is a credential that spends your balance, so treat it like a password. How Gatewayz keeps your API keys and data secure covers the habits worth building from the first request.
How do I find the right model id?
Ask the catalog. GET https://api.gatewayz.ai/v1/models returns every model currently available, and it does not require a key:
curl -s https://api.gatewayz.ai/v1/modelsThe response is a JSON object with a data array. Each entry has an id, which is the exact string to put in the model field of a request, along with fields such as context_length and pricing. If you have jq installed, list just the ids:
curl -s https://api.gatewayz.ai/v1/models | jq -r '.data[].id'Model ids are namespaced by provider, for example anthropic/claude-sonnet-4-6, openai/gpt-5 or moonshot/kimi-k2.6. Some ids point at a dated snapshot such as anthropic/claude-haiku-4-5-20251001. An undated alias resolves to exactly one dated snapshot, and an id that does not exist returns an error rather than a different model. Resolution, not substitution explains why that matters. Copy ids from the catalog instead of typing them from memory, since a single wrong character is enough to fail the request.
How do I send a chat completion request with curl?
Send a POST with a JSON body containing model and messages. This call goes to an Anthropic model:
curl -s https://api.gatewayz.ai/v1/chat/completions \
-H "Authorization: Bearer $GATEWAYZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-4-6",
"messages": [
{"role": "system", "content": "You answer in one short sentence."},
{"role": "user", "content": "What is an API endpoint?"}
]
}'To call an OpenAI model instead, change only the model string:
curl -s https://api.gatewayz.ai/v1/chat/completions \
-H "Authorization: Bearer $GATEWAYZ_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5",
"messages": [
{"role": "user", "content": "What is an API endpoint?"}
]
}'The request shape follows the OpenAI chat completions API reference. The messages array holds the conversation in order, each entry with a role (system, user or assistant) and content. The request and response format is the same whichever provider serves the model.
What does a successful response look like?
A successful call returns HTTP 200 and a chat completion object. The answer is in choices[0].message.content, and the token counts that determine the charge are in usage. The example below is abbreviated, with some fields omitted:
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"model": "anthropic/claude-sonnet-4-6",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "An API endpoint is a specific URL where a service accepts requests."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 24,
"completion_tokens": 14,
"total_tokens": 38
}
}prompt_tokens counts the input tokens you sent, including the system message, and completion_tokens counts the tokens the model produced. You are billed per token at the provider's list price plus a routing fee, from one prepaid balance. finish_reason tells you why generation stopped: stop means the model finished, while length means it hit a token limit and the answer may be cut off.
How do I make the same request with the OpenAI Python SDK?
Point the official OpenAI SDK at Gatewayz by setting base_url and passing your Gatewayz key. The rest of the code is ordinary OpenAI SDK usage, as described in the OpenAI Python library README.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.gatewayz.ai/v1",
api_key=os.environ["GATEWAYZ_API_KEY"],
)
response = client.chat.completions.create(
model="anthropic/claude-sonnet-4-6",
messages=[
{"role": "user", "content": "What is an API endpoint?"},
],
)
print(response.choices[0].message.content)
print(response.usage.prompt_tokens, response.usage.completion_tokens)Reading the key with os.environ["GATEWAYZ_API_KEY"] fails loudly with a KeyError if the variable is not set, which is better than sending a request with an empty key. Switching to openai/gpt-5 is again a one-line change to model.
Streaming
For interactive use, add stream=True and read the answer as it is generated:
stream = client.chat.completions.create(
model="openai/gpt-5",
messages=[{"role": "user", "content": "Explain tokens in two sentences."}],
stream=True,
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)With curl, add "stream": true to the JSON body and the response arrives as server-sent events. If a stream fails partway through, Gatewayz ends it with an explicit error event rather than simply closing the connection, so your code can tell a finished answer from a truncated one. Streaming failures agents can detect covers how to handle that.
The Anthropic Messages alternative
Gatewayz also serves the native Anthropic Messages API at https://api.gatewayz.ai/v1/messages. If your code already uses the Anthropic SDK, or you use Claude Code, set the base URL to the host https://api.gatewayz.ai and keep the Messages format. Run Claude Code through Gatewayz walks through that setup.
What do Gatewayz API errors mean?
Errors return a non-2xx status and a JSON body in the form {"error": {"message": "...", "type": "...", "code": "..."}}. The status class tells a program whether to retry. The code tells a person what to change.
| Status | Code | What it means | Retry? |
|---|---|---|---|
| 400 | model_not_found | The model id does not exist. Gatewayz never substitutes another model | No. Copy the id from the catalog |
| 401 | invalid_api_key | The key is missing, mistyped, deleted or deactivated | No. Check the header and the key |
| 402 | request_cap_exhausted | This key's request cap is spent | No. Raise the cap or use another key |
| 402 | insufficient_credits | The account balance is empty | No. Add credits |
| 429 | Rate limited | Yes, after a pause | |
| 5xx | Upstream provider or server error | Yes, with backoff |
The split between terminal and retryable statuses matters as soon as code, not a person, handles the error. The OpenAI Python SDK retries 429 and 5xx responses on its own and raises immediately on other 4xx responses, which is the right behavior with this contract. Who reads the error? explains why a typo must never look like an outage.
Why is my first request failing?
A failing first request is usually a setup mistake rather than a service problem. Check these in order before anything else.
- No doubled /v1. With the OpenAI SDK,
base_urlishttps://api.gatewayz.ai/v1and the SDK adds/chat/completions. If you setbase_urlto the full endpoint URL, or add/v1twice, the request goes to a path that does not exist. - The Bearer prefix is present. The header must read
Authorization: Bearer <key>, with the wordBearerand one space. A bare key in the header returns 401. - The environment variable is set in this shell. Run
echo ${GATEWAYZ_API_KEY:+set}. If it prints nothing, the variable is empty in the current terminal, often because it was exported in a different window or your editor did not inherit it. - The model id is copied from the catalog. Provider prefix included, exact spelling, no trailing spaces.
- The JSON is valid. A missing comma or a smart quote pasted from a document breaks the body. Single quotes around the curl
-dpayload keep the shell from altering it. - The balance and cap are not spent. A 402 is a billing or limit condition, not a bug in your code. Read the
codeto see which one.
When all six pass, the request works. If you want the shortest path to a key and a working call, the start page has it.
Frequently asked questions
Do I need a key to list models?
No. https://api.gatewayz.ai/v1/models is public, so you can check which model ids exist before creating a key. You need a key only to send requests to /v1/chat/completions or /v1/messages.
Can I use my existing OpenAI code with Gatewayz?
Usually yes, if it uses chat completions. Set the SDK's base_url to https://api.gatewayz.ai/v1, use your Gatewayz key, and change the model to a provider-namespaced id such as openai/gpt-5. The request and response shapes stay the same, so parsing code that reads choices[0].message.content keeps working.
Why did I get 400 model_not_found for a model I know exists?
The id you sent is not an exact match for anything in the catalog. The usual causes are a missing provider prefix, a typo, or a snapshot date that is not offered. Gatewayz returns 400 rather than quietly serving a different model, so copy the id directly from the /v1/models response.
Should my code retry a 402 response?
No. Both 402 codes, request_cap_exhausted and insufficient_credits, are terminal. The request will keep failing until someone raises the key's cap or adds credits, so the right response is to stop and alert a person. Retry only 429 and 5xx responses, with a pause between attempts.
Where do I set the key for Claude Code instead?
Claude Code uses the Anthropic Messages format, so it takes ANTHROPIC_BASE_URL=https://api.gatewayz.ai and ANTHROPIC_AUTH_TOKEN set to your Gatewayz key. Note the base URL is the host without /v1. The Claude Code guide has the full setup and verification steps.
Related
- Run Claude Code through Gatewayz. The Anthropic Messages setup.
- How Gatewayz keeps your API keys and data secure. Key handling from day one.
- Who reads the error?. Why status codes are control flow.
- AI tokens and pricing. What prompt and completion tokens cost.
- APIs, endpoints and keys. The vocabulary behind this guide.
