One read of Claude Developer Platformapi-20260930T153709Z
266 pages moved out of 642 read.
Pages moved
266
significant first
Pages read
642
in this capture
Captured
15:37 UTC
Corpus hash
5fbd08954ac7
corpus-hash
What this read moved
226-250 of 266, page 10 of 11This capture is too large to show at once. Changes 226-250 of 266 are below, significant first; the rest are on the following screens.
manage-claude/compliance-integration-patterns Changed · +8 / -8 lines
from line 112
112112
113113Five retention horizons govern what you can retrieve later:
114114
115| Data | Retained for | Controlled by |
116| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
117| Activity Feed records | 6 years | Anthropic |
118| Chat, file, and project content | Your organization's claude.ai retention policy, unless a user deletes it sooner | Your organization |
119| Local session transcripts (sessions on users' machines) | 6 years by default, or your organization's custom conversation retention period when a finite one is set | Anthropic by default; your organization when it sets a custom period |
120| Remote session transcripts (sessions in the cloud) | 6 years, unless a user deletes the session sooner | Anthropic |
121| Content hard-deleted through the Compliance API | Not retained; deletion is immediate and permanent | The caller of the `DELETE` endpoint |
115| Data | Retained for | Controlled by |
116| ------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
117| Activity Feed records | 6 years | Anthropic |
118| Chat, file, and project content | Your organization's claude.ai retention policy, unless a user deletes it sooner | Your organization |
119| Local session transcripts (sessions on users' machines) | 6 years by default, or your organization's custom conversation retention period when a finite one is set; 30 days in organizations with HIPAA readiness enabled | Anthropic by default; your organization when it sets a custom period |
120| Remote session transcripts (sessions in the cloud) | 6 years, unless a user deletes the session sooner | Anthropic |
121| Content hard-deleted through the Compliance API | Not retained; deletion is immediate and permanent | The caller of the `DELETE` endpoint |
122122
123123To learn how the rest of the Claude Platform handles retention, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention).
124124
from line 148
148148* Prompt text or model responses from Claude Console, or from Claude API workloads authenticated with an API key.
149149* On-device activity in local sessions that is never sent to Anthropic, such as local files that Claude did not read.
150150* Claude Code usage authenticated with a Claude Console API key, run through a third-party cloud platform (Amazon Bedrock, Google Cloud, or Microsoft Foundry), or run in a [Claude Code cloud session](https://code.claude.com/docs/en/claude-code-on-the-web), which runs on cloud infrastructure instead of the user's machine.
151* Local sessions from organizations with [HIPAA readiness](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention#hipaa-readiness) enabled, and local sessions for which [zero data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention#zero-data-retention-zdr-scope) is in effect.
151* Local sessions from products other than Cowork and Claude Code in organizations with [HIPAA readiness](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention#hipaa-readiness) enabled, and local sessions for which [zero data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention#zero-data-retention-zdr-scope) is in effect.
152152* Thinking blocks, and images or other binary content, inside session transcripts (transcripts carry user prompts, assistant responses, and tool activity only; local session transcripts show a placeholder `text` block where binary content was omitted).
153153* The original file for a chat attachment that claude.ai stored as extracted text, such as some Word, PowerPoint, and PDF uploads (the file content endpoint returns the extracted text; see [Retrieve files and artifacts](https://platform.claude.com/docs/en/manage-claude/compliance-content-data#retrieve-files-and-artifacts)).
154154* The system prompt of local sessions (a marker message stands in for it).
manage-claude/compliance-sessions Changed · +17 / -17 lines
from line 33
3333
3434* Claude Code sessions authenticated with a Claude Console API key, or run through a third-party cloud platform such as Amazon Bedrock, Google Cloud, or Microsoft Foundry.
3535* [Claude Code cloud sessions](https://code.claude.com/docs/en/claude-code-on-the-web) (including Claude Code routines that run in the cloud), which run on cloud infrastructure instead of the user's machine. These cloud sessions are not remote sessions, even though both run in the cloud; the remote session endpoints return Cowork sessions only.
36* Local sessions in organizations with [HIPAA readiness](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention#hipaa-readiness) enabled. No local session data is captured, so the local session endpoints return no sessions for those organizations.
36* Local sessions from products other than Cowork and Claude Code in organizations with [HIPAA readiness](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention#hipaa-readiness) enabled. In those organizations, the local session endpoints return Cowork and Claude Code sessions only, and captured session content is stored for 30 days.
3737* Local sessions for which [zero data retention (ZDR)](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention#zero-data-retention-zdr-scope) is in effect. These sessions are excluded from list results, and the retrieve and messages endpoints return 404 for them.
3838
3939Anthropic recommends the Compliance API for retrieving session content. The following table compares [local sessions](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-local-sessions) and [remote sessions](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-remote-sessions) with the OpenTelemetry-based alternatives available for Cowork and Claude Code, [Cowork's OpenTelemetry logging](https://support.claude.com/en/articles/14477985-monitor-claude-cowork-activity-with-opentelemetry) and [Claude Code monitoring](https://code.claude.com/docs/en/monitoring-usage).
4040
41| | Local sessions (on users' machines) | Remote sessions (in the cloud) | OpenTelemetry logging |
42| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
43| Delivery | Pull: query and export over HTTPS | Pull: query and export over HTTPS | Push: streamed to your OTLP collector |
44| Setup | Works with your existing Compliance Access Key | Works with your existing Compliance Access Key | Admin configures an OTLP endpoint and content-capture settings |
45| Infrastructure | Anthropic-hosted | Anthropic-hosted | You run the collector and storage |
46| ID prefix | `clls_` | `cse_` | N/A |
47| `product_surface` values | `cowork`, `claude_code`, `claude_science`, `claude_in_chrome`, and values beginning with `office_agents` | `cowork_remote` | N/A |
48| Retention | 6 years by default, or your organization's custom conversation retention period when a finite one is set; held by Anthropic | 6 years, unless a user deletes the session sooner; held by Anthropic | Your infrastructure, your policies |
49| User prompts and assistant responses | Yes | Yes | Yes, subject to content-capture settings |
50| Tool inputs | Truncated to 10,000 bytes per input by default; up to about 1 MiB on request | Truncated to 10,000 bytes per input by default; up to about 1 MiB on request | Truncated summaries |
51| Tool result content | Each text entry truncated to 10,000 bytes by default; up to about 1 MiB on request | Each text entry truncated to 10,000 bytes by default; up to about 1 MiB on request | Metadata such as size and success; Claude Code can also capture content with an optional, size-capped setting |
52| File contents | Yes, through transcript tool calls (text only; other content appears as a placeholder) | Yes, through transcript tool calls (text only; other content is omitted) | File paths; Claude Code can also capture contents with an optional, size-capped setting |
53| Host and device metadata (terminal type, workspace paths) | No | No | Yes |
54| Token usage and cost | No; available through the [Claude Enterprise Analytics API](https://platform.claude.com/docs/en/manage-claude/analytics-api#get-access-to-the-claude-enterprise-analytics-api) | No; available through the [Claude Enterprise Analytics API](https://platform.claude.com/docs/en/manage-claude/analytics-api#get-access-to-the-claude-enterprise-analytics-api) | Yes |
41| | Local sessions (on users' machines) | Remote sessions (in the cloud) | OpenTelemetry logging |
42| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- |
43| Delivery | Pull: query and export over HTTPS | Pull: query and export over HTTPS | Push: streamed to your OTLP collector |
44| Setup | Works with your existing Compliance Access Key | Works with your existing Compliance Access Key | Admin configures an OTLP endpoint and content-capture settings |
45| Infrastructure | Anthropic-hosted | Anthropic-hosted | You run the collector and storage |
46| ID prefix | `clls_` | `cse_` | N/A |
47| `product_surface` values | `cowork`, `claude_code`, `claude_science`, `claude_in_chrome`, and values beginning with `office_agents` | `cowork_remote` | N/A |
48| Retention | 6 years by default, or your organization's custom conversation retention period when a finite one is set; 30 days in organizations with HIPAA readiness enabled; held by Anthropic | 6 years, unless a user deletes the session sooner; held by Anthropic | Your infrastructure, your policies |
49| User prompts and assistant responses | Yes | Yes | Yes, subject to content-capture settings |
50| Tool inputs | Truncated to 10,000 bytes per input by default; up to about 1 MiB on request | Truncated to 10,000 bytes per input by default; up to about 1 MiB on request | Truncated summaries |
51| Tool result content | Each text entry truncated to 10,000 bytes by default; up to about 1 MiB on request | Each text entry truncated to 10,000 bytes by default; up to about 1 MiB on request | Metadata such as size and success; Claude Code can also capture content with an optional, size-capped setting |
52| File contents | Yes, through transcript tool calls (text only; other content appears as a placeholder) | Yes, through transcript tool calls (text only; other content is omitted) | File paths; Claude Code can also capture contents with an optional, size-capped setting |
53| Host and device metadata (terminal type, workspace paths) | No | No | Yes |
54| Token usage and cost | No; available through the [Claude Enterprise Analytics API](https://platform.claude.com/docs/en/manage-claude/analytics-api#get-access-to-the-claude-enterprise-analytics-api) | No; available through the [Claude Enterprise Analytics API](https://platform.claude.com/docs/en/manage-claude/analytics-api#get-access-to-the-claude-enterprise-analytics-api) | Yes |
5555
5656## Sessions on users' machines (local sessions)
5757
from line 118
118118
119119The list is built from session activity metadata, so it can include sessions whose transcript content was not captured, for example sessions that ran before capture began for your organization (as far back as your retention period allows); the transcript of such a session returns each message with its content marked unavailable (see [Retrieve a local session transcript](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-a-local-session-transcript)).
120120
121Captured local session content is stored for 6 years from capture by default. If the organization that ran the session has set a finite custom conversation retention period in [claude.ai > Organization settings > Data and privacy](https://claude.ai/admin-settings/data-privacy-controls), that period applies instead, whether it is shorter or longer than the default; when the organization has more than one custom retention period configured, the shortest applies. A change to that setting takes effect in two different ways: the endpoints stop returning activity older than the organization's current period as soon as the setting changes, whereas each captured message is stored for the period that was in effect when it was captured, so lengthening the period later does not restore content that has already expired.
121Captured local session content is stored for 6 years from capture by default. If the organization that ran the session has set a finite custom conversation retention period in [claude.ai > Organization settings > Data and privacy](https://claude.ai/admin-settings/data-privacy-controls), that period applies instead, whether it is shorter or longer than the default; when the organization has more than one custom retention period configured, the shortest applies. A change to that setting takes effect in two different ways: the endpoints stop returning activity older than the organization's current period as soon as the setting changes, whereas each captured message is stored for the period that was in effect when it was captured, so lengthening the period later does not restore content that has already expired. In organizations with [HIPAA readiness](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention#hipaa-readiness) enabled, captured local session content is stored for 30 days from capture, or for the organization's custom conversation retention period when that is shorter; the 6-year default does not apply.
122122
123123To fetch one session's metadata directly, pass its ID to `GET /v1/compliance/apps/sessions/local/{session_id}`. The response is the same session object the list endpoint returns, with no envelope and no transcript content. A malformed session ID returns [400 Bad Request](https://platform.claude.com/docs/en/manage-claude/compliance-errors#400-bad-request). A single [404 Not Found](https://platform.claude.com/docs/en/manage-claude/compliance-errors#404-not-found) covers four cases that the response does not distinguish: the session is not in an organization your key can read (including sessions under another parent organization), it does not exist, zero data retention is in effect for it, or every call in it has aged past retention.
124124
from line 425
425425
426426## Retention and deletion
427427
428The session endpoints are read-only; local and remote sessions cannot be deleted through the Compliance API. Local session transcripts are retained for 6 years by default, or your organization's custom conversation retention period when a finite one is set, as described under [Sessions on users' machines](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-local-sessions). Remote session transcripts are retained for 6 years, unless a user deletes the session sooner. The remote session endpoints no longer return a session once a user deletes it, and its transcript is not recoverable through the Compliance API. To learn how these periods sit alongside Anthropic's other retention arrangements, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention).
428The session endpoints are read-only; local and remote sessions cannot be deleted through the Compliance API. Local session transcripts are retained for 6 years by default, or your organization's custom conversation retention period when a finite one is set, or 30 days in organizations with HIPAA readiness enabled, as described under [Sessions on users' machines](https://platform.claude.com/docs/en/manage-claude/compliance-sessions#retrieve-local-sessions). Remote session transcripts are retained for 6 years, unless a user deletes the session sooner. The remote session endpoints no longer return a session once a user deletes it, and its transcript is not recoverable through the Compliance API. To learn how these periods sit alongside Anthropic's other retention arrangements, see [API and data retention](https://platform.claude.com/docs/en/manage-claude/api-and-data-retention).
429429
430430## Next steps
431431
manage-claude/rate-limits-api Changed · +174 / -151 lines
from line 42
4242
4343 rate_limits = client.beta.organization.rate_limits.list()
4444
45 for group in rate_limits:
46 models = f" ({', '.join(group.models)})" if group.models else ""
47 print(f"{group.group_type}{models}")
48 for limit in group.limits:
45 for entry in rate_limits:
46 models = f" ({', '.join(entry.models)})" if entry.models else ""
47 print(f"{entry.group.type}{models}")
48 for limit in entry.limits:
4949 print(f" {limit.type}: {limit.value}")
5050 ```
5151
from line 54
5454
5555 const rateLimits = await client.beta.organization.rateLimits.list();
5656
57 for await (const group of rateLimits) {
58 const models = group.models ? ` (${group.models.join(", ")})` : "";
59 console.log(`${group.group_type}${models}`);
60 for (const limit of group.limits) {
57 for await (const entry of rateLimits) {
58 const models = entry.models ? ` (${entry.models.join(", ")})` : "";
59 console.log(`${entry.group.type}${models}`);
60 for (const limit of entry.limits) {
6161 console.log(` ${limit.type}: ${limit.value}`);
6262 }
6363 }
from line 68
6868
6969 var rateLimits = await client.Beta.Organization.RateLimits.List();
7070
71 await foreach (var group in rateLimits.Paginate())
71 await foreach (var entry in rateLimits.Paginate())
7272 {
73 var models = group.Models is null ? "" : $" ({string.Join(", ", group.Models)})";
74 Console.WriteLine($"{group.GroupType.Raw()}{models}");
75 foreach (var limit in group.Limits)
73 var models = entry.Models is null ? "" : $" ({string.Join(", ", entry.Models)})";
74 Console.WriteLine($"{entry.Group.Type.GetString()}{models}");
75 foreach (var limit in entry.Limits)
7676 {
7777 Console.WriteLine($" {limit.Type}: {limit.Value}");
7878 }
from line 85
8585 rateLimits := client.Beta.Organization.RateLimits.ListAutoPaging(context.Background(), anthropic.BetaOrganizationRateLimitListParams{})
8686
8787 for rateLimits.Next() {
88 group := rateLimits.Current()
88 entry := rateLimits.Current()
8989 models := ""
90 if len(group.Models) > 0 {
91 models = fmt.Sprintf(" (%s)", strings.Join(group.Models, ", "))
90 if len(entry.Models) > 0 {
91 models = fmt.Sprintf(" (%s)", strings.Join(entry.Models, ", "))
9292 }
93 fmt.Printf("%s%s\n", group.GroupType, models)
94 for _, limit := range group.Limits {
93 fmt.Printf("%s%s\n", entry.Group.Type, models)
94 for _, limit := range entry.Limits {
9595 fmt.Printf(" %s: %d\n", limit.Type, limit.Value)
9696 }
9797 }
from line 105
105105
106106 var rateLimits = client.beta().organization().rateLimits().list();
107107
108 for (var group : rateLimits.autoPager()) {
109 var models = group.models()
108 for (var entry : rateLimits.autoPager()) {
109 var models = entry.models()
110110 .map(modelIds -> " (" + String.join(", ", modelIds) + ")")
111111 .orElse("");
112 IO.println(group.groupType().asString() + models);
113 for (var limit : group.limits()) {
112 IO.println(entry.group().type().asString() + models);
113 for (var limit : entry.limits()) {
114114 IO.println(" " + limit.type() + ": " + limit.value());
115115 }
116116 }
from line 121
121121
122122 $rateLimits = $client->beta->organization->rateLimits->list();
123123
124 foreach ($rateLimits->data as $group) {
125 $models = $group->models ? ' (' . implode(', ', $group->models) . ')' : '';
126 echo "{$group->groupType}{$models}\n";
127 foreach ($group->limits as $limit) {
124 foreach ($rateLimits->data as $entry) {
125 $models = $entry->models ? ' (' . implode(', ', $entry->models) . ')' : '';
126 echo "{$entry->group->type}{$models}\n";
127 foreach ($entry->limits as $limit) {
128128 echo " {$limit->type}: {$limit->value}\n";
129129 }
130130 }
from line 135
135135
136136 rate_limits = client.beta.organization.rate_limits.list
137137
138 rate_limits.data.each do |group|
139 models = group.models ? " (#{group.models.join(", ")})" : ""
140 puts "#{group.group_type}#{models}"
141 group.limits.each do |limit|
138 rate_limits.data.each do |entry|
139 models = entry.models ? " (#{entry.models.join(", ")})" : ""
140 puts "#{entry.group.type}#{models}"
141 entry.limits.each do |limit|
142142 puts " #{limit.type}: #{limit.value}"
143143 end
144144 end
from line 152
152152### Key concepts
153153
154154* **Rate limit groups:** Each entry in the response represents one rate limit group. Model rate limits are grouped so that several model versions share a single set of limits, and other groups cover resources such as the Message Batches API, the Files API, the Token Counting API, agent skills, and the web search tool.
155* **`group_type`:** Identifies which category of limits the entry covers. See [Filtering by group type](https://platform.claude.com/docs/en/manage-claude/rate-limits-api#filtering-by-group-type) for the list of values.
155* **`group` object:** Present on every entry, it identifies the rate limit group the entry applies to. It always has `type`, which is one of the `group_type` values, and `id`, an opaque identifier with the `rlg_` prefix. On `model_group` entries it also has `display_name`, Anthropic's current label for the group, such as `Claude Sonnet 4.x`. The label is for display only and may change. Other group types have no `display_name`.
156* **The `id` inside `group`:** A group has the same `id` in every organization and on every workspace override, and it never changes. Use it to match entries across organizations or against your own catalog. The entry's own `id` differs per organization, and `models` changes when Anthropic moves a model between groups. Neither is a stable key for the group.
157* **`group_type`:** Deprecated in favor of the `type` inside `group`. It's still returned, always equals that value, and has no removal date. The `group_type` query parameter isn't deprecated. See [Filtering by group type](https://platform.claude.com/docs/en/manage-claude/rate-limits-api#filtering-by-group-type) for the list of values.
156158* **`models` list:** For `model_group` entries, the `models` field lists every model ID and alias that counts against that group's limits. Use this list to look up which group any model string falls under. For other group types, `models` is `null`.
157159* **`limits` list:** Each group carries a list of `{type, value}` pairs. The `type` field identifies the limiter (such as `requests_per_minute`, `input_tokens_per_minute`, or `output_tokens_per_minute`) and `value` is the configured limit. See [Rate limits](https://platform.claude.com/docs/en/api/rate-limits) for how each limiter is measured and enforced.
158160
from line 178
176178
177179 rate_limits = client.beta.organization.rate_limits.list()
178180
179 for group in rate_limits:
180 models = f" ({', '.join(group.models)})" if group.models else ""
181 print(f"{group.group_type}{models}")
182 for limit in group.limits:
181 for entry in rate_limits:
182 models = f" ({', '.join(entry.models)})" if entry.models else ""
183 print(f"{entry.group.type}{models}")
184 for limit in entry.limits:
183185 print(f" {limit.type}: {limit.value}")
184186 ```
185187
from line 190
188190
189191 const rateLimits = await client.beta.organization.rateLimits.list();
190192
191 for await (const group of rateLimits) {
192 const models = group.models ? ` (${group.models.join(", ")})` : "";
193 console.log(`${group.group_type}${models}`);
194 for (const limit of group.limits) {
193 for await (const entry of rateLimits) {
194 const models = entry.models ? ` (${entry.models.join(", ")})` : "";
195 console.log(`${entry.group.type}${models}`);
196 for (const limit of entry.limits) {
195197 console.log(` ${limit.type}: ${limit.value}`);
196198 }
197199 }
from line 204
202204
203205 var rateLimits = await client.Beta.Organization.RateLimits.List();
204206
205 await foreach (var group in rateLimits.Paginate())
207 await foreach (var entry in rateLimits.Paginate())
206208 {
207 var models = group.Models is null ? "" : $" ({string.Join(", ", group.Models)})";
208 Console.WriteLine($"{group.GroupType.Raw()}{models}");
209 foreach (var limit in group.Limits)
209 var models = entry.Models is null ? "" : $" ({string.Join(", ", entry.Models)})";
210 Console.WriteLine($"{entry.Group.Type.GetString()}{models}");
211 foreach (var limit in entry.Limits)
210212 {
211213 Console.WriteLine($" {limit.Type}: {limit.Value}");
212214 }
from line 221
219221 rateLimits := client.Beta.Organization.RateLimits.ListAutoPaging(context.Background(), anthropic.BetaOrganizationRateLimitListParams{})
220222
221223 for rateLimits.Next() {
222 group := rateLimits.Current()
224 entry := rateLimits.Current()
223225 models := ""
224 if len(group.Models) > 0 {
225 models = fmt.Sprintf(" (%s)", strings.Join(group.Models, ", "))
226 if len(entry.Models) > 0 {
227 models = fmt.Sprintf(" (%s)", strings.Join(entry.Models, ", "))
226228 }
227 fmt.Printf("%s%s\n", group.GroupType, models)
228 for _, limit := range group.Limits {
229 fmt.Printf("%s%s\n", entry.Group.Type, models)
230 for _, limit := range entry.Limits {
229231 fmt.Printf(" %s: %d\n", limit.Type, limit.Value)
230232 }
231233 }
from line 241
239241
240242 var rateLimits = client.beta().organization().rateLimits().list();
241243
242 for (var group : rateLimits.autoPager()) {
243 var models = group.models()
244 for (var entry : rateLimits.autoPager()) {
245 var models = entry.models()
244246 .map(modelIds -> " (" + String.join(", ", modelIds) + ")")
245247 .orElse("");
246 IO.println(group.groupType().asString() + models);
247 for (var limit : group.limits()) {
248 IO.println(entry.group().type().asString() + models);
249 for (var limit : entry.limits()) {
248250 IO.println(" " + limit.type() + ": " + limit.value());
249251 }
250252 }
from line 257
255257
256258 $rateLimits = $client->beta->organization->rateLimits->list();
257259
258 foreach ($rateLimits->data as $group) {
259 $models = $group->models ? ' (' . implode(', ', $group->models) . ')' : '';
260 echo "{$group->groupType}{$models}\n";
261 foreach ($group->limits as $limit) {
260 foreach ($rateLimits->data as $entry) {
261 $models = $entry->models ? ' (' . implode(', ', $entry->models) . ')' : '';
262 echo "{$entry->group->type}{$models}\n";
263 foreach ($entry->limits as $limit) {
262264 echo " {$limit->type}: {$limit->value}\n";
263265 }
264266 }
from line 271
269271
270272 rate_limits = client.beta.organization.rate_limits.list
271273
272 rate_limits.data.each do |group|
273 models = group.models ? " (#{group.models.join(", ")})" : ""
274 puts "#{group.group_type}#{models}"
275 group.limits.each do |limit|
274 rate_limits.data.each do |entry|
275 models = entry.models ? " (#{entry.models.join(", ")})" : ""
276 puts "#{entry.group.type}#{models}"
277 entry.limits.each do |limit|
276278 puts " #{limit.type}: #{limit.value}"
277279 end
278280 end
from line 287
285287 {
286288 "type": "rate_limit",
287289 "group_type": "model_group",
290 "group": {
291 "type": "model_group",
292 "id": "rlg_01Hq7YkP3mZ9dTwRx4cVbN2s",
293 "display_name": "Claude Opus 5.5"
294 },
288295 "models": ["claude-opus-5-5"],
289296 "limits": [
290297 { "type": "requests_per_minute", "value": 4000 },
from line 302
295302 {
296303 "type": "rate_limit",
297304 "group_type": "model_group",
305 "group": {
306 "type": "model_group",
307 "id": "rlg_01Kd5wMv8nSq2LcXy6tRfJ4b",
308 "display_name": "Claude Opus 4.x"
309 },
298310 "models": [
299311 "claude-opus-4-5",
300312 "claude-opus-4-5-20251101",
from line 323
311323 {
312324 "type": "rate_limit",
313325 "group_type": "batch",
326 "group": { "type": "batch", "id": "rlg_01Wn3pBz6kCg9vHtQ7mLxD5a" },
314327 "models": null,
315328 "limits": [{ "type": "enqueued_batch_requests", "value": 500000 }]
316329 }
from line 352
339352
340353 rate_limits = client.beta.organization.rate_limits.list(model="claude-opus-5")
341354
342 for group in rate_limits:
343 models = f" ({', '.join(group.models)})" if group.models else ""
344 print(f"{group.group_type}{models}")
345 for limit in group.limits:
355 for entry in rate_limits:
356 models = f" ({', '.join(entry.models)})" if entry.models else ""
357 print(f"{entry.group.type}{models}")
358 for limit in entry.limits:
346359 print(f" {limit.type}: {limit.value}")
347360 ```
348361
from line 364
351364
352365 const rateLimits = await client.beta.organization.rateLimits.list({ model: "claude-opus-5" });
353366
354 for await (const group of rateLimits) {
355 const models = group.models ? ` (${group.models.join(", ")})` : "";
356 console.log(`${group.group_type}${models}`);
357 for (const limit of group.limits) {
367 for await (const entry of rateLimits) {
368 const models = entry.models ? ` (${entry.models.join(", ")})` : "";
369 console.log(`${entry.group.type}${models}`);
370 for (const limit of entry.limits) {
358371 console.log(` ${limit.type}: ${limit.value}`);
359372 }
360373 }
from line 381
368381 Model = "claude-opus-5"
369382 });
370383
371 await foreach (var group in rateLimits.Paginate())
384 await foreach (var entry in rateLimits.Paginate())
372385 {
373 var models = group.Models is null ? "" : $" ({string.Join(", ", group.Models)})";
374 Console.WriteLine($"{group.GroupType.Raw()}{models}");
375 foreach (var limit in group.Limits)
386 var models = entry.Models is null ? "" : $" ({string.Join(", ", entry.Models)})";
387 Console.WriteLine($"{entry.Group.Type.GetString()}{models}");
388 foreach (var limit in entry.Limits)
376389 {
377390 Console.WriteLine($" {limit.Type}: {limit.Value}");
378391 }
from line 400
387400 })
388401
389402 for rateLimits.Next() {
390 group := rateLimits.Current()
403 entry := rateLimits.Current()
391404 models := ""
392 if len(group.Models) > 0 {
393 models = fmt.Sprintf(" (%s)", strings.Join(group.Models, ", "))
405 if len(entry.Models) > 0 {
406 models = fmt.Sprintf(" (%s)", strings.Join(entry.Models, ", "))
394407 }
395 fmt.Printf("%s%s\n", group.GroupType, models)
396 for _, limit := range group.Limits {
408 fmt.Printf("%s%s\n", entry.Group.Type, models)
409 for _, limit := range entry.Limits {
397410 fmt.Printf(" %s: %d\n", limit.Type, limit.Value)
398411 }
399412 }
from line 427
414427 .build();
415428 var rateLimits = client.beta().organization().rateLimits().list(params);
416429
417 for (var group : rateLimits.autoPager()) {
418 var models = group.models()
430 for (var entry : rateLimits.autoPager()) {
431 var models = entry.models()
419432 .map(modelIds -> " (" + String.join(", ", modelIds) + ")")
420433 .orElse("");
421 IO.println(group.groupType().asString() + models);
422 for (var limit : group.limits()) {
434 IO.println(entry.group().type().asString() + models);
435 for (var limit : entry.limits()) {
423436 IO.println(" " + limit.type() + ": " + limit.value());
424437 }
425438 }
from line 448
435448 model: Model::CLAUDE_OPUS_5->value,
436449 );
437450
438 foreach ($rateLimits->data as $group) {
439 $models = $group->models ? ' (' . implode(', ', $group->models) . ')' : '';
440 echo "{$group->groupType}{$models}\n";
441 foreach ($group->limits as $limit) {
451 foreach ($rateLimits->data as $entry) {
452 $models = $entry->models ? ' (' . implode(', ', $entry->models) . ')' : '';
453 echo "{$entry->group->type}{$models}\n";
454 foreach ($entry->limits as $limit) {
442455 echo " {$limit->type}: {$limit->value}\n";
443456 }
444457 }
from line 462
449462
450463 rate_limits = client.beta.organization.rate_limits.list(model: Anthropic::Model::CLAUDE_OPUS_5)
451464
452 rate_limits.data.each do |group|
453 models = group.models ? " (#{group.models.join(", ")})" : ""
454 puts "#{group.group_type}#{models}"
455 group.limits.each do |limit|
465 rate_limits.data.each do |entry|
466 models = entry.models ? " (#{entry.models.join(", ")})" : ""
467 puts "#{entry.group.type}#{models}"
468 entry.limits.each do |limit|
456469 puts " #{limit.type}: #{limit.value}"
457470 end
458471 end
from line 509
496509 "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
497510 )
498511
499 for group in rate_limits:
500 models = f" ({', '.join(group.models)})" if group.models else ""
501 print(f"{group.group_type}{models}")
502 for limit in group.limits:
512 for entry in rate_limits:
513 models = f" ({', '.join(entry.models)})" if entry.models else ""
514 print(f"{entry.group.type}{models}")
515 for limit in entry.limits:
503516 print(f" {limit.type}: {limit.value}")
504517 ```
505518
from line 523
510523 "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
511524 );
512525
513 for await (const group of rateLimits) {
514 const models = group.models ? ` (${group.models.join(", ")})` : "";
515 console.log(`${group.group_type}${models}`);
516 for (const limit of group.limits) {
526 for await (const entry of rateLimits) {
527 const models = entry.models ? ` (${entry.models.join(", ")})` : "";
528 console.log(`${entry.group.type}${models}`);
529 for (const limit of entry.limits) {
517530 console.log(` ${limit.type}: ${limit.value}`);
518531 }
519532 }
from line 539
526539 "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
527540 );
528541
529 await foreach (var group in rateLimits.Paginate())
542 await foreach (var entry in rateLimits.Paginate())
530543 {
531 var models = group.Models is null ? "" : $" ({string.Join(", ", group.Models)})";
532 Console.WriteLine($"{group.GroupType.Raw()}{models}");
533 foreach (var limit in group.Limits)
544 var models = entry.Models is null ? "" : $" ({string.Join(", ", entry.Models)})";
545 Console.WriteLine($"{entry.Group.Type.GetString()}{models}");
546 foreach (var limit in entry.Limits)
534547 {
535548 Console.WriteLine($" {limit.Type}: {limit.Value}");
536549 }
from line 560
547560 )
548561
549562 for rateLimits.Next() {
550 group := rateLimits.Current()
563 entry := rateLimits.Current()
551564 models := ""
552 if len(group.Models) > 0 {
553 models = fmt.Sprintf(" (%s)", strings.Join(group.Models, ", "))
565 if len(entry.Models) > 0 {
566 models = fmt.Sprintf(" (%s)", strings.Join(entry.Models, ", "))
554567 }
555 fmt.Printf("%s%s\n", group.GroupType, models)
556 for _, limit := range group.Limits {
568 fmt.Printf("%s%s\n", entry.Group.Type, models)
569 for _, limit := range entry.Limits {
557570 fmt.Printf(" %s: %d\n", limit.Type, limit.Value)
558571 }
559572 }
from line 581
568581 var rateLimits = client.beta().organization().workspaces().rateLimits()
569582 .list("wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ");
570583
571 for (var group : rateLimits.autoPager()) {
572 var models = group.models()
584 for (var entry : rateLimits.autoPager()) {
585 var models = entry.models()
573586 .map(modelIds -> " (" + String.join(", ", modelIds) + ")")
574587 .orElse("");
575 IO.println(group.groupType().asString() + models);
576 for (var limit : group.limits()) {
588 IO.println(entry.group().type().asString() + models);
589 for (var limit : entry.limits()) {
577590 IO.println(" " + limit.type() + ": " + limit.value());
578591 }
579592 }
from line 599
586599 workspaceID: 'wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ',
587600 );
588601
589 foreach ($rateLimits->data as $group) {
590 $models = $group->models ? ' (' . implode(', ', $group->models) . ')' : '';
591 echo "{$group->groupType}{$models}\n";
592 foreach ($group->limits as $limit) {
602 foreach ($rateLimits->data as $entry) {
603 $models = $entry->models ? ' (' . implode(', ', $entry->models) . ')' : '';
604 echo "{$entry->group->type}{$models}\n";
605 foreach ($entry->limits as $limit) {
593606 echo " {$limit->type}: {$limit->value}\n";
594607 }
595608 }
from line 614
601614 workspace_id = "wrkspc_01JwQvzr7rXLA5AGx3HKfFUJ"
602615 rate_limits = client.beta.organization.workspaces.rate_limits.list(workspace_id)
603616
604 rate_limits.data.each do |group|
605 models = group.models ? " (#{group.models.join(", ")})" : ""
606 puts "#{group.group_type}#{models}"
607 group.limits.each do |limit|
617 rate_limits.data.each do |entry|
618 models = entry.models ? " (#{entry.models.join(", ")})" : ""
619 puts "#{entry.group.type}#{models}"
620 entry.limits.each do |limit|
608621 puts " #{limit.type}: #{limit.value}"
609622 end
610623 end
from line 630
617630 {
618631 "type": "workspace_rate_limit",
619632 "group_type": "model_group",
633 "group": {
634 "type": "model_group",
635 "id": "rlg_01Hq7YkP3mZ9dTwRx4cVbN2s",
636 "display_name": "Claude Opus 5.5"
637 },
620638 "models": ["claude-opus-5-5"],
621639 "limits": [
622640 { "type": "requests_per_minute", "value": 1000, "org_limit": 4000 },
from line 644
626644 {
627645 "type": "workspace_rate_limit",
628646 "group_type": "model_group",
647 "group": {
648 "type": "model_group",
649 "id": "rlg_01Kd5wMv8nSq2LcXy6tRfJ4b",
650 "display_name": "Claude Opus 4.x"
651 },
629652 "models": [
630653 "claude-opus-4-5",
631654 "claude-opus-4-5-20251101",
from line 686
663686
664687 rate_limits = client.beta.organization.rate_limits.list(group_type="batch")
665688
666 for group in rate_limits:
667 models = f" ({', '.join(group.models)})" if group.models else ""
668 print(f"{group.group_type}{models}")
669 for limit in group.limits:
689 for entry in rate_limits:
690 models = f" ({', '.join(entry.models)})" if entry.models else ""
691 print(f"{entry.group.type}{models}")
692 for limit in entry.limits:
670693 print(f" {limit.type}: {limit.value}")
671694 ```
672695
from line 698
675698
676699 const rateLimits = await client.beta.organization.rateLimits.list({ group_type: "batch" });
677700
678 for await (const group of rateLimits) {
679 const models = group.models ? ` (${group.models.join(", ")})` : "";
680 console.log(`${group.group_type}${models}`);
681 for (const limit of group.limits) {
701 for await (const entry of rateLimits) {
702 const models = entry.models ? ` (${entry.models.join(", ")})` : "";
703 console.log(`${entry.group.type}${models}`);
704 for (const limit of entry.limits) {
682705 console.log(` ${limit.type}: ${limit.value}`);
683706 }
684707 }
from line 717
694717 GroupType = GroupType.Batch
695718 });
696719
697 await foreach (var group in rateLimits.Paginate())
720 await foreach (var entry in rateLimits.Paginate())
698721 {
699 var models = group.Models is null ? "" : $" ({string.Join(", ", group.Models)})";
700 Console.WriteLine($"{group.GroupType.Raw()}{models}");
701 foreach (var limit in group.Limits)
722 var models = entry.Models is null ? "" : $" ({string.Join(", ", entry.Models)})";
723 Console.WriteLine($"{entry.Group.Type.GetString()}{models}");
724 foreach (var limit in entry.Limits)
702725 {
703726 Console.WriteLine($" {limit.Type}: {limit.Value}");
704727 }
from line 736
713736 })
714737
715738 for rateLimits.Next() {
716 group := rateLimits.Current()
739 entry := rateLimits.Current()
717740 models := ""
718 if len(group.Models) > 0 {
719 models = fmt.Sprintf(" (%s)", strings.Join(group.Models, ", "))
741 if len(entry.Models) > 0 {
742 models = fmt.Sprintf(" (%s)", strings.Join(entry.Models, ", "))
720743 }
721 fmt.Printf("%s%s\n", group.GroupType, models)
722 for _, limit := range group.Limits {
744 fmt.Printf("%s%s\n", entry.Group.Type, models)
745 for _, limit := range entry.Limits {
723746 fmt.Printf(" %s: %d\n", limit.Type, limit.Value)
724747 }
725748 }
from line 762
739762 .build();
740763 var rateLimits = client.beta().organization().rateLimits().list(params);
741764
742 for (var group : rateLimits.autoPager()) {
743 var models = group.models()
765 for (var entry : rateLimits.autoPager()) {
766 var models = entry.models()
744767 .map(modelIds -> " (" + String.join(", ", modelIds) + ")")
745768 .orElse("");
746 IO.println(group.groupType().asString() + models);
747 for (var limit : group.limits()) {
769 IO.println(entry.group().type().asString() + models);
770 for (var limit : entry.limits()) {
748771 IO.println(" " + limit.type() + ": " + limit.value());
749772 }
750773 }
from line 784
761784 groupType: GroupType::BATCH,
762785 );
763786
764 foreach ($rateLimits->data as $group) {
765 $models = $group->models ? ' (' . implode(', ', $group->models) . ')' : '';
766 echo "{$group->groupType}{$models}\n";
767 foreach ($group->limits as $limit) {
787 foreach ($rateLimits->data as $entry) {
788 $models = $entry->models ? ' (' . implode(', ', $entry->models) . ')' : '';
789 echo "{$entry->group->type}{$models}\n";
790 foreach ($entry->limits as $limit) {
768791 echo " {$limit->type}: {$limit->value}\n";
769792 }
770793 }
from line 798
775798
776799 rate_limits = client.beta.organization.rate_limits.list(group_type: :batch)
777800
778 rate_limits.data.each do |group|
779 models = group.models ? " (#{group.models.join(", ")})" : ""
780 puts "#{group.group_type}#{models}"
781 group.limits.each do |limit|
801 rate_limits.data.each do |entry|
802 models = entry.models ? " (#{entry.models.join(", ")})" : ""
803 puts "#{entry.group.type}#{models}"
804 entry.limits.each do |limit|
782805 puts " #{limit.type}: #{limit.value}"
783806 end
784807 end
manage-claude/workload-identity-federation Changed · +4 / -4 lines
from line 49
4949
50501. **Your IdP issues a JWT to the workload.** On most platforms this is ambient: a Kubernetes projected service-account token, the Google Cloud metadata server, Azure IMDS, or the GitHub Actions OIDC endpoint. The JWT's `iss` claim identifies the provider, and its `sub` and other claims identify the specific workload.
51512. **The SDK exchanges the JWT for an Anthropic access token.** The SDK posts the JWT to `POST /v1/oauth/token` using the [RFC 7523](https://www.rfc-editor.org/rfc/rfc7523) `jwt-bearer` grant. Anthropic verifies the JWT against the issuer's JWKS and the federation rule's match conditions, then returns a short-lived `sk-ant-oat01-...` token that acts on behalf of the rule's target service account.
523. **The SDK sends the token on every request and refreshes it before it expires.** Your application code constructs the client with no `api_key` and calls the API as usual. The SDK re-runs the exchange before the token expires.
523. **The SDK sends the token on every request and refreshes it before it expires.** Your application code constructs the client with no API key and calls the API as usual. The SDK re-runs the exchange before the token expires.
5353
5454## Set up federation
5555
from line 83
8383
8484## Authenticate from your workload
8585
86With federation configured, your workload exchanges its IdP-issued JWT for an Anthropic token at runtime. The SDKs handle the exchange and refresh loop for you. The cURL tab shows the underlying HTTP exchange for shell scripts, debugging, or languages without SDK support.
86With federation configured, your workload exchanges its IdP-issued JWT for an Anthropic token at runtime. The SDK handles the exchange and refresh loop for you. The cURL tab shows the underlying HTTP exchange for shell scripts, debugging, or languages without SDK support.
8787
8888### Construct the SDK client
8989
from line 354
354354
355355The minted Anthropic token's lifetime is the lesser of (a) the rule's `token_lifetime_seconds` (default 3,600 seconds) and (b) twice the remaining lifetime of the IdP JWT you presented. The result is never less than 60 seconds. The second bound prevents an Anthropic token from outliving the upstream identity it was derived from by more than a small margin.
356356
357The SDKs cache the token and refresh it on a two-tier schedule modeled on `botocore`:
357The SDK caches the token and refreshes it on a two-tier schedule modeled on `botocore`:
358358
359359* **Advisory refresh** at expiry minus 120 seconds. The SDK attempts a new exchange. If the token endpoint is unreachable, the SDK continues serving the cached token, which is still valid for roughly 90 more seconds.
360360* **Mandatory refresh** at expiry minus 30 seconds. A failed exchange at this point raises an error. The cached token is too close to expiry to be safe.
from line 401
401401
402402* [Manage WIF with the Admin API](https://platform.claude.com/docs/en/manage-claude/wif-admin-api): create issuers, service accounts, and rules from infrastructure as code
403403* [WIF reference](https://platform.claude.com/docs/en/manage-claude/wif-reference): environment variables, profile file schema, validation rules, and error codes
404* [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication): all authentication options across the Anthropic SDKs
404* [Authentication](https://platform.claude.com/docs/en/manage-claude/authentication): all the SDK's authentication options
405405* [Admin API reference](https://platform.claude.com/docs/en/api/beta/organization): generated request and response schemas for every Admin API endpoint
406406
managed-agents/memory Changed · +8 / -8 lines
from line 573
573573
574574### Create a memory
575575
576`memories.create` creates a memory at a given `path`. Create does not overwrite; to change an existing memory, use [`memories.update`](https://platform.claude.com/docs/en/managed-agents/memory#update-a-memory).
576`POST /v1/memory_stores/{memory_store_id}/memories` (curl; python, ruby: `client.beta.memory_stores.memories.create()`; typescript: `client.beta.memoryStores.memories.create()`; go: `client.Beta.MemoryStores.Memories.New()`; java: `client.beta().memoryStores().memories().create()`; csharp: `client.Beta.MemoryStores.Memories.Create()`; php: `$client->beta->memoryStores->memories->create()`; cli: `ant beta:memory-stores:memories create`) creates a memory at a given `path`. Create does not overwrite; to change an existing memory, [update it](https://platform.claude.com/docs/en/managed-agents/memory#update-a-memory) with `POST /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (curl; python, ruby: `client.beta.memory_stores.memories.update()`; typescript: `client.beta.memoryStores.memories.update()`; go, csharp: `client.Beta.MemoryStores.Memories.Update()`; java: `client.beta().memoryStores().memories().update()`; php: `$client->beta->memoryStores->memories->update()`; cli: `ant beta:memory-stores:memories update`).
577577
578578<CodeGroup>
579579 ```bash cURL
from line 656
656656
657657### Update a memory
658658
659`memories.update` modifies an existing memory by ID. You can change `content`, `path` (a rename), or both. The example renames a memory to an archive path:
659`POST /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (curl; python, ruby: `client.beta.memory_stores.memories.update()`; typescript: `client.beta.memoryStores.memories.update()`; go, csharp: `client.Beta.MemoryStores.Memories.Update()`; java: `client.beta().memoryStores().memories().update()`; php: `$client->beta->memoryStores->memories->update()`; cli: `ant beta:memory-stores:memories update`) modifies an existing memory by ID. You can change `content`, `path` (a rename), or both. The example renames a memory to an archive path:
660660
661661<CodeGroup>
662662 ```bash cURL
from line 916
916916
917917Every mutation to a memory creates an immutable **memory version** (`memver_...`). Use the version endpoints to audit who changed what and when, to inspect or restore a prior snapshot, and to scrub sensitive content out of history with redact.
918918
919Versions belong to the store (not the individual memory) and are not deleted when the memory itself is deleted, so the audit trail also covers deleted memories, subject to the retention described below. Versions are retained for 30 days after they are written; however, the recent versions of a live memory are always kept regardless of age, so memories that change infrequently might retain history beyond 30 days. The live `memories.retrieve` call always returns the latest version; the version endpoints give you the retained history.
919Versions belong to the store (not the individual memory) and are not deleted when the memory itself is deleted, so the audit trail also covers deleted memories, subject to the retention described below. Versions are retained for 30 days after they are written; however, the recent versions of a live memory are always kept regardless of age, so memories that change infrequently might retain history beyond 30 days. The live `GET /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (curl; python, ruby: `client.beta.memory_stores.memories.retrieve()`; typescript: `client.beta.memoryStores.memories.retrieve()`; go: `client.Beta.MemoryStores.Memories.Get()`; java: `client.beta().memoryStores().memories().retrieve()`; csharp: `client.Beta.MemoryStores.Memories.Retrieve()`; php: `$client->beta->memoryStores->memories->retrieve()`; cli: `ant beta:memory-stores:memories retrieve`) call always returns the latest version; the version endpoints give you the retained history.
920920
921There is no dedicated restore endpoint; to roll back, retrieve the version you want and write its `content` back with `memories.update` (or `memories.create` if the parent memory has been deleted, provided the version you want is still retained).
921There is no dedicated restore endpoint; to roll back, retrieve the version you want and write its `content` back with `POST /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (curl; python, ruby: `client.beta.memory_stores.memories.update()`; typescript: `client.beta.memoryStores.memories.update()`; go, csharp: `client.Beta.MemoryStores.Memories.Update()`; java: `client.beta().memoryStores().memories().update()`; php: `$client->beta->memoryStores->memories->update()`; cli: `ant beta:memory-stores:memories update`) (or `POST /v1/memory_stores/{memory_store_id}/memories` (curl; python, ruby: `client.beta.memory_stores.memories.create()`; typescript: `client.beta.memoryStores.memories.create()`; go: `client.Beta.MemoryStores.Memories.New()`; java: `client.beta().memoryStores().memories().create()`; csharp: `client.Beta.MemoryStores.Memories.Create()`; php: `$client->beta->memoryStores->memories->create()`; cli: `ant beta:memory-stores:memories create`) if the parent memory has been deleted, provided the version you want is still retained).
922922
923923Past memory versions might be deleted after 30 days. To preserve memory history for longer, export versions through the API.
924924
from line 1318
13181318
13191319See the [Archive a memory store reference](https://platform.claude.com/docs/en/api/beta/memory_stores/archive) for full parameters and response schema.
13201320
1321To permanently remove a store along with all of its memories and versions, use [`memory_stores.delete`](https://platform.claude.com/docs/en/api/beta/memory_stores/delete).
1321To [permanently remove a store](https://platform.claude.com/docs/en/api/beta/memory_stores/delete) along with all of its memories and versions, call `DELETE /v1/memory_stores/{memory_store_id}` (curl; python, ruby: `client.beta.memory_stores.delete()`; typescript: `client.beta.memoryStores.delete()`; go, csharp: `client.Beta.MemoryStores.Delete()`; java: `client.beta().memoryStores().delete()`; php: `$client->beta->memoryStores->delete()`; cli: `ant beta:memory-stores delete`).
13221322
13231323## Best practices for memory management
13241324
1325When a store reaches its 10,000-memory limit, writes to new memories fail: both direct `memories.create` calls and the agent's file writes to unmapped paths. Existing memories remain readable and editable. The following practices help you stay well under the limit and recover gracefully if you reach it.
1325When a store reaches its 10,000-memory limit, writes to new memories fail: both direct `POST /v1/memory_stores/{memory_store_id}/memories` (curl; python, ruby: `client.beta.memory_stores.memories.create()`; typescript: `client.beta.memoryStores.memories.create()`; go: `client.Beta.MemoryStores.Memories.New()`; java: `client.beta().memoryStores().memories().create()`; csharp: `client.Beta.MemoryStores.Memories.Create()`; php: `$client->beta->memoryStores->memories->create()`; cli: `ant beta:memory-stores:memories create`) calls and the agent's file writes to unmapped paths. Existing memories remain readable and editable. The following practices help you stay well under the limit and recover gracefully if you reach it.
13261326
13271327* **Use focused stores.** Rather than one large general-purpose store, use smaller purpose-built stores: one per user, one for shared domain knowledge, and one for project-specific context. Each store has its own 10,000-memory limit, so keeping stores scoped reduces the chance any single one fills up.
13281328
1329* **Condense or prune before the store fills up.** Delete stale or redundant memories with `memories.delete`. You can also run a [dreaming session](https://platform.claude.com/docs/en/managed-agents/dreams), which consolidates fragmented content into a separate new output store rather than modifying the original. Switch your sessions over to that output store, then archive or delete the original.
1329* **Condense or prune before the store fills up.** Delete stale or redundant memories with `DELETE /v1/memory_stores/{memory_store_id}/memories/{memory_id}` (curl; python, ruby: `client.beta.memory_stores.memories.delete()`; typescript: `client.beta.memoryStores.memories.delete()`; go, csharp: `client.Beta.MemoryStores.Memories.Delete()`; java: `client.beta().memoryStores().memories().delete()`; php: `$client->beta->memoryStores->memories->delete()`; cli: `ant beta:memory-stores:memories delete`). You can also run a [dreaming session](https://platform.claude.com/docs/en/managed-agents/dreams), which consolidates fragmented content into a separate new output store rather than modifying the original. Switch your sessions over to that output store, then archive or delete the original.
13301330
13311331* **Attach a new store when it makes sense.** If a store has grown beyond its useful scope, attach a fresh one for new content and attach the original with `read_only` access. The agent can read from both while only writing to the new one.
13321332
managed-agents/migration Changed · +8 / -8 lines
from line 14
1414
1515## From a Messages API agent loop
1616
17If you built an agent by calling `messages.create` in a `while` loop, running tool calls yourself, and appending results to the conversation history, most of that code goes away.
17If you built an agent by calling `client.messages.create()` (python, typescript, ruby; csharp: `client.Messages.Create()`; go: `client.Messages.New()`; java: `client.messages().create()`; php: `$client->messages->create()`; cli: `ant messages create`; curl: `POST /v1/messages`) in a loop, running tool calls yourself, and appending results to the conversation history, most of that code goes away.
1818
1919### What you stop managing
2020
from line 1332
13321332
13331333The tradeoff for Anthropic running the agent loop is that a few things the SDK handled automatically become your client's responsibility.
13341334
1335| SDK feature | Managed Agents approach |
1336| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1337| Plan mode | Run a planning-only session first, then a second session to run the plan. |
1338| Output styles, slash commands | Apply in your client before sending `user.message` or after receiving `agent.message`. |
1339| `PreToolUse` / `PostToolUse` hooks | Your client already sees every `agent.custom_tool_use` event before responding; put the logic there. For built-in tools, use `permission_policy: always_ask` to review every call. [`auto`](https://platform.claude.com/docs/en/managed-agents/permission-policies#let-the-server-evaluate-each-call-with-auto) lets the server evaluate each call instead, but if the server evaluates a call as safe, it runs without reaching your client. |
1340| `max_turns` | Count turns client-side. |
1335| SDK feature | Managed Agents approach |
1336| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1337| Plan mode | Run a planning-only session first, then a second session to run the plan. |
1338| Output styles, slash commands | Apply in your client before sending `user.message` or after receiving `agent.message`. |
1339| `PreToolUse` / `PostToolUse` hooks | Your client already sees every `agent.custom_tool_use` event before responding; put the logic there. For built-in tools, use `permission_policy: always_ask` to review every call. [`auto`](https://platform.claude.com/docs/en/managed-agents/permission-policies#let-the-server-evaluate-each-call-with-auto) lets the server evaluate each call instead, but if the server evaluates a call as safe, it runs without reaching your client. |
1340| `max_turns` (python; typescript: `maxTurns`) | Count turns client-side. |
13411341
13421342## Migration checklist
13431343
134413441. [Create an environment](https://platform.claude.com/docs/en/managed-agents/environments) with the networking and runtimes your agent needs.
134513452. Port your system prompt and tool selection to an [agent definition](https://platform.claude.com/docs/en/managed-agents/agent-setup).
13463. Replace your loop with [`sessions.create`](https://platform.claude.com/docs/en/managed-agents/sessions) and [`sessions.events.stream`](https://platform.claude.com/docs/en/managed-agents/events-and-streaming).
13463. Replace your loop: [create a session](https://platform.claude.com/docs/en/managed-agents/sessions) with `client.beta.sessions.create()` (python, typescript, ruby; go: `client.Beta.Sessions.New()`; csharp: `client.Beta.Sessions.Create()`; java: `client.beta().sessions().create()`; php: `$client->beta->sessions->create()`; cli: `ant beta:sessions create`; curl: `POST /v1/sessions`) and [stream its events](https://platform.claude.com/docs/en/managed-agents/events-and-streaming) with `client.beta.sessions.events.stream()` (python, typescript; ruby: `client.beta.sessions.events.stream_events()`; go: `client.Beta.Sessions.Events.StreamEvents()`; csharp: `client.Beta.Sessions.Events.StreamStreaming()`; java: `client.beta().sessions().events().streamStreaming()`; php: `$client->beta->sessions->events->streamStream()`; cli: `ant beta:sessions:events stream`; curl: `GET /v1/sessions/{session_id}/events/stream`).
134713474. For any local files the agent reads, upload them through the [Files API](https://platform.claude.com/docs/en/managed-agents/files) and mount them as `resources`.
134813485. For any custom tool handlers, move execution into your event loop as responses to `agent.custom_tool_use` events.
134913496. Verify with a test session before pointing production traffic at the new flow.
managed-agents/vaults Changed · +8 / -7 lines
from line 39
3939
4040 <CodeGroupItem>
4141 ```bash CLI
42 ant beta:vaults create < alice.vault.yaml
42 ant apply vaults/service_accounts.yaml
4343 ```
4444
45 <File filename="alice.vault.yaml">
45 <File filename="vaults/service_accounts.yaml">
4646 ```yaml
47 display_name: Alice
48 metadata:
49 external_user_id: usr_abc123
47 # yaml-language-server: $schema=https://platform.claude.com/schemas/ant/beta/vault.json
48 display_name: Service accounts
5049 ```
5150 </File>
51
52 [`ant apply`](https://platform.claude.com/docs/en/cli-sdks-libraries/cli/apply) creates the vault from `vaults/service_accounts.yaml`, prints its ID, and records it in `claude-lock.json`. To see the vault record, run `ant beta:vaults retrieve`.
5253 </CodeGroupItem>
5354
5455 ```python Python
from line 182
181182 ```bash CLI
182183 ant beta:vaults:credentials create \
183184 --vault-id "$VAULT_ID" \
184 --display-name "Alice's Slack" <<'YAML'
185 --display-name "Slack" <<'YAML'
185186 auth:
186187 type: mcp_oauth
187188 mcp_server_url: https://mcp.slack.com/mcp
from line 760
759760 --agent "$AGENT_ID" \
760761 --environment-id "$ENVIRONMENT_ID" \
761762 --vault-id "$VAULT_ID" \
762 --title "Alice's Slack digest"
763 --title "Slack digest"
763764 ```
764765
765766 ```python Python
models/opus-5-5/migration-guide Changed · +8 / -8 lines
from line 328
328328
329329* Remove any assistant-message prefills; Claude Opus 4.6 already rejects them.
330330* Verify tool call JSON parsing uses a standard JSON parser.
331* Move from `client.beta.messages.create` to `client.messages.create`: adaptive thinking and effort need no beta namespace.
331* Move from `client.beta.messages.create()` (python, typescript, ruby; csharp: `client.Beta.Messages.Create()`; go: `client.Beta.Messages.New()`; java: `client.beta().messages().create()`; php: `$client->beta->messages->create()`; cli: `ant beta:messages create`) to `client.messages.create()` (python, typescript, ruby; csharp: `client.Messages.Create()`; go: `client.Messages.New()`; java: `client.messages().create()`; php: `$client->messages->create()`; cli: `ant messages create`): adaptive thinking and effort need no beta namespace.
332332* Remove the `effort-2025-11-24` beta header (the effort parameter does not require it).
333333* Remove the `fine-grained-tool-streaming-2025-05-14` beta header.
334334* Remove the `interleaved-thinking-2025-05-14` beta header (adaptive thinking enables interleaved thinking automatically).
from line 1546
15461546
15471547The first item is required on Claude Opus 5.5; the rest are recommended.
15481548
15491. **Migrate to adaptive thinking (required):** `thinking: {"type": "enabled", "budget_tokens": N}` returns a 400 error on Claude Opus 4.7 and later models. The before and after is item 1 of the [breaking changes for migrating from Claude Opus 4.6](https://platform.claude.com/docs/en/models/opus-5-5/migration-guide#opus-46-breaking-changes). The migration also moves from `client.beta.messages.create` to `client.messages.create`: adaptive thinking and effort do not require the beta SDK namespace or any beta headers.
15491. **Migrate to adaptive thinking (required):** `thinking: {"type": "enabled", "budget_tokens": N}` returns a 400 error on Claude Opus 4.7 and later models. The before and after is item 1 of the [breaking changes for migrating from Claude Opus 4.6](https://platform.claude.com/docs/en/models/opus-5-5/migration-guide#opus-46-breaking-changes). The migration also moves from `client.beta.messages.create()` (python, typescript, ruby; csharp: `client.Beta.Messages.Create()`; go: `client.Beta.Messages.New()`; java: `client.beta().messages().create()`; php: `$client->beta->messages->create()`; cli: `ant beta:messages create`) to `client.messages.create()` (python, typescript, ruby; csharp: `client.Messages.Create()`; go: `client.Messages.New()`; java: `client.messages().create()`; php: `$client->messages->create()`; cli: `ant messages create`): adaptive thinking and effort do not require the beta SDK namespace or any beta headers.
15501550
15512. **Remove effort beta header:** The effort parameter does not require a beta header. Remove `betas=["effort-2025-11-24"]` from your requests.
15512. **Remove effort beta header:** The effort parameter does not require a beta header. Remove the `effort-2025-11-24` beta from your requests.
15521552
15533. **Remove fine-grained tool streaming beta header:** Fine-grained tool streaming does not require a beta header. Remove `betas=["fine-grained-tool-streaming-2025-05-14"]` from your requests.
15533. **Remove fine-grained tool streaming beta header:** Fine-grained tool streaming does not require a beta header. Remove the `fine-grained-tool-streaming-2025-05-14` beta from your requests.
15541554
15554. **Remove interleaved thinking beta header:** With adaptive thinking, interleaved thinking is automatic on every model that supports adaptive thinking. Remove `betas=["interleaved-thinking-2025-05-14"]` from your requests.
15554. **Remove interleaved thinking beta header:** With adaptive thinking, interleaved thinking is automatic on every model that supports adaptive thinking. Remove the `interleaved-thinking-2025-05-14` beta from your requests.
15561556
155715575. **Migrate to output\_config.format:** If using structured outputs, update `output_format={...}` to `output_config={"format": {...}}`. The `output_format` parameter is deprecated and will be removed in the future. To use it anyway, add the `structured-outputs-2025-11-13` beta header. Without it, the API returns a 400 error. The Python SDK (v1.0 and later) does not accept `output_format={...}` on `client.beta.messages.create()` or `count_tokens()`. The `output_format=Model` argument of the `parse()` and `stream()` helpers is unchanged.
15581558
agents-and-tools/tool-use/advisor-tool Changed · +1 / -1 lines
from line 1574
15741574| Feature | Interaction |
15751575| ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
15761576| [Batch processing](https://platform.claude.com/docs/en/build-with-claude/batch-processing) | Supported. `usage.iterations` is reported per item. |
1577| [Token counting](https://platform.claude.com/docs/en/build-with-claude/token-counting) | Returns the executor's first-iteration input tokens only. For a rough advisor estimate, call `count_tokens` with `model` set to the advisor model and the same messages. |
1577| [Token counting](https://platform.claude.com/docs/en/build-with-claude/token-counting) | Returns the executor's first-iteration input tokens only. For a rough advisor estimate, call `client.beta.messages.count_tokens()` (python, ruby; typescript: `client.beta.messages.countTokens()`; go, csharp: `client.Beta.Messages.CountTokens()`; java: `client.beta().messages().countTokens()`; php: `$client->beta->messages->countTokens()`; cli: `ant beta:messages count-tokens`; curl: `POST /v1/messages/count_tokens`) with `model` set to the advisor model and the same messages. |
15781578| [Context editing](https://platform.claude.com/docs/en/build-with-claude/context-editing) | `clear_tool_uses` is not fully compatible with advisor tool blocks. With `clear_thinking`, see the earlier caching warning. |
15791579| `pause_turn` | A dangling advisor call ends the response with `stop_reason: "pause_turn"` and a `server_tool_use` block with no result when no client `tool_use` block is awaiting your result in the same turn. The advisor runs on resumption. If the executor also called one of your tools in that turn, the response ends with `stop_reason: "tool_use"` instead, and the pending advisor call runs at the start of your next request, after you send the `tool_result` blocks. See [Resuming a paused turn](https://platform.claude.com/docs/en/agents-and-tools/tool-use/advisor-tool#resuming-a-paused-turn), [Mixing server tools and client tools in one turn](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools#mixing-server-tools-and-client-tools-in-one-turn), and [Server tools](https://platform.claude.com/docs/en/agents-and-tools/tool-use/server-tools#the-server-side-loop-and-pause-turn). |
15801580
agents-and-tools/tool-use/bash-tool Changed · +1 / -1 lines
from line 257
257257
258258`bash_20250124` is the current version of the tool, and it requires no beta header. Every model from Claude Sonnet 3.7 ([retired](https://platform.claude.com/docs/en/about-claude/model-deprecations)) onward accepts it, including all current Claude models.
259259
260The original `bash_20241022` version works only with the October 2024 Claude Sonnet 3.5 model ([retired](https://platform.claude.com/docs/en/about-claude/model-deprecations)). Requests that use it need the `anthropic-beta: computer-use-2024-10-22` header, and the SDKs expose it only in their beta namespaces. New integrations should use `bash_20250124`.
260The original `bash_20241022` version works only with the October 2024 Claude Sonnet 3.5 model ([retired](https://platform.claude.com/docs/en/about-claude/model-deprecations)). Requests that use it need the `anthropic-beta: computer-use-2024-10-22` header, and the SDK exposes it only in its beta namespace. New integrations should use `bash_20250124`.
261261
262262## Example: Multistep automation
263263
agents-and-tools/tool-use/build-a-tool-using-agent Changed · +0 / -4 lines
from line 4019
40194019
40204020Each SDK provides a helper that turns an ordinary function into a runnable tool and derives the input schema from its signature; the tabs below show the idiomatic form for each language.
40214021
4022<Note>
4023 Tool Runner is available in all seven SDKs: Python, TypeScript, C#, Go, Java, PHP, and Ruby. See [Tool Runner](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-runner) for the full reference. The cURL and CLI tabs show a note instead of code; keep the Ring 4 loop for curl- or CLI-based scripts.
4024</Note>
4025
40264022<CodeGroup>
40274023 ```bash cURL
40284024 #!/bin/bash
agents-and-tools/tool-use/fine-grained-tool-streaming Changed · +1 / -1 lines
from line 484
484484
485485When a `tool_use` content block streams, the initial `content_block_start` event contains `input: {}` (an empty object). This is a placeholder. The actual input arrives as a series of `input_json_delta` events, each carrying a `partial_json` string fragment. To assemble the full input, concatenate these fragments and parse the result when the block closes.
486486
487Where your SDK provides an accumulator helper (as the Python, TypeScript, Go, Java, and Ruby tabs in the previous example do), it handles this for you. The manual pattern is for SDKs without a helper, or when you want full control over how the input is assembled.
487Where your SDK provides an accumulator helper (as the Python, TypeScript, Go, Java, and Ruby tabs in the previous example do), it handles this for you. Use the manual pattern when your SDK has no helper or when you want full control over how the input is assembled.
488488
489489The accumulation contract:
490490
agents-and-tools/tool-use/memory-tool Changed · +2 / -2 lines
from line 285
285285
286286Claude's reply to a request like the previous one ends with a `tool_use` block that requests a memory operation, such as `view /memories`. Your application executes the operation and returns the result in a `tool_result` block, then sends the conversation back so Claude can continue: the standard [tool-use loop](https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls).
287287
288Four SDKs provide memory tool helpers that handle the tool interface and the loop. Subclass `BetaAbstractMemoryTool` (Python and C#), use `betaMemoryTool` (TypeScript), or implement `BetaMemoryToolHandler` (Java) to back memory with your own storage, such as files on disk, a database, cloud storage, or encrypted files. Python and TypeScript also ship a ready-made local-filesystem implementation, `BetaLocalFilesystemMemoryTool`. The helper and tool-runner surfaces live in each SDK's beta namespace even though the memory tool itself doesn't require a beta header. The Go and Ruby SDKs have no memory helper, so those examples run the tool-use loop themselves, and PHP wraps your handler closure in its generic `BetaRunnableTool`. All three use an in-memory store that you replace with your own storage.
288Four SDKs provide memory tool helpers that handle the tool interface and the loop. Subclass `BetaAbstractMemoryTool` (Python and C#), use `betaMemoryTool` (TypeScript), or implement `BetaMemoryToolHandler` (Java) to back memory with your own storage, such as files on disk, a database, cloud storage, or encrypted files. Python and TypeScript also ship a ready-made local-filesystem implementation, `BetaLocalFilesystemMemoryTool`. The helper and tool-runner surfaces live in your SDK's beta namespace even though the memory tool itself doesn't require a beta header. The Go and Ruby SDKs have no memory helper, so those examples run the tool-use loop themselves, and PHP wraps your handler closure in its generic `BetaRunnableTool`. All three use an in-memory store that you replace with your own storage.
289289
290290<CodeGroup exclude="shell">
291291 ```python Python
from line 751
751751* Excludes hidden items (files starting with `.`) and `node_modules`
752752* Uses a tab character between the size and the path
753753
754The first `view` of `/memories` on an empty store is not an error. The SDKs' local-filesystem memory tools (`BetaLocalFilesystemMemoryTool`) create the memory root before Claude's first call and return the listing header followed by a single size-and-path line for the empty directory itself.
754The first `view` of `/memories` on an empty store is not an error. Where your SDK ships a local-filesystem memory tool, `BetaLocalFilesystemMemoryTool`, it creates the memory root before Claude's first call and returns the listing header followed by a single size-and-path line for the empty directory itself.
755755
756756**For files:** Return file contents with a header and line numbers:
757757
agents-and-tools/tool-use/overview Changed · +1 / -1 lines
from line 729
729729The current weather in San Francisco is 15 degrees Celsius with partly cloudy skies.
730730```
731731
732[Handle tool calls](https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls) covers each step in detail, including result formatting and error signaling; [Parallel tool use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/parallel-tool-use) covers responses that call several tools at once. To skip writing this round trip yourself, use [Tool Runner](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-runner): the SDKs execute your tools and send the results back automatically.
732[Handle tool calls](https://platform.claude.com/docs/en/agents-and-tools/tool-use/handle-tool-calls) covers each step in detail, including result formatting and error signaling; [Parallel tool use](https://platform.claude.com/docs/en/agents-and-tools/tool-use/parallel-tool-use) covers responses that call several tools at once. To skip writing this round trip yourself, use [Tool Runner](https://platform.claude.com/docs/en/agents-and-tools/tool-use/tool-runner): the SDK executes your tools and sends the results back automatically.
733733
734734For the full conceptual model including the agentic loop and when to choose each approach, see [How tool use works](https://platform.claude.com/docs/en/agents-and-tools/tool-use/how-tool-use-works).
735735
api/beta/organization/workspaces/archive Changed · +1 / -1 lines
from line 69
6969
7070 - `"us"`
7171
72 - `Unrestricted = "unrestricted"`
72 - `"unrestricted"`
7373
7474 - `default_inference_geo: "global" or "us"`
7575
api/beta/organization/workspaces/list Changed · +1 / -1 lines
from line 89
8989
9090 - `"us"`
9191
92 - `Unrestricted = "unrestricted"`
92 - `"unrestricted"`
9393
9494 - `default_inference_geo: "global" or "us"`
9595
api/beta/organization/workspaces/retrieve Changed · +1 / -1 lines
from line 71
7171
7272 - `"us"`
7373
74 - `Unrestricted = "unrestricted"`
74 - `"unrestricted"`
7575
7676 - `default_inference_geo: "global" or "us"`
7777
api/beta/organization/workspaces/update Changed · +2 / -2 lines
from line 29
2929
3030 - `"us"`
3131
32 - `Unrestricted = "unrestricted"`
32 - `"unrestricted"`
3333
3434 - `default_inference_geo: optional "global" or "us" or null`
3535
from line 125
125125
126126 - `"us"`
127127
128 - `Unrestricted = "unrestricted"`
128 - `"unrestricted"`
129129
130130 - `default_inference_geo: "global" or "us"`
131131
api/overview Changed · +1 / -1 lines
from line 148
148148
149149To go back a page, pass `prev_page` as the `page` parameter. `prev_page` is `null` when you're on the first page. Not all list endpoints support `prev_page`. Only `GET /v1/sessions` returns `prev_page`; on list endpoints that do not support backward pagination, the field is absent from the response rather than `null`. For a request walkthrough, see [Listing sessions](https://platform.claude.com/docs/en/managed-agents/session-operations#listing-sessions).
150150
151Every SDK provides an auto-paginating iterator that follows `next_page` for you. In Python and TypeScript, you get it by iterating the list result directly. The other SDKs provide the iterator through a separate method. SDK auto-pagination is forward-only; to go back a page, read `prev_page` from the response and pass it back as the `page` parameter yourself. See [client SDKs](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) for language-specific details.
151The SDK provides an auto-paginating iterator that follows `next_page` for you. For example, `for session in client.beta.sessions.list()` (python; typescript: `for await (const session of client.beta.sessions.list())`; go: `client.Beta.Sessions.ListAutoPaging()`; java: `client.beta().sessions().list().autoPager()`; csharp: `(await client.Beta.Sessions.List()).Paginate()`; php: `$client->beta->sessions->list()->pagingEachItem()`; ruby: `client.beta.sessions.list.auto_paging_each`) walks through every session. SDK auto-pagination is forward-only; to go back a page, read `prev_page` from the response and pass it back as the `page` parameter yourself. See [client SDKs](https://platform.claude.com/docs/en/cli-sdks-libraries/overview) for details.
152152
153153<Note>
154154 Some list endpoints use a different cursor scheme. The [Message Batches API](https://platform.claude.com/docs/en/build-with-claude/batch-processing), the [Models API](https://platform.claude.com/docs/en/api/models/list), and several [Admin API](https://platform.claude.com/docs/en/manage-claude/admin-api) endpoints take `after_id` and `before_id` query parameters instead of `page`. Their responses return `has_more`, `first_id`, and `last_id` instead of `next_page`. See the reference page for each endpoint for its exact pagination fields.
api/rate-limits Changed · +1 / -1 lines
from line 58
5858}
5959```
6060
61* The error type is `rate_limit_error`, the same as for a rate limit, but the response has no `retry-after` header. Retrying, including the SDKs' automatic retries, fails until access resumes.
61* The error type is `rate_limit_error`, the same as for a rate limit, but the response has no `retry-after` header. Retrying, including the SDK's automatic retries, fails until access resumes.
6262* On the Messages API, `error.details.error_code` is `enforced_spend_limit_reached`. Use it to tell this response apart from a rate limit.
6363* Moving to a higher tier restores access; see [Requesting higher limits](https://platform.claude.com/docs/en/api/rate-limits#requesting-higher-limits).
6464
build-with-claude/claude-in-amazon-bedrock Changed · +1 / -1 lines
from line 325
325325</Tabs>
326326
327327<Tip>
328 You can also use the standard `Anthropic` client: set `base_url` to `https://bedrock-mantle.{region}.api.aws/anthropic` and pass your bearer token as `api_key`. This path supports bearer-token authentication only. SigV4 signing requires `AnthropicBedrockMantle` (csharp: `AnthropicBedrockMantleClient`; go: `bedrock.NewMantleClient`; java: `BedrockMantleBackend`; php: `MantleClient`; ruby: `Anthropic::BedrockMantleClient`).
328 You can also create the standard client with `Anthropic` (python, typescript; go: `anthropic.NewClient()`; java: `AnthropicOkHttpClient.builder()`; csharp: `AnthropicClient`; php: `Anthropic\Client`; ruby: `Anthropic::Client`): set `base_url` (python, ruby; typescript: `baseURL`; go: `option.WithBaseURL()`; java: `.baseUrl()`; csharp: `BaseUrl`; php: `baseUrl`) to `https://bedrock-mantle.{region}.api.aws/anthropic` and pass your bearer token as `api_key` (python, ruby; typescript, php: `apiKey`; go: `option.WithAPIKey()`; java: `.apiKey()`; csharp: `ApiKey`). This path supports bearer-token authentication only. SigV4 signing requires `AnthropicBedrockMantle` (csharp: `AnthropicBedrockMantleClient`; go: `bedrock.NewMantleClient`; java: `BedrockMantleBackend`; php: `MantleClient`; ruby: `Anthropic::BedrockMantleClient`).
329329</Tip>
330330
331331## Supported models
build-with-claude/claude-on-amazon-bedrock-legacy Changed · +2 / -2 lines
from line 533
533533
534534You can authenticate with Bedrock using bearer tokens instead of AWS credentials. This is useful in corporate environments where teams need access to Bedrock without managing AWS credentials, IAM roles, or account-level permissions.
535535
536The simplest approach is to set the `AWS_BEARER_TOKEN_BEDROCK` environment variable, which each SDK detects automatically when resolving credentials from the environment.
536The simplest approach is to set the `AWS_BEARER_TOKEN_BEDROCK` environment variable, which the SDK detects automatically when resolving credentials from the environment.
537537
538538To provide a token programmatically:
539539
from line 540
540540<Tabs>
541541 <Tab title="cURL">
542542 <Note>
543 This section shows how to configure a bearer token in an SDK client. The SDKs also read the token from the `AWS_BEARER_TOKEN_BEDROCK` environment variable. To make direct HTTP requests with a bearer token, see the [Amazon Bedrock documentation](https://docs.aws.amazon.com/bedrock/).
543 This section shows how to configure a bearer token in an SDK client, which also reads the token from the `AWS_BEARER_TOKEN_BEDROCK` environment variable. To make direct HTTP requests with a bearer token, see the [Amazon Bedrock documentation](https://docs.aws.amazon.com/bedrock/).
544544 </Note>
545545 </Tab>
546546
build-with-claude/fallback-credit Changed · +1 / -1 lines
from line 627
627627</Accordion>
628628
629629<Accordion title="When fallback_has_prefill_claim is absent">
630 The field is `null` only when the token is also `null`, so a value you observe while holding a token is never `null`. It can still be absent (`None` in the typed SDKs) on Amazon Bedrock, Google Cloud, and Microsoft Foundry while their support for the field rolls out. In that case, treat the retry shape as unknown rather than as `false`. Try the appended-assistant-message shape first, and rely on the rejection handling in [When a retry is rejected](https://platform.claude.com/docs/en/build-with-claude/fallback-credit#when-a-retry-is-rejected), which falls back to the unchanged body.
630 The field has no value only when the token has none either, so while you hold a token the field has a value, except on Amazon Bedrock, Google Cloud, and Microsoft Foundry, where it can still be absent while their support for the field rolls out. In that case, treat the retry shape as unknown rather than as `false` (python: `False`). Try the appended-assistant-message shape first, and rely on the rejection handling in [When a retry is rejected](https://platform.claude.com/docs/en/build-with-claude/fallback-credit#when-a-retry-is-rejected), which falls back to the unchanged body.
631631</Accordion>
632632
633633<Accordion title="Echoing the refused response's content">
build-with-claude/fast-mode Changed · +1 / -1 lines
from line 407
407407
408408### Automatic retries
409409
410When fast mode rate limits are exceeded, the API returns a `429` error with a `retry-after` header. The Anthropic SDKs automatically retry these requests up to 2 times by default (configurable with `max_retries` (typescript, java, php: `maxRetries`; csharp: `MaxRetries`; go: `option.WithMaxRetries`)), waiting for the server-specified delay before each retry. Because fast mode uses continuous token replenishment, the `retry-after` delay is typically short and requests succeed once capacity is available.
410When fast mode rate limits are exceeded, the API returns a `429` error with a `retry-after` header. The SDK automatically retries these requests up to 2 times by default (configurable with `max_retries` (typescript, java, php: `maxRetries`; csharp: `MaxRetries`; go: `option.WithMaxRetries`)), waiting for the server-specified delay before each retry. Because fast mode uses continuous token replenishment, the `retry-after` delay is typically short and requests succeed once capacity is available.
411411
412412### Falling back to standard speed
413413
build-with-claude/files Changed · +1 / -1 lines
from line 687
687687
688688#### List files
689689
690Retrieve a list of your uploaded files. The endpoint is paginated: each request returns up to `limit` files (20 by default, and at most 1,000), and the response's `next_page` cursor fetches the next page when passed back as the `page` parameter. Files are ordered newest first. See the [List Files API reference](https://platform.claude.com/docs/en/api/files/list). The SDKs return the first page and provide auto-pagination helpers. The CLI example bounds the total with `--max-items`:
690Retrieve a list of your uploaded files. The endpoint is paginated: each request returns up to `limit` files (20 by default, and at most 1,000), and the response's `next_page` cursor fetches the next page when passed back as the `page` parameter. Files are ordered newest first. See the [List Files API reference](https://platform.claude.com/docs/en/api/files/list). The SDK returns the first page and provides [auto-pagination](https://platform.claude.com/docs/en/api/overview#pagination) helpers. The CLI example bounds the total with `--max-items`:
691691
692692<CodeGroup>
693693 ```bash cURL