,

xAI Console and API: only if you build apps

11 min read
xAI Console and API: only if you build apps, with the official product logo. Editorial illustration for Analytics Made Simple.

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, hit https://api.x.ai/v1, and run one curl against 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.

When to open the xAI Console: yes if software will call the model on a schedule or for many users, no if you only need chat, Outlook, consumer Imagine, or Grok Build under a chat plan
When to open the xAI Console: yes if software will call the model on a schedule or for many users, no if you only need chat, Outlook, con…

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.

First API checklist: mint a named key in console.x.ai, export XAI_API_KEY, send one Responses request with grok-4.6, read the grain sentence, revoke or cap the key, never gist the secret
First API checklist: mint a named key in console.x.ai, export XAI_API_KEY, send one Responses request with grok-4.6, read the grain sente…
  1. Create a key named grain-lesson in the Console. Load $5 of credits or whatever the minimum is this week, not $200.
  2. Export XAI_API_KEY in that terminal only. Confirm with echo ${#XAI_API_KEY} (a length, not the secret).
  3. Run the curl from above exactly once.
  4. 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.
  5. Run the Python snippet once. Confirm you get a sentence, not a stack trace about base_url.
  6. Revoke grain-lesson if 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.

FieldToy value
HTTP200
modelgrok-4.6
output_textOne 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

MistakeWhat you seeFix
Key in a gist, chat, or screenshotSpend alerts, or a stranger’s script on your walletRevoke now. Env var or a secret store. Never xai- in git
Retry loop on 429Thousands of requests, one userCap retries. Sleep. Log. Then stop
Expecting SuperGrok to auth curl401 with a chat loginConsole key, separate credits
Wrong base_urlAuth errors or the wrong vendor’s billhttps://api.x.ai/v1 as of writing
Imagine id on a text call (or the reverse)400, or a weird empty imageText ids for Responses. Imagine ids for image routes
Minting a key for a huddle noteA secret with no appUse 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 URL https://api.x.ai/v1. Model id from docs, as of writing grok-4.6
  • First call: Responses API via curl, then the OpenAI-compatible Python client with base_url set
  • 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: