This page deliberately does not reprint a copy-paste snippet. Model names and request details change, and a stale snippet on a third-party site is worse than no snippet; the canonical, current one is in xAI's own docs. What follows is the part that does not go stale: the pieces, and what to decide about each.
The four pieces of a request
The key. Created in the xAI console, linked from x.ai/api. It belongs in an environment variable or a secret manager, never in source control, never in a browser bundle. If a key has ever been pasted into a chat, a ticket or a screenshot, rotate it.
The base URL. xAI exposes an OpenAI-style HTTP API at https://api.x.ai/v1,
which is why existing SDKs work: you point the client's base URL at xAI and pass
your key, and the rest of your code is unchanged. Using an existing SDK is
usually less work than hand-rolling requests.
That compatibility has a sharp edge worth knowing about early: several parameters from the OpenAI shape are accepted and then silently ignored. See The Grok API accepted your parameter and ignored it.
The model name. A string, and the most volatile part of your integration. Read it from configuration rather than hard-coding it in three files; see Keeping up when Grok changes. The current list is on the models page.
The messages. A conversation is an ordered list of role-tagged messages that you resend on every call. The API is stateless: it does not remember the previous turn, you do. That surprises people coming from the chat app, and it is the root of a large share of "it forgot what I said" bugs.
Four decisions to make before request number two
Where does the model name live? One place, read from config.
What happens on 429? Rate limits are a normal operating condition, not an exception. Retry with exponential backoff and jitter from the beginning; see 429: rate limited.
Streaming or not? Streaming is better UX and more code: partial output, mid-stream failures, and a different error path. Decide before you build the UI around it.
Either way, raise your client timeout. A reasoning model can think for a long time before the first token appears, and default HTTP client timeouts are nowhere near generous enough; xAI's own examples set them to an hour. A premature client-side close looks exactly like a hung API.
What do you log? At minimum: the model name, the token usage, and a request identifier. Diagnosing anything without these is guesswork.
Two surfaces worth knowing exist
Batch. If the work is not latency-sensitive, the batch surface is billed at a discount and does not count against your rate limits at all. Many teams building "process these ten thousand records" jobs do it the hard way against the interactive endpoint first.
Prompt caching. Repeated prefixes can be billed more cheaply. Two things to know before you rely on it: a cache miss is normal and never an error, and cached tokens still count toward your token rate limit even when they cost less.
Before you ship
- Cost: usage is priced per token and differs per model. Read the current pricing page and do the arithmetic for your expected volume before you find out empirically.
- Failure: decide what your product does when the API is unavailable. "Nothing, and the page hangs" is a decision too, just not a good one.
- Privacy: know what you are sending. Whatever your users typed is now leaving your infrastructure, and your privacy policy should already say so.
What changes
Model names, context limits, pricing, rate-limit tiers and available parameters all change. Everything specific belongs in docs.x.ai; everything on this page is meant to survive the next release.