authentication changedmanage-claude/authentication
Nearest release: v2.1.250, published an hour before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Recorded here
Lines+245added
Lines−8removed
From line
8
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits12to this page, all time
### Key types ### Create and use a key ### Select a workspace ### Replacing workspace API keys
The whole hunk
from line 8, old and new numbered
/
from line 8
88
99| Method | Credential | Best for |
1010| ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
11| [API key](https://platform.claude.com/docs/en/manage-claude/authentication#api-keys) | Static `sk-ant-api...` secret in the `x-api-key` header | Local development, prototyping, scripts, and single-tenant servers where you control secret storage |
11| [API key](https://platform.claude.com/docs/en/manage-claude/authentication#api-keys) | Static `sk-ant-api...` secret in the `x-api-key` header | Local development, prototyping, scripts, and servers where you control secret storage |
1212| [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/authentication#workload-identity-federation) | Short-lived bearer token exchanged from your identity provider's identity token | Production workloads on cloud platforms (AWS, Google Cloud, Azure), CI/CD pipelines, and Kubernetes, where you want to eliminate static secrets |
1313| [App Attest](https://platform.claude.com/docs/en/manage-claude/authentication#app-attest) | Short-lived access token issued to a genuine, attested installation of your registered iOS or macOS app | iOS and macOS apps distributed to end users, where the app calls the Claude API directly with no back end or proxy |
1414
15API keys and Workload Identity Federation grant the same access to Claude API endpoints. Choose API keys to get started quickly, and move to Workload Identity Federation when your workload already has a platform-issued identity you can federate. Use App Attest for iOS and macOS apps you distribute to end users.
15API keys and Workload Identity Federation grant the same access to Claude API endpoints. Choose API keys to get started quickly: a personal key for your own development, or a service account key for anything shared. Move to Workload Identity Federation when your workload already has a platform-issued identity you can federate. Use App Attest for iOS and macOS apps you distribute to end users.
1616
1717## API keys
1818
19API keys are static secrets that you generate in the Claude Console and pass on every request.
19API keys are static secrets that you generate in the Claude Console and send on every request in the `x-api-key` header.
2020
21* **Create a key:** Go to [Settings → API keys](https://platform.claude.com/settings/keys) in the Claude Console. You choose an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration) as part of creation. Use [workspaces](https://platform.claude.com/settings/workspaces) to scope keys by project or environment.
22* **Send the key:** Set the `x-api-key` header on direct HTTP requests, or set the `ANTHROPIC_API_KEY` environment variable and the [client SDKs](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) pick it up automatically.
21### Key types
2322
23When you create a key, you choose its type, which determines what the key can do, where it works, and when it stops working:
24
25| Key type | Acts as | Works in | Stops working when |
26| -------------------------- | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
27| **Personal key** | You, the user, with your roles and permissions | Either a single workspace or the workspaces where your role allows API use, chosen when the key is created | You lose access to the organization or, for a single-workspace key, to that workspace. Personal keys are archived when you are removed from the organization. If you are re-invited, create new keys; archived keys are not restored |
28| **Service account key** | A [service account](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation#service-accounts) | Either a single workspace or anything the service account has access to, chosen when the key is created. A service account has access to the Default Workspace and to workspaces it has been added to | The service account is archived or, for a single-workspace key, is removed from that workspace |
29| **Workspace key** (legacy) | No one: it belongs to the workspace it was created in | That workspace | It expires, is disabled or deleted, or its workspace is archived, regardless of whether its creator leaves the organization |
30
31Personal keys and service account keys are identity-backed: each belongs to a user or service account your organization already manages, and every request acts as that identity. When that identity is removed from the organization, the key stops working. This means that keys won't accidentally outlive the people or workloads that own them. Prefer them over workspace keys for new integrations.
32
33Use a personal key for your own development and scripts. A shared personal key acts as one person and breaks when they leave. For shared or automated workloads (CI, production services), have an organization admin create a service account so the workload has its own identity.
34
35Workspace API keys still work but should be considered legacy; identity-backed keys or [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/workload-identity-federation) are preferred. To migrate, see [Replacing workspace API keys](https://platform.claude.com/docs/en/manage-claude/authentication#replacing-workspace-api-keys).
36
37### Create and use a key
38
39* **Create a key:** Go to [Settings → API keys](https://platform.claude.com/settings/keys) in the Claude Console and click **Create key**. Name the key and choose an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration). Set **Linked account** to yourself for a personal key, or to a service account for a key shared across multiple users. You can also scope the key to a specific workspace, which lets you skip setting a workspace ID manually in future requests.
40* **Use the key:** Set the `x-api-key` header on direct HTTP requests, or set the `ANTHROPIC_API_KEY` environment variable and the [client SDKs](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) pick it up automatically.
41
2442```http
2543POST /v1/messages
2644x-api-key: YOUR_API_KEY
from line 46
2846content-type: application/json
2947```
3048
31Store API keys in a secrets manager, rotate them periodically, and revoke any key you suspect has leaked. You can also set an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration) when you create a key to limit how long a leaked credential stays usable.
49Store API keys in a secrets manager, rotate them periodically, and disable or delete any key you suspect has leaked. On the [API keys page](https://platform.claude.com/settings/keys), **Disable** is reversible (the Admin API reports the key's `status` as `"inactive"`, and **Re-enable** returns it to `"active"`), while **Delete** is permanent: the key is archived and still appears in [List API Keys](https://platform.claude.com/docs/en/api/admin/api_keys/list) with `status: "archived"`. Expired keys can only be deleted. You can also set an [expiration](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration) when you create a key to limit how long a leaked credential stays usable.
3250
3351<CodeGroup>
3452 ```bash cURL
from line 119
101119 ```
102120</CodeGroup>
103121
122### Select a workspace
123
124API keys that are created for a specific workspace only work in that workspace, and API requests using these keys can omit the workspace ID.
125
126If your API key isn't scoped to a workspace, you must specify the workspace ID in the `anthropic-workspace-id` header for each request. See the following example for how to set this header in a request or in SDKs.
127
128The [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) accepts a personal key or service account key only if the key isn't scoped to a specific workspace.
129
130You can find a workspace's ID in the **ID** column of [Settings → Workspaces](https://platform.claude.com/settings/workspaces) in the Claude Console, or by calling the [List Workspaces](https://platform.claude.com/docs/en/api/admin/workspaces/list) endpoint. Neither lists the Default Workspace's ID: read it from the `anthropic-workspace-id` [response header](https://platform.claude.com/docs/en/manage-claude/workspaces#identify-the-workspace-behind-an-api-response) of any request that runs there (for example, one made with a workspace key from the Default Workspace), or from `scope.workspace_id` on such a key in [List API Keys](https://platform.claude.com/docs/en/api/admin/api_keys/list).
131
132<CodeGroup>
133 ```bash cURL
134 # Required on every request for a multi-workspace key.
135 # Omit the anthropic-workspace-id header for a single-workspace key.
136 curl https://api.anthropic.com/v1/messages \
137 -H "x-api-key: $ANTHROPIC_API_KEY" \
138 -H "anthropic-version: 2023-06-01" \
139 -H "anthropic-workspace-id: wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" \
140 -H "content-type: application/json" \
141 -d '{
142 "model": "claude-opus-5",
143 "max_tokens": 1024,
144 "messages": [{"role": "user", "content": "Hello, Claude"}]
145 }'
146 ```
147
148 ```bash CLI
149 # Required on every command for a multi-workspace key.
150 # Omit --workspace-id for a single-workspace key.
151 ant messages create \
152 --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ \
153 --model claude-opus-5 \
154 --max-tokens 1024 \
155 --message '{role: user, content: "Hello, Claude"}'
156 ```
157
158 ```python Python
159 client = Anthropic() # reads ANTHROPIC_API_KEY
160
161 # Required on every request for a multi-workspace key.
162 # Omit extra_headers for a single-workspace key.
163 message = client.messages.create(
164 model="claude-opus-5",
165 max_tokens=1024,
166 messages=[{"role": "user", "content": "Hello, Claude"}],
167 extra_headers={"anthropic-workspace-id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"},
168 )
169 print(message.content)
170
171 # Or set it once for every request from this client:
172 workspace_client = Anthropic(
173 default_headers={"anthropic-workspace-id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"},
174 )
175 ```
176
177 ```typescript TypeScript
178 const client = new Anthropic(); // reads ANTHROPIC_API_KEY
179
180 // Required on every request for a multi-workspace key.
181 // Omit the second argument for a single-workspace key.
182 const message = await client.messages.create(
183 {
184 model: "claude-opus-5",
185 max_tokens: 1024,
186 messages: [{ role: "user", content: "Hello, Claude" }]
187 },
188 { headers: { "anthropic-workspace-id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" } }
189 );
190 console.log(message.content);
191
192 // Or set it once for every request from this client:
193 const workspaceClient = new Anthropic({
194 defaultHeaders: { "anthropic-workspace-id": "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" }
195 });
196 ```
197
198 ```csharp C#
199 AnthropicClient client = new(); // reads ANTHROPIC_API_KEY
200
201 MessageCreateParams parameters = new()
202 {
203 Model = Model.ClaudeOpus5,
204 MaxTokens = 1024,
205 Messages = [new() { Role = Role.User, Content = "Hello, Claude" }],
206 };
207
208 // Required on every request for a multi-workspace key.
209 // Call client.Messages.Create(parameters) directly for a single-workspace key.
210 var message = await client
211 .WithOptions(options =>
212 options with
213 {
214 ExtraHeaders = new Dictionary<string, string>
215 {
216 ["anthropic-workspace-id"] = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
217 },
218 }
219 )
220 .Messages.Create(parameters);
221 Console.WriteLine(message);
222
223 // Or set it once for every request from this client:
224 AnthropicClient workspaceClient = new(new ClientOptions
225 {
226 ExtraHeaders = new Dictionary<string, string>
227 {
228 ["anthropic-workspace-id"] = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ",
229 },
230 });
231 ```
232
233 ```go Go
234 client := anthropic.NewClient() // reads ANTHROPIC_API_KEY
235
236 // Required on every request for a multi-workspace key.
237 // Omit the option for a single-workspace key.
238 message, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
239 Model: anthropic.ModelClaudeOpus5,
240 MaxTokens: 1024,
241 Messages: []anthropic.MessageParam{
242 anthropic.NewUserMessage(anthropic.NewTextBlock("Hello, Claude")),
243 },
244 }, option.WithHeader("anthropic-workspace-id", "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"))
245 if err != nil {
246 log.Fatal(err)
247 }
248 fmt.Println(message.Content)
249
250 // Or set it once for every request from this client:
251 workspaceClient := anthropic.NewClient(
252 option.WithHeader("anthropic-workspace-id", "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"),
253 )
254 ```
255
256 ```java Java
257 AnthropicClient client = AnthropicOkHttpClient.fromEnv(); // reads ANTHROPIC_API_KEY
258
259 // Required on every request for a multi-workspace key.
260 // Omit putAdditionalHeader for a single-workspace key.
261 Message message = client.messages().create(MessageCreateParams.builder()
262 .model(Model.CLAUDE_OPUS_5)
263 .maxTokens(1024)
264 .addUserMessage("Hello, Claude")
265 .putAdditionalHeader("anthropic-workspace-id", "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ")
266 .build());
267
268 IO.println(message.content());
269
270 // Or set it once for every request from this client:
271 AnthropicClient workspaceClient = AnthropicOkHttpClient.builder()
272 .fromEnv()
273 .putHeader("anthropic-workspace-id", "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ")
274 .build();
275 ```
276
277 ```php PHP
278 $client = new Client(); // reads ANTHROPIC_API_KEY
279
280 // Required on every request for a multi-workspace key.
281 // Omit requestOptions for a single-workspace key.
282 $message = $client->messages->create(
283 model: Model::CLAUDE_OPUS_5,
284 maxTokens: 1024,
285 messages: [['role' => 'user', 'content' => 'Hello, Claude']],
286 requestOptions: [
287 'extraHeaders' => ['anthropic-workspace-id' => 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ'],
288 ],
289 );
290
291 echo json_encode($message->content), PHP_EOL;
292 ```
293
294 ```ruby Ruby
295 client = Anthropic::Client.new # reads ANTHROPIC_API_KEY
296
297 # Required on every request for a multi-workspace key.
298 # Omit request_options for a single-workspace key.
299 message = client.messages.create(
300 model: Anthropic::Model::CLAUDE_OPUS_5,
301 max_tokens: 1024,
302 messages: [{role: "user", content: "Hello, Claude"}],
303 request_options: {extra_headers: {"anthropic-workspace-id" => "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"}}
304 )
305
306 puts message.content
307 ```
308</CodeGroup>
309
310If a request made with a key that isn't scoped to a workspace omits the header, the API returns a 400 `invalid_request_error`:
311
312```json JSON
313{
314 "type": "error",
315 "error": {
316 "type": "invalid_request_error",
317 "message": "anthropic-workspace-id is required when authenticating with an identity-linked API key; send the id of the workspace this request acts in."
318 },
319 "request_id": "req_011CSHoEeqs5C35K2UUqR7Fy"
320}
321```
322
323A header value that isn't a valid workspace ID returns a 400 `invalid_request_error` with the message `anthropic-workspace-id header must be a valid workspace ID.` If the workspace doesn't exist, or the key's user or service account doesn't have access to it, the API returns a 404 `not_found_error` with the message ``Workspace `<id>` not found.``, the same response as for any unknown workspace.
324
325Workload Identity Federation selects a workspace at token exchange instead; see the [WIF reference](https://platform.claude.com/docs/en/manage-claude/wif-reference) for details.
326
104327### Key expiration
105328
106329When you create an API key from the [API keys page](https://platform.claude.com/settings/keys) in the Claude Console, you choose an expiration: a preset (3 hours, 1 day, 7 days, or 30 days), a custom duration, or **Never** for keys you store in a secrets manager and rotate yourself. If your organization has a maximum expiration policy, the Console limits presets and custom durations to the policy maximum, and **Never** is unavailable. Existing keys keep their current behavior; expiration is set at creation time and cannot be changed afterward. The same expiration choice applies when you [create an Admin API key](https://platform.claude.com/docs/en/manage-claude/admin-api-keys) in the Claude Console.
from line 334
111334
112335The Console API keys table shows each key's expiration, and the Admin API reports each key's `expires_at` timestamp on the [List API Keys](https://platform.claude.com/docs/en/api/admin/api_keys/list) and [Retrieve API Key](https://platform.claude.com/docs/en/api/admin/api_keys/retrieve) endpoints, so you can audit and rotate keys before they expire. The field is `null` for keys without an expiration.
113336
114Expiration limits the lifetime of a leaked credential, but it is not a substitute for secret hygiene. Regardless of expiration, store keys in a secrets manager and revoke any key you suspect has leaked.
337Expiration limits the lifetime of a leaked credential, but it is not a substitute for secret hygiene. Regardless of expiration, store keys in a secrets manager and disable or delete any key you suspect has leaked.
338
339### Replacing workspace API keys
340
341If you have a workspace key, you may want to replace it with [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/wif-reference) or a personal or service account key. This provides better security and observability.
342
343See [Workload Identity Federation](https://platform.claude.com/docs/en/manage-claude/wif-reference) for details on configuring Workload Identity Federation, which is preferred over long-lived keys.
344
345To replace a workspace key with a personal or service account key:
346
3471. **Decide the key type.** Your own tooling should use a personal key. A shared or unattended workload should use a service account key.
3482. **Create a service account** if necessary. You may have to ask an organization admin to create one in [Settings → Service accounts](https://platform.claude.com/settings/service-accounts) and add it to the relevant workspace.
3493. **Create the new key.** Create it specifically for the integration's workspace unless multiple workspaces are needed.
3504. **Deploy the new key.** Replace the old key wherever the integration reads it, typically the `ANTHROPIC_API_KEY` environment variable or a secrets manager entry. For a multi-workspace key, also send the `anthropic-workspace-id` header as shown in [Select a workspace](https://platform.claude.com/docs/en/manage-claude/authentication#select-a-workspace).
3515. **Delete the old key.** Confirm that requests succeed, then delete the workspace key on the [API keys page](https://platform.claude.com/settings/keys).
115352
116353## Workload Identity Federation
117354
No line in this hunk matches that.