API / send-safety-identifier-on-grok-api

API

Send a safety_identifier on Grok API requests

Attach an opaque safety_identifier on each request so that when a completion violates xAI usage policy, the report can name one of your end users instead of blaming the whole API key. Official Security FAQ documents the field as a stable string your application assigns — end users never choose it — and says to hash an internal user id rather than send an email, phone number, or display name. The same field works on Chat Completions, the Responses API (including streaming and WebSocket mode), deferred chat completions, the Batch API, and the gRPC GetCompletionsRequest. Create a key and load credits at console.x.ai.

What you need

An XAI_API_KEY, a stable internal user id you can hash per request, and a gateway or product path that fans many end users through one team key (OpenRouter-style platforms are the usual case). Neighboring jobs include Use priority processing when latency tiers matter on the same Responses body, Continue an agentic conversation with store_messages when you also preserve tool state across turns, and Mix client-side and server-side tools on Grok for hybrid tool loops. More API jobs live on the API hub.

Attach safety_identifier on Responses

  1. Export the key outside of source control, then hash a stable internal user id (example: SHA-256 hex of your database user primary key) so the value you send cannot be reversed to PII:
export XAI_API_KEY="your_api_key"
export SAFETY_ID="$(printf '%s' 'user_12345' | sha256sum | awk '{print $1}')"
  1. Send the hashed value on a Responses call:
curl https://api.x.ai/v1/responses \
  -H "Authorization: Bearer $XAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{
    \"model\": \"grok-4.7\",
    \"input\": \"What is the meaning of life?\",
    \"safety_identifier\": \"$SAFETY_ID\"
  }"
  1. Or pass the same field through an OpenAI-compatible client pointed at https://api.x.ai/v1:
import hashlib
import os
from openai import OpenAI

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

safety_id = hashlib.sha256(b"user_12345").hexdigest()

response = client.responses.create(
    model="grok-4.7",
    input="What is the meaning of life?",
    safety_identifier=safety_id,
)

print(response.output_text)
  1. Repeat the same field on Chat Completions, deferred completions, Batch request rows, and Responses WebSocket response.create bodies when those surfaces share the key. The legacy user field still works for compatibility; prefer safety_identifier going forward so abuse mail references the documented name.

After a policy contact

When xAI contacts your team about a violation, match the identifier in the notice to your hash table and act on that end user (suspend, rate-limit, or investigate) without rotating the whole team key. Gateways should set the field per end user on every forward so a single abusive client cannot hide behind the platform key.

Pitfalls

Sending an email or display name as safety_identifier puts PII into an abuse-attribution channel the docs tell you to keep opaque. Omitting the field on a multi-tenant gateway forces xAI to attribute abuse to your API key alone. Assuming user and safety_identifier are different namespaces for the same request can confuse logs — pick one stable hash and stick to safety_identifier. Mixing Console API credits with SuperGrok weekly pools on grok.com confuses two different meters the docs keep separate.