A 401 means the request was rejected before any model saw it. Nothing about your prompt, model choice or payload is relevant. Work through these in order; the first three account for most cases.
1. The variable is empty
By far the most common cause. The code reads a key from the environment, the environment does not have it, and an empty string is sent as a perfectly well-formed credential.
Check that the variable is actually set in the process that is running, not in
your shell, not in a .env file that is loaded somewhere else, not in your
deployment's other environment. Print its length (never its value) at startup and
you will find this in seconds.
2. The header is malformed
The API expects the key in an Authorization header using the Bearer scheme.
Two classic mistakes: sending the key without Bearer , and sending
Bearer: <key> with a stray colon. If you are using an official SDK, do not set
this header yourself; pass the key to the client and let it build the header.
3. Whitespace
A key copied from a console or a chat message often carries a trailing newline or
a leading space, and neither is visible when you print it. Trim the value where
you read it. If you exported it in a shell, re-check for a trailing space after
the =.
4. The key was revoked: rotated or deleted
Keys stop working when someone rotates them, when a trial ends, or when the key was deleted from the console. Check the key's status in the xAI console, linked from x.ai/api. If a key has ever been pasted into a ticket, a screenshot or a chat, rotate it now and treat this 401 as the good outcome.
5. Wrong provider entirely
An OpenAI-style API means SDKs are interchangeable, which means it is easy to
point an SDK at xAI while it still reads OPENAI_API_KEY, or to send an xAI key
to a different vendor's endpoint. Confirm that the base URL and the key come from
the same provider.
Note also that "Grok" (xAI) and "Groq" (a different company) are one character apart. Their keys, endpoints and docs are unrelated, and mixing them produces exactly this error.
6. The key belongs to a different team or project
Where keys are scoped to a team, workspace or project, a key from one does not authenticate against another's resources. Check which team the key was created under.
What to do next
If all six check out, generate a fresh key, use it directly in a single manual request with nothing else changed, and see whether that works. That isolates "the credential" from "how the credential reaches the code", and the answer tells you which half to keep looking at.
What changes
Header format and key management are stable, but console layout and key scoping options do change. docs.x.ai is authoritative.