The intern named the gist demo-grok-ping.py and pasted a key that starts with xai- into a public GitHub gist at 7:19 p.m. By 11:07 a.m. Slack #eng-alerts shows $184.20 of xAI spend in 40 minutes. The log says 12,041 requests. The script retried on every 429 with no sleep, and the gist still had the key in plaintext when finance pinged.
This is Part 11 of the Grok series, last door on the product map. Part 8 said the Console is for apps. Part 10 kept mail in a work add-in. Here you open console.x.ai only when you need a key, you make one small request, and you treat chat-plan money as a different wallet from API credits. If you only write, summarize Outlook, or try Imagine in the consumer studio, you can bookmark this page and come back the day you ship a bot. Most AMS readers should not mint a key because a thread said “real builders use the API.”
Who needs the Console, and who should stay
- Who needs the Console, and who should stay in chat
- How to create a key, set
XAI_API_KEY, hithttps://api.x.ai/v1, and run onecurlagainst the Responses API - How to call the same endpoint with the OpenAI-compatible Python client
- Why SuperGrok (or paid X) does not fund that
curl - Why Imagine API ids are a separate meter from
grok-4.6 - A worked mini request, plus the three-line result you should see on a toy prompt
As of writing, docs and keys live at x.ai/api and console.x.ai. Model ids, base URLs, and list prices move. Re-check the week you ship. Do not paste a real key into this post, a gist, Slack, or a screenshot. Examples below use xai-... as a shape, never as a secret.
Who needs the Console
You need the Console when software will call Grok without you clicking Send. A daily Slack stub that defines “pick wave” from a README. An IDE plugin on a laptop that is not Grok Build. A backend that classifies inbound tickets. A notebook that scores 200 rows overnight. Those are apps. They need a key, a spend cap, logging, and someone who owns retries.
You do not need the Console to chat on grok.com (see Part 2), to run the Outlook add-in from Part 10, to open Imagine in the consumer studio, or to use Grok Build under a chat plan that includes it. Build can authenticate in a browser on first launch. Headless Build can take XAI_API_KEY, which is a reason to be careful, not a reason to mint a key for a huddle note. If the caller is you, stay in the app. If the caller is a process, keep reading.

Kenji (the intern) needed a demo for a lunch-and-learn. A grok.com thread would have been enough. A public gist with a live key is how you buy a $184.20 story. The test for “do I need the Console” is not “will I type Python.” It is “will this still run at 2 a.m. if I close my laptop.” If no, you wanted chat.
Keys, base URL, first curl
Sign up or log in at console.x.ai. Open API Keys. Create one key. Name it for the environment (shipments-dev, not key). Copy it once. Store it in an environment variable. Never commit it. Never paste it into grok.com “for safekeeping.” Work secrets still follow Part 6.
export XAI_API_KEY="xai-..."The HTTP base URL as of writing is https://api.x.ai/v1. The first request in current docs uses the Responses API: POST /v1/responses with a model id and an input string. Chat Completions also exists. This tutorial uses Responses because that is the snippet xAI prints first. If your copy of the docs has moved, follow the live page, not this paragraph’s path.
Toy prompt: we want a grain sentence an analyst can paste into a README. One row is one shipment. Columns are ship_date, units, region. That is small enough to read, and wrong answers are obvious (if the model says “one row is a customer,” you caught it).
curl https://api.x.ai/v1/responses \
-H "Authorization: Bearer $XAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-4.6",
"input": "One row is one shipment. Columns: ship_date, units, region. Write a one-sentence grain definition a new analyst can paste into a README."
}'If $XAI_API_KEY is empty, you will get an auth error, not a grain sentence. If the key is a chat-plan password, you will also get an auth error. Console keys start with xai- as of writing. Your Microsoft login is not a Bearer token. Your SuperGrok cookie is not a Bearer token.
Spend a minute on the boring Console settings before you loop. Set a monthly credit limit you would not mind explaining. Create a separate key per environment. If the vendor UI offers IP allow lists or key expiry, turn on what you can live with. Kenji’s gist would still have been a mistake with a $5 cap, but it would have been a $5 mistake. $184.20 in 40 minutes is a retry loop plus no cap plus a public secret.
OpenAI-compatible client
You can call the same API with xAI’s own SDK. Many teams already have the OpenAI Python client. As of writing, that client works if you point base_url at https://api.x.ai/v1 and pass the xAI key. Install with pip install openai. Pin versions in real apps. This snippet is the smallest path that prints text.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("XAI_API_KEY"),
base_url="https://api.x.ai/v1",
)
response = client.responses.create(
model="grok-4.6",
input="One row is one shipment. Columns: ship_date, units, region. Write a one-sentence grain definition a new analyst can paste into a README.",
)
print(response.output_text)Two details that bite. First, base_url must be the xAI host. If you leave the OpenAI default, you will bill the wrong vendor or fail auth. Second, the method is client.responses.create in this snippet, matching the curl. Older examples on the internet still show chat.completions.create with a messages array. Both can be valid on this API family as of writing. Pick one, log the id, and do not mix snippets from three blogs in one file.
Do not put the key in the Python file. os.getenv exists for this. If getenv returns None, fail loud on startup. A retry loop that sends Authorization: Bearer None 12,041 times is how you get a different kind of alert.
Chat sub vs API money
Say it so finance can hear it. A SuperGrok or paid X subscription pays for a human using chat apps, and as of writing it is also how xAI has gated some consumer features (Outlook add-in, Grok Build eligibility). API credits pay for tokens your code spends in the Console. They do not refill each other. Buying $25 of API credits does not unstick Imagine on a phone. Paying SuperGrok does not authorize curl.
List prices on docs as of writing for Grok 4.6 sit at $2 per million input tokens and $6 per million output tokens. The Grok 4.5 launch post printed the same pair. That is a vendor list, not a quote. Batch, caching, image, and video meters are extra lines. Your team’s live rate card is in the Console. Budget from that, then add a cap that pages a human.
Retries are a billing feature whether you meant them or not. HTTP 429 means slow down. A while True that ignores 429 is a spend accelerator. Kenji’s 12,041 calls were not 12,041 users. They were one script that refused to sleep. If you need retries, cap them (three), back off (seconds, then more seconds), and log the request id. If you do not know how to do that yet, you are not ready for a public gist, and you might not be ready for a key.
Imagine endpoints are extra
Text models and Imagine models do not share a “Grok call” bucket in your head, even if they share a Console login. Image generation as of writing uses ids such as grok-imagine-image-2.0 and a different path (/v1/images/generations in the current quickstart). Video is another family. Putting grok-4.6 in an image payload, or putting an Imagine id in the Responses model field you copied from above, is how you get a 400 and then a confused Slack thread.
Consumer Imagine at grok.com/imagine can stay on the chat-plan side. You only need the Imagine API when your app, not you, must render stills. That is a real product (a pipeline that stamps labels on 200 SKUs overnight). It is not “the intern wanted a poster for lunch-and-learn.” Posters still go through the studio. Apps that emit images go through the Console, on purpose, with a cap.
Docs: Imagine capabilities and the Image 2.0 news post. Re-check ids. This map only needs the split: extra endpoint, extra meter, extra chance to leak a key in a render job that retries.
Worked mini request
You are not Kenji. You are going to run the toy grain prompt once, on a key that never leaves your machine, with no loop. Then you revoke the key if this was only a lesson.

- Create a key named
grain-lessonin the Console. Load $5 of credits or whatever the minimum is this week, not $200. - Export
XAI_API_KEYin that terminal only. Confirm withecho ${#XAI_API_KEY}(a length, not the secret). - Run the
curlfrom above exactly once. - Read the text. Does one row mean one shipment? If the sentence smuggles in customers or revenue, the model drifted. You still learned the plumbing.
- Run the Python snippet once. Confirm you get a sentence, not a stack trace about
base_url. - Revoke
grain-lessonif you do not have an app. If you do, rotate to a server-side secret store the same day.
What that toy request should look like when it works (made-up body, real shape). Your wording will differ. The grain must still say shipment, not customer.
| Field | Toy value |
|---|---|
| HTTP | 200 |
| model | grok-4.6 |
| output_text | One row means one shipment leaving the warehouse, with the calendar ship date, the unit count, and the region on that row. |
If you get 401, the key is missing, truncated, or from the wrong product. If you get 429 on the first call, wait. Do not wrap the curl in a bash until loop. If you get a sentence about customers, you still have a working pipe. Fix the prompt. Do not add retries to chase a better vibe.
That is the whole first app: one request, one check, one secret that dies if it was only homework. The 12,041-request version is the same homework without the word “once.”
Open the Console only when software
| Mistake | What you see | Fix |
|---|---|---|
| Key in a gist, chat, or screenshot | Spend alerts, or a stranger’s script on your wallet | Revoke now. Env var or a secret store. Never xai- in git |
| Retry loop on 429 | Thousands of requests, one user | Cap retries. Sleep. Log. Then stop |
| Expecting SuperGrok to auth curl | 401 with a chat login | Console key, separate credits |
Wrong base_url | Auth errors or the wrong vendor’s bill | https://api.x.ai/v1 as of writing |
| Imagine id on a text call (or the reverse) | 400, or a weird empty image | Text ids for Responses. Imagine ids for image routes |
| Minting a key for a huddle note | A secret with no app | Use grok.com. No app, no key |
Open the Console only when software is the (build)
If you have no app, skip the key. Write one sentence in a doc: “We would need the API if ___ ran without a person clicking Send.” If the blank is empty, you are done with the product map. If the blank is a real bot, run the six-step mini request on a $5 cap, then revoke or store the key like it is a production password, because it is.
The product map ends here. Next in this series is everyday work: Grok for writing, explaining, and brainstorming (Part 12). That is the writing habit this series covers before anyone needs curl. Find it from the Grok series hub when it is up. If you still cannot name the four doors, go back to Part 8. If your next idea is “put Grok on every intern laptop with a shared key,” reread Kenji’s gist time stamps first.
Open the Console only when software is the 3
- Open the Console only when software is the caller
- Key in
XAI_API_KEY. Base URLhttps://api.x.ai/v1. Model id from docs, as of writinggrok-4.6 - First call: Responses API via
curl, then the OpenAI-compatible Python client withbase_urlset - Chat plans and API credits are separate wallets
- Imagine API ids and routes are extra meters
- One request, read the grain sentence, cap or revoke the key
- Never gist a key. 12,041 retries is a loop, not traffic
Sources
Research and further reading used for this article:
- xAI Console (sign up, API keys, credits)
- xAI API (live models, pricing entry, builder landing)
- xAI docs: Grok 4.6 (API id, list price to re-check, Responses examples)
- xAI docs: Imagine capabilities (separate image/video ids and routes)
- xAI: Imagine Image 2.0 (consumer vs API family)
- xAI docs: Grok Build overview (when a chat-plan agent is enough and a key is optional)
- Grok FAQ (plan vs product questions)
- Analytics Made Simple: Learn (related paths on this site)
