API / authenticate-with-mtls

API

Authenticate with mTLS

Authenticate with mTLS

mTLS is an enterprise feature. Contact support@x.ai with your team ID (from the xAI Console), your CA certificate in PEM format, and the Common Name (CN) from the client certificates your systems will use. xAI configures the team and confirms when mTLS is active. Config is team-level: every API key on the team shares it.

Point requests at https://mtls.api.x.ai. All paths work the same (/v1/chat/completions, /v1/responses, /v1/embeddings, and the rest). Keep sending Authorization: Bearer with your API key. mTLS sits on top. Certs are X.509 PEM for both the CA (provided at setup) and the client certificates.

If mTLS is required for the team, requests to api.x.ai are rejected because no client certificate is presented. mTLS is currently on the global mtls.api.x.ai endpoint. For regional mTLS, contact support.

curl

curl https://mtls.api.x.ai/v1/chat/completions \
  --cert /path/to/client-cert.pem \
  --key /path/to/client-key.pem \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -d '{
    "messages": [
      {
        "role": "user",
        "content": "Hello, world!"
      }
    ],
    "model": "grok-4.6",
    "stream": false
  }'

Test the handshake

curl -v https://mtls.api.x.ai/v1/api-key \
  --cert /path/to/client-cert.pem \
  --key /path/to/client-key.pem \
  -H "Authorization: Bearer $XAI_API_KEY"

403 Forbidden points at a cert problem. 401 Unauthorized points at a key problem.

OpenAI Python with httpx

import os
import httpx
from openai import OpenAI

http_client = httpx.Client(
    cert=("/path/to/client-cert.pem", "/path/to/client-key.pem")
)

client = OpenAI(
    api_key=os.getenv("XAI_API_KEY"),
    base_url="https://mtls.api.x.ai/v1",
    http_client=http_client,
)

completion = client.chat.completions.create(
    model="grok-4.6",
    messages=[
        {"role": "user", "content": "Hello, world!"}
    ]
)
print(completion.choices[0].message.content)

OpenAI JavaScript

import OpenAI from 'openai';
import https from 'https';
import fs from 'fs';

const client = new OpenAI({
    apiKey: process.env.XAI_API_KEY,
    baseURL: 'https://mtls.api.x.ai/v1',
    httpAgent: new https.Agent({
        cert: fs.readFileSync('/path/to/client-cert.pem'),
        key: fs.readFileSync('/path/to/client-key.pem'),
    }),
});

Certificate rotation

Change Action
Same CA, same CN, new client cert Nothing to do. Start using the new cert.
Updated CA or new intermediate Contact support@x.ai to upload the updated CA bundle.
Different CA entirely Contact support@x.ai to register the new CA.

Pitfalls

  • Enterprise setup through support@x.ai. There is no self-serve Console toggle.
  • Keep sending the Bearer API key on every request.
  • 403 = cert. 401 = key. Use GET /v1/api-key on mtls.api.x.ai to test.
  • Regional mTLS needs support. Global endpoint only for now.
  • Console API credits are separate from SuperGrok's weekly pool on grok.com.