Claude's API Can Now Ban One Customer Instead of Your Whole Org. Its Webhook Isn't Live Anthropic released user profiles for the Claude API on October 20, letting SaaS apps, gateways and resellers tag each request with a per-customer ID so that an enforcement action against one end customer no longer applies to the whole organization. A day later the company added enforcement_status and enforcement_actions response fields, but the webhook meant to notify developers of a customer ban accepts registrations and does not yet deliver events, per Anthropic's documentation. Profiles are created via POST /v1/user_profiles and passed in the anthropic-user-profile-id header, and the call is not idempotent, so developers must store the uprof_ ID at onboarding. You run a SaaS app, a gateway or a reseller on the Claude API. Every request you send for your customers arrives under one organization: yours. Anthropic's own docs spell out what that has meant until now: "one end customer can trigger an enforcement action that applies to your whole organization" Anthropic, user profiles https://platform.claude.com/docs/en/manage-claude/user-profiles . On October 20, Anthropic shipped the fix: user profiles https://platform.claude.com/docs/en/release-notes/overview , so you can tell it which end customer each API request is for. On October 21 it added enforcement status and enforcement actions fields, so you can see whether Anthropic has restricted or banned one of your customers release notes https://platform.claude.com/docs/en/release-notes/overview . MIXED News https://mixed-news.com/en/claude-api-user-profiles-ban-one-customer-not-whole-account/ summed it up as resellers being able to get "one customer banned instead of their whole account." There's a catch in the fine print. The webhook that's supposed to tell you when a customer gets banned exists, takes registrations, and sends nothing. Anthropic's docs say so in a note: "Event delivery isn't live" organization webhooks https://platform.claude.com/docs/en/manage-claude/organization-webhooks . A profile is a record you create once per end customer with POST /v1/user profiles . It returns an ID that starts with uprof , and you send that ID in the anthropic-user-profile-id header on every request you make for that customer docs https://platform.claude.com/docs/en/manage-claude/user-profiles . When a safety action hits that profile, "the rest of your traffic is unaffected," per the same page. Two details make it easy to adopt: Who gets a profile depends on what you sell. A signed-up user of your app gets an application profile, the default. A company you resell API access to gets one passthrough profile for the whole company, not one per employee docs https://platform.claude.com/docs/en/manage-claude/user-profiles . A request with no profile ID counts as your own usage, and Anthropic recommends keeping that usage in a separate organization, because profiles belong to an organization, not a workspace docs https://platform.claude.com/docs/en/manage-claude/user-profiles . The SDKs take the ID as an argument. This is the Python call from Anthropic's page, with the import and the stored ID added and the print removed: python import anthropic profile id = "uprof ..." the ID you stored at signup client = anthropic.Anthropic message = client.messages.create model="claude-opus-5-5", max tokens=1024, messages= {"role": "user", "content": "Hello, Claude"} , user profile id=profile id, The same header works on token counting, Message Batches and the OpenAI SDK compatibility endpoint docs https://platform.claude.com/docs/en/manage-claude/user-profiles . With a profile on each request, a restriction can land on one customer's window instead of the whole building. 1. Creating a profile isn't idempotent. "Every call creates a new profile, even when reference id matches an existing one" docs https://platform.claude.com/docs/en/manage-claude/user-profiles . Create it in your onboarding flow, store the uprof ID on the customer record, and have every service read it from there. A worker that calls create on startup will mint a new profile per boot. 2. An old beta header hides the ban fields. Responses leave out enforcement status and enforcement actions when your anthropic-beta header carries user-profiles-2026-09-04 or an earlier value, and the enforcement status list filter returns a 400 webhooks docs https://platform.claude.com/docs/en/manage-claude/organization-webhooks . If you adopted profiles during the beta, remove that value. 3. Bedrock and Google Cloud don't look the profile up. Profiles also work on Claude in Amazon Bedrock and on Claude Models on Google Cloud Google managed , but you create them on the Claude API or Claude Platform on AWS. Those two platforms check only the ID's format. "They accept any well-formed ID, so a successful response doesn't confirm that the ID matches a profile" docs https://platform.claude.com/docs/en/manage-claude/user-profiles . On Bedrock, the ID goes in a user profile id field in the request body, not a header, and the older InvokeModel and Converse integration doesn't support it at all. 4. On Claude Platform on AWS, the fields always say unrestricted. There, enforcement status is always unrestricted and the actions list is always empty, and Anthropic doesn't refuse requests there because of an open action docs https://platform.claude.com/docs/en/manage-claude/user-profiles . 5. You can't clear a field. You can replace a value in external user details , but the API rejects null with a 400 docs https://platform.claude.com/docs/en/manage-claude/user-profiles . If you don't know a customer's country, leave it out rather than sending a placeholder you can never remove. Each profile now reports enforcement status as unrestricted , restricted or banned the API reference https://platform.claude.com/docs/en/api/user profiles/list also lists pending , while an identity check is under review . "While an action is open, Anthropic refuses some or all inference requests that carry the profile's ID" docs https://platform.claude.com/docs/en/manage-claude/user-profiles . Each entry in enforcement actions has a type restriction or ban , a reason such as fraud or abuse or account compromise , an action the customer can take or null , and an expires at time or null . The docs also tell you how to handle values they haven't invented yet: treat an unknown enforcement status as restricted and an unknown reason as unspecified docs https://platform.claude.com/docs/en/manage-claude/user-profiles . In code, that's one line with a fallback: python KNOWN = {"unrestricted", "restricted", "banned"} def effective status raw: str - str: Anthropic can add values; fail toward caution. return raw if raw in KNOWN else "restricted" Knowing a customer is restricted lets your app show them a real message instead of a stream of failed requests, and lets your support team see the reason before the customer opens a ticket. Anthropic also added organization webhooks https://platform.claude.com/docs/en/manage-claude/organization-webhooks in beta, behind the webhooks-2026-10-07 header. They define two events, user profile.enforcement action opened and user profile.enforcement action resolved . To get access, you contact your Anthropic account team docs https://platform.claude.com/docs/en/manage-claude/organization-webhooks . Then comes the note: "Anthropic doesn't send the two events, so an endpoint you register receives nothing" docs https://platform.claude.com/docs/en/manage-claude/organization-webhooks . You can build the handler today. You can't rely on it today. The enforcement webhook is wired to nothing for now. A scheduled check is the doorbell that works. Even once delivery goes live, the docs describe a webhook you can't treat as the source of truth docs https://platform.claude.com/docs/en/manage-claude/organization-webhooks : id . Deduplicate on it. resolved event. Deliveries follow the Standard Webhooks https://www.standardwebhooks.com/ spec, so verify the webhook-signature header with your endpoint's whsec secret, and return a 2xx within 5 seconds before doing slow work docs https://platform.claude.com/docs/en/manage-claude/organization-webhooks . Every path above ends at the same call. Anthropic's own catch-up advice is to list your profiles https://platform.claude.com/docs/en/api/user profiles/list filtered by status docs https://platform.claude.com/docs/en/manage-claude/organization-webhooks : curl -g "https://api.anthropic.com/v1/user profiles\ ?enforcement status =restricted&enforcement status =banned" \ -H "x-api-key: $ANTHROPIC API KEY" \ -H "anthropic-version: 2023-06-01" The -g flag stops curl from treating the brackets as a glob. A page can come back with fewer profiles than limit , or none, before the list ends, so keep requesting pages until next page is null docs https://platform.claude.com/docs/en/manage-claude/organization-webhooks . Also, a status change "doesn't reliably move updated at ," so compare the two enforcement fields with the values you last stored, not the timestamp docs https://platform.claude.com/docs/en/manage-claude/user-profiles . Run that on a schedule now. When event delivery goes live, keep the job as the reconciliation pass behind the webhook. The webhook tells you sooner; the scheduled list call catches whatever it repeats, reorders or drops. Profiles are optional, so a platform that skips them keeps the old risk MIXED News https://mixed-news.com/en/claude-api-user-profiles-ban-one-customer-not-whole-account/ . If you send traffic for other people, creating a profile per customer and sending one header is a cheap way to keep one bad customer's ban from landing on everyone else. Are you creating profiles at signup, or backfilling an existing customer base first? A ban webhook that can repeat, reorder and drop events is the textbook case for idempotent consumers and a reconciliation job. If you're wiring one up, my Event-Driven Architecture Pocket Guide https://www.amazon.com/dp/B0GX3B8371 walks through the event-driven patterns around it: sagas, CQRS, the outbox, and the traps nobody warns you about. It's one of 8 short books in the Pocket Guides for Developers https://www.amazon.com/dp/B0GYLH38X4 series, covering agents, RAG, prompts, observability, events, databases and system design. I also build Hermes IDE, a free desktop app for running Claude Code, Codex and other coding agents side by side, each on its own branch: download it https://hermes-ide.com/download or star it on GitHub https://github.com/hermes-hq/hermes-ide .