User profiles: stop one end customer from getting your whole API organization banned
In brief
On October 20, 2026 Anthropic launched user profiles, which tag each API request with the end customer it is for, so a safety restriction lands on that customer instead of your whole organization. Organization webhooks (beta) tell you when it happens. Who needs this, and how to wire it in.
Contents
On October 20, 2026, Anthropic launched user profiles on the Claude API. A user profile is a record you create for one of your end customers. You then send its ID on every request you make for that customer. If Anthropic's safety systems decide that customer is misusing Claude, the restriction or ban applies to that one profile. The rest of your traffic keeps working.
At the same time, Anthropic added organization webhooks in beta. A webhook is a URL on your server that Anthropic calls when something happens. Here it fires when one of your profiles is restricted or banned, and again when that ends.
Who needs this
Anyone who sends other people's requests to Claude under their own API key:
- SaaS products with a Claude-powered feature that thousands of users can type into.
- Gateways and resellers that sell API access to other companies.
- Agencies and platforms running Claude for several clients from one organization.
Anthropic runs automated safety classifiers over API traffic. Before this launch, every request from your organization looked like it came from you. If one of your users tried to get Claude to write malware, the enforcement action could land on your organization, and every customer you have would lose service. User profiles give Anthropic a way to separate that one user from everyone else.
If you only use Claude internally, for your own employees, you don't need profiles. A request with no profile ID counts as your organization's own usage.
Decide what a profile stands for
A profile has an access_type with two values:
| You sell Claude to... | One profile per... | access_type |
|---|---|---|
| People who sign up for your product | User, created at signup | application (the default) |
| Companies that buy API access through you | Company, not each person inside it | passthrough (you must send it) |
Profiles belong to the organization, not to a workspace, so a profile ID works across every workspace in that organization. Anthropic recommends keeping end-customer traffic in one organization and your own internal usage in a separate one. Separate workspaces in one organization are not enough.
Profiles are free and don't change your pricing.
Step 1: create a profile when a customer signs up
You need a regular API key, not an Admin API key. This example registers a company that buys access through a gateway:
import anthropic
client = anthropic.Anthropic()
profile = client.user_profiles.create(
name="Acme Analytics, Inc.",
access_type="passthrough",
external_user_details={"reference_id": "cust-8f2a1c", "country": "US"},
)
# Store this on your customer record: "uprof_011CZk..."
print(profile.id)
Things to know about the fields:
- Every field is optional. Leave out anything you don't know instead of sending a placeholder. Once a value is set in
external_user_details, you can replace it but not clear it. reference_idis your own ID for the customer. It doesn't have to be unique.countryis the customer's country, not yours.- Privacy: if you can't share a name or email, send
name_hashandemail_hashinstead. Use the same hash function and normalization every time, or the hashes won't match across profiles.
POST /v1/user_profiles is not idempotent. Each call creates a new profile, even with the same reference_id. Create it once in your onboarding flow, save the ID on the customer record, and have every service read it from there. If you have an existing customer base to backfill, Anthropic asks you to contact your account team first, because profile creation is rate limited.
Step 2: send the profile ID on every request
The ID goes in the anthropic-user-profile-id header. The SDKs take it as an argument:
message = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
messages=[{"role": "user", "content": user_input}],
user_profile_id=customer.anthropic_profile_id,
)
const message = await client.messages.create({
model: "claude-opus-5-5",
max_tokens: 1024,
messages: [{ role: "user", content: userInput }],
user_profile_id: customer.anthropicProfileId,
});
The same header works on token counting, Message Batches (it applies to every request in the batch), and the OpenAI SDK compatibility endpoint.
For a passthrough profile, the profile identifies the company, not the person typing. If you know which person sent a request, also put an identifier for them in the Messages request's metadata.user_id field. That helps Anthropic narrow misuse down to one person.
A wrong ID fails loudly. On the Claude API, Claude Platform on AWS, and Microsoft Foundry deployments hosted on Anthropic, a malformed ID or one from another organization returns a 400. Test this path before you ship, because a bug that sends the wrong customer's ID will break that customer's requests.
On Amazon Bedrock or Google Cloud
You can't create profiles there. Create them in an organization on the Claude API or Claude Platform on AWS, then:
- Google Cloud: send the same
anthropic-user-profile-idheader. - Claude in Amazon Bedrock: put
user_profile_idat the top level of the request body. The older Bedrock integration (InvokeModel/Converse) doesn't support profiles.
Then link each AWS account or Google Cloud project to your Anthropic organization in the Verification Portal at portal.anthropic.com, under Linked accounts. These platforms check only the ID's format. They don't look the profile up, so a successful response doesn't prove the ID is right.
Step 3: hear about enforcement actions (beta)
Organization webhooks use the Admin API under /v1/organizations/webhooks with the webhooks-2026-10-07 beta header. Access is by request through your Anthropic account team. Only admins and owners can create endpoints.
endpoint = client.beta.organization.webhooks.create(
url="https://example.com/anthropic-webhooks",
name="Enforcement actions",
enabled_events=[
"user_profile.enforcement_action_opened",
"user_profile.enforcement_action_resolved",
],
)
# endpoint.signing_secret is only returned now. Store it.
The event carries IDs only: data.id is the profile, data.enforcement_action_id is the action. To see what happened, fetch the profile with GET /v1/user_profiles/{id} and read its enforcement_status (unrestricted, restricted, or banned) and enforcement_actions list.
Rules for your receiver:
- Verify the signature. Deliveries follow the Standard Webhooks spec, so any Standard Webhooks library can check the
webhook-signatureheader. - Return a 2xx within 5 seconds. Do the slow work afterward.
- Deduplicate on the event
id. The same event can arrive twice. - Trust the profile, not the order of events. Events can arrive late or out of order.
- Don't rely on delivery alone. Failed deliveries are retried for a few minutes and then dropped. Run a periodic job that lists profiles filtered by
enforcement_status[]=restrictedandenforcement_status[]=banned.
Check the docs before you count on events. At launch, the webhook docs say event delivery is not live yet. You can register endpoints and build the handler now, but until Anthropic switches delivery on, the periodic listing job is your only signal.
What to do when a customer is restricted
Decide this before it happens:
- Show that customer a clear error instead of retrying their requests.
- Notify your support team with the profile's
reference_idso they can find the account. - Review the customer under your own terms of service. Anthropic's action is a strong signal of a usage policy problem on your platform.
How this connects to other programs
Profiles also carry a read-only programs field. If one of your end customers is approved for the Cyber Verification Program or similar trusted-access programs, they can link their profile in the Verification Portal so their approval applies when they use Claude through your product. That is how a security company building on your platform could get the relaxed safeguards it was approved for, without you being approved yourself.
If you're an Enterprise admin looking at controls for your own staff rather than your customers, inference hooks are the relevant feature. They also left beta on October 20.
A rollout checklist
- Move your own internal usage into a separate organization.
- Add a profile-creation call to signup, and store the ID.
- Backfill existing customers after talking to your account team.
- Pass
user_profile_idon every request path, including batches and background jobs. - Add a test that a missing or wrong ID is caught before it reaches production.
- Request organization webhooks, build the receiver, and add the periodic listing job.
- Delete a profile when a customer closes their account or asks for erasure. Stop sending its ID first.