Follow Discord
Sweep 10 Nov 2026 · 02:18Z Build v2.1.322 539 read Stable v2.1.311 Latest v2.1.322 Next v2.1.322 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · api

admin-api changedmanage-claude/admin-api

Nearest release: v2.1.319, published an hour after 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+44added
Lines−12removed
From line 31 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits26to this page, all time

The whole hunk

from line 31, old and new numbered
/
lines
from line 31
3131 
3232An Admin API key covers most endpoints. The service-account, federation-issuer, and federation-rule endpoints accept only an `org:admin` OAuth token. Send a personal key or service account key in the `x-api-key` header, as you would an Admin API key. The following examples call the [organization info endpoint](https://platform.claude.com/docs/en/manage-claude/admin-api#accessing-organization-info) with an OAuth token and with an Admin API key.
3333 
34In Python, TypeScript, C#, Go, Java, PHP, and Ruby, the SDK exposes the endpoints on this page under `client.organization` (csharp, go: `client.Organization`; java: `client.organization()`; php: `$client->organization`), and the `ant` CLI under `ant organization`. The examples on this page use the default client, which reads an Admin API key from `ANTHROPIC_API_KEY` or an OAuth bearer token from `ANTHROPIC_AUTH_TOKEN`. SDK list methods in Python, TypeScript, C#, Go, and Java return an iterator that fetches more pages on demand, so `limit` sets the page size, not the total. The PHP, Ruby, and curl examples return one page. In the CLI, `--limit` caps the results on the member, invite, workspace, workspace-member, and API-key lists. For each endpoint’s parameters and responses, see the [Admin API reference](https://platform.claude.com/docs/en/api/organization).
34The SDK exposes the endpoints on this page under `client.organization` (csharp, go: `client.Organization`; java: `client.organization()`; php: `$client->organization`), and the `ant` CLI under `ant organization`. The examples on this page use the default client, which reads an Admin API key from `ANTHROPIC_API_KEY` or an OAuth bearer token from `ANTHROPIC_AUTH_TOKEN`. The comments in each list example say whether it fetches more pages or reads only the first. For each endpoint’s parameters and responses, see the [Admin API reference](https://platform.claude.com/docs/en/api/organization).
3535 
3636### OAuth bearer token
3737 
from line 42
4242export ANTHROPIC_AUTH_TOKEN=$(ant auth print-credentials --profile admin --access-token)
4343```
4444 
45Interactive tokens are short-lived. If requests start returning 401, re-run the `export` command to refresh the token.
45Interactive tokens are short-lived. If requests start returning 401, rerun the `export` command to refresh the token.
4646 
47The SDK and the `ant` CLI read `ANTHROPIC_AUTH_TOKEN` automatically. Leave `ANTHROPIC_API_KEY` unset in the same shell so they send the bearer token. Automated workloads skip the login: they authenticate through workload identity federation, and the SDK and CLI perform the token exchange from the federation environment variables. See [Bootstrap a workload to manage WIF](https://platform.claude.com/docs/en/manage-claude/wif-admin-api#bootstrap-a-workload-to-manage-wif).
47The SDK and the `ant` CLI read `ANTHROPIC_AUTH_TOKEN` automatically. Leave `ANTHROPIC_API_KEY` unset in the same shell so they send the bearer token. Automated workloads skip the login: they authenticate through Workload Identity Federation, and the SDK and CLI perform the token exchange from the federation environment variables. See [Bootstrap a workload to manage WIF](https://platform.claude.com/docs/en/manage-claude/wif-admin-api#bootstrap-a-workload-to-manage-wif).
4848 
4949Call the Admin API with the exported token:
5050 
from line 248
248248 
249249<CodeGroup>
250250 ```bash cURL
251 # Returns one page.
251252 curl "https://api.anthropic.com/v1/organizations/users?limit=10" \
252253 -H "x-api-key: $ANTHROPIC_API_KEY" \
253254 -H "anthropic-version: 2026-10-21"
from line 255
254255 ```
255256 
256257 ```bash CLI
258 # At a terminal, the view fetches more pages as you scroll. When piped or with `--format json`, `--limit` caps the results.
257259 ant organization:users list --limit 10
258260 ```
259261 
from line 264
262264 
263265 users = client.organization.users.list(limit=10)
264266 
265 # Automatically fetches more pages as needed.
267 # Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
266268 for user in users:
267269 print(f"{user.id}: {user.email} ({user.role})")
268270 ```
from line 274
272274 
273275 const users = await client.organization.users.list({ limit: 10 });
274276 
277 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
275278 for await (const user of users) {
276279 console.log(`${user.id}: ${user.email} (${user.role})`);
277280 }
from line 285
282285 
283286 var page = await client.Organization.Users.List(new() { Limit = 10 });
284287 
288 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
285289 await foreach (var user in page.Paginate())
286290 {
287291 Console.WriteLine($"{user.ID}: {user.Email} ({user.Role.Raw()})");
from line 299
295299 Limit: anthropic.Int(10),
296300 })
297301 
302 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
298303 for users.Next() {
299304 user := users.Current()
300305 fmt.Printf("%s: %s (%s)\n", user.ID, user.Email, user.Role)
from line 320
315320 .build();
316321 var users = client.organization().users().list(params);
317322 
323 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
318324 for (var user : users.autoPager()) {
319325 IO.println(user.id() + ": " + user.email() + " (" + user.role().asString() + ")");
320326 }
from line 332
326332 
327333 $users = $client->organization->users->list(limit: 10);
328334 
335 // Reads only the first page.
329336 foreach ($users->getItems() as $user) {
330337 echo "{$user->id}: {$user->email} ({$user->role})\n";
331338 }
from line 343
336343 
337344 users = client.organization.users.list(limit: 10)
338345 
346 # Reads only the first page.
339347 users.data.each do |user|
340348 puts "#{user.id}: #{user.email} (#{user.role})"
341349 end
from line 672
664672 ```
665673</CodeGroup>
666674 
667List pending invites:
675List pending, accepted, and expired invites:
668676 
669677<CodeGroup>
670678 ```bash cURL
679 # Returns one page.
671680 curl "https://api.anthropic.com/v1/organizations/invites?limit=10" \
672681 -H "x-api-key: $ANTHROPIC_API_KEY" \
673682 -H "anthropic-version: 2026-10-21"
from line 683
674683 ```
675684 
676685 ```bash CLI
686 # At a terminal, the view fetches more pages as you scroll. When piped or with `--format json`, `--limit` caps the results.
677687 ant organization:invites list --limit 10
678688 ```
679689 
from line 692
682692 
683693 invites = client.organization.invites.list(limit=10)
684694 
685 # Automatically fetches more pages as needed.
695 # Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
686696 for invite in invites:
687697 print(f"{invite.id}: {invite.email} ({invite.status})")
688698 ```
from line 702
692702 
693703 const invites = await client.organization.invites.list({ limit: 10 });
694704 
705 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
695706 for await (const invite of invites) {
696707 console.log(`${invite.id}: ${invite.email} (${invite.status})`);
697708 }
from line 713
702713 
703714 var page = await client.Organization.Invites.List(new() { Limit = 10 });
704715 
716 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
705717 await foreach (var invite in page.Paginate())
706718 {
707719 Console.WriteLine($"{invite.ID}: {invite.Email} ({invite.Status.Raw()})");
from line 727
715727 Limit: anthropic.Int(10),
716728 })
717729 
730 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
718731 for invites.Next() {
719732 invite := invites.Current()
720733 fmt.Printf("%s: %s (%s)\n", invite.ID, invite.Email, invite.Status)
from line 748
735748 .build();
736749 var invites = client.organization().invites().list(params);
737750 
751 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
738752 for (var invite : invites.autoPager()) {
739753 IO.println(invite.id() + ": " + invite.email() + " (" + invite.status().asString() + ")");
740754 }
from line 760
746760 
747761 $invites = $client->organization->invites->list(limit: 10);
748762 
763 // Reads only the first page.
749764 foreach ($invites->getItems() as $invite) {
750765 echo "{$invite->id}: {$invite->email} ({$invite->status})\n";
751766 }
from line 771
756771 
757772 invites = client.organization.invites.list(limit: 10)
758773 
774 # Reads only the first page.
759775 invites.data.each do |invite|
760776 puts "#{invite.id}: #{invite.email} (#{invite.status})"
761777 end
from line 865
849865 
850866### Workspace members
851867 
852Manage [user access to specific workspaces](https://platform.claude.com/docs/en/api/organization/workspaces/members/retrieve):
868Manage [user access to specific workspaces](https://platform.claude.com/docs/en/api/organization/workspaces/members/retrieve).
853869 
854870Add a member to a workspace:
855871 
from line 1007
9911007 
9921008<CodeGroup>
9931009 ```bash cURL
1010 # Returns one page.
9941011 curl "https://api.anthropic.com/v1/organizations/workspaces/wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ/members?limit=10" \
9951012 -H "x-api-key: $ANTHROPIC_API_KEY" \
9961013 -H "anthropic-version: 2026-10-21"
from line 1014
9971014 ```
9981015 
9991016 ```bash CLI
1017 # At a terminal, the view fetches more pages as you scroll. When piped or with `--format json`, `--limit` caps the results.
10001018 ant organization:workspaces:members list \
10011019 --workspace-id wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ \
10021020 --limit 10
from line 1027
10091027 "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ", limit=10
10101028 )
10111029 
1012 # Automatically fetches more pages as needed.
1030 # Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
10131031 for member in members:
10141032 print(f"{member.user_id}: {member.workspace_role}")
10151033 ```
from line 1040
10221040 { limit: 10 }
10231041 );
10241042 
1043 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
10251044 for await (const member of members) {
10261045 console.log(`${member.user_id}: ${member.workspace_role}`);
10271046 }
from line 1054
10351054 new() { Limit = 10 }
10361055 );
10371056 
1057 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
10381058 await foreach (var member in page.Paginate())
10391059 {
10401060 Console.WriteLine($"{member.UserID}: {member.WorkspaceRole.Raw()}");
from line 1072
10521072 },
10531073 )
10541074 
1075 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
10551076 for members.Next() {
10561077 member := members.Current()
10571078 fmt.Printf("%s: %s\n", member.UserID, member.WorkspaceRole)
from line 1094
10731094 var members = client.organization().workspaces().members()
10741095 .list("wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ", params);
10751096 
1097 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
10761098 for (var member : members.autoPager()) {
10771099 IO.println(member.userId() + ": " + member.workspaceRole().asString());
10781100 }
from line 1109
10871109 limit: 10,
10881110 );
10891111 
1112 // Reads only the first page.
10901113 foreach ($members->getItems() as $member) {
10911114 echo "{$member->userID}: {$member->workspaceRole}\n";
10921115 }
from line 1121
10981121 workspace_id = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
10991122 members = client.organization.workspaces.members.list(workspace_id, limit: 10)
11001123 
1124 # Reads only the first page.
11011125 members.data.each do |member|
11021126 puts "#{member.user_id}: #{member.workspace_role}"
11031127 end
from line 1373
13491373 
13501374<CodeGroup>
13511375 ```bash cURL
1376 # Returns one page.
13521377 curl "https://api.anthropic.com/v1/organizations/api_keys?limit=10&status=active&workspace_id=wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ" \
13531378 -H "x-api-key: $ANTHROPIC_API_KEY" \
13541379 -H "anthropic-version: 2026-10-21"
from line 1380
13551380 ```
13561381 
13571382 ```bash CLI
1383 # At a terminal, the view fetches more pages as you scroll. When piped or with `--format json`, `--limit` caps the results.
13581384 ant organization:api-keys list \
13591385 --limit 10 \
13601386 --status active \
from line 1394
13681394 limit=10, status="active", workspace_id="wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
13691395 )
13701396 
1371 # Automatically fetches more pages as needed.
1397 # Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
13721398 for api_key in api_keys:
13731399 print(f"{api_key.id}: {api_key.name} ({api_key.status})")
13741400 ```
from line 1408
13821408 workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
13831409 });
13841410 
1411 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
13851412 for await (const apiKey of apiKeys) {
13861413 console.log(`${apiKey.id}: ${apiKey.name} (${apiKey.status})`);
13871414 }
from line 1426
13991426 WorkspaceID = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
14001427 });
14011428 
1429 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
14021430 await foreach (var apiKey in page.Paginate())
14031431 {
14041432 Console.WriteLine($"{apiKey.ID}: {apiKey.Name} ({apiKey.Status.Raw()})");
from line 1442
14141442 WorkspaceID: anthropic.String("wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"),
14151443 })
14161444 
1445 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
14171446 for apiKeys.Next() {
14181447 apiKey := apiKeys.Current()
14191448 fmt.Printf("%s: %s (%s)\n", apiKey.ID, apiKey.Name, apiKey.Status)
from line 1465
14361465 .build();
14371466 var apiKeys = client.organization().apiKeys().list(params);
14381467 
1468 // Automatically fetches more pages as needed, so `limit` sets the page size, not the total.
14391469 for (var apiKey : apiKeys.autoPager()) {
14401470 IO.println(apiKey.id() + ": " + apiKey.name() + " (" + apiKey.status().asString() + ")");
14411471 }
from line 1484
14541484 workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
14551485 );
14561486 
1487 // Reads only the first page.
14571488 foreach ($apiKeys->getItems() as $apiKey) {
14581489 echo "{$apiKey->id}: {$apiKey->name} ({$apiKey->status})\n";
14591490 }
from line 1499
14681499 workspace_id: "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
14691500 )
14701501 
1502 # Reads only the first page.
14711503 api_keys.data.each do |api_key|
14721504 puts "#{api_key.id}: #{api_key.name} (#{api_key.status})"
14731505 end
from line 1772
17401772* Use meaningful names and descriptions for workspaces and API keys
17411773* Handle errors from failed operations
17421774* Regularly audit member roles and permissions
1743* Clean up unused workspaces and expired invites
1775* Archive unused workspaces and delete pending invites you no longer need
17441776* Monitor API key usage, audit each key’s [`expires_at`](https://platform.claude.com/docs/en/manage-claude/authentication#key-expiration), and rotate keys periodically
17451777 
17461778## FAQ
from line 1782
17501782 The Admin API accepts an Admin API key (starting with `sk-ant-admin`), an OAuth bearer token with the `org:admin` scope, or a personal key or service account key that isn’t scoped to a specific workspace. Only organization members with the admin role can provision Admin API keys, and only members with the admin, owner, or primary owner role can obtain `org:admin` tokens. A personal key or service account key has the same permissions as the linked account. See [Authentication](https://platform.claude.com/docs/en/manage-claude/admin-api#authentication).
17511783 </Accordion>
17521784 
1753 <Accordion title="Can I create new API keys through the Admin API?">
1785 <Accordion title="Can the Admin API create API keys?">
17541786 No. You create API keys in the Claude Console. The Admin API can only read, rename, and change the status of existing keys.
17551787 </Accordion>
17561788 
Feedback