Rate limits
Limits are applied per credential, not per IP address, because AI agents tend to burst and people often share a network. The credential is your token, or your connection if you signed in to connect; a connection counts as a single bucket no matter how often it refreshes in the background.
The limits
Section titled “The limits”| Surface | Per minute | Per hour |
|---|---|---|
| Most endpoints | 120 | 3,000 |
Search (/v1/search) |
30 | 600 |
The member directory (/v1/members, /v1/members/progress, /v1/members/{id}, /v1/invitations, /v1/reporting-lines) |
30 | 600 |
Learning queues (/v1/me/learning-queue, /v1/people/{id}/learning-queue) |
20 | 300 |
| Drafting an announcement | 60 | 600 |
| Planning or previewing an announcement | 10 | 60 |
| Sending or withdrawing an announcement | 5 | 30 |
| Creating a document or adding a YouTube video | 10 | 100 |
| Assigning or unassigning a lesson | 10 | 60 |
| Sending a pop quiz | 5 | 30 |
| Other training changes (obligations, retraining, a retraining policy) | 30 | 300 |
| Creating a lesson, changing what it teaches or its settings, writing its material again, or splitting it | 5 | 30 |
| Other lesson changes (sharing, tagging, closing, reopening, deleting) | 30 | 300 |
| Publishing a document’s, guide’s, video’s or audio recording’s draft | 5 | 30 |
| Other content changes (titles, drafts, sharing, tags, what a team holds) | 30 | 300 |
| Filing an issue | 10 | 60 |
| Previewing or deleting resources | 30 | 300 |
| Deciding a content review | 5 | 30 |
| Deciding an issue | 10 | 40 |
| Managing people (inviting, a role, deactivating, reactivating, removing, a reporting line) | 10 | 60 |
These are generous for interactive use. They exist to stop a runaway loop, not to throttle normal work.
Each of the member directory reads hands back names, addresses and, for an
organization admin, phone numbers a page at a time, so the cost that matters is how
fast a credential could copy the whole directory. They are held to a lower limit
than the other reads, and the same numbers apply to the MCP tools list_members,
get_member, list_pending_invitations, list_member_progress and
list_reporting_lines. The budget is per route and per tool, counted separately,
and not one pool across them.
A learning queue is not stored: every request works it out from the person’s roles,
duties, mastery and obligations, and every page of it is worked out again, so it is
held to a lower limit than the other reads. The same numbers apply to the MCP tools
get_my_learning_queue and get_user_learning_queue.
Assigning a lesson and sending a pop quiz reach people by email and text, and
each has questions written for every person it reaches; unassigning can take a
lesson and its progress back from hundreds of people at once. So they are held
lower than the rest of the training changes, with
the same numbers for the MCP tools assign_training, unassign_training and
create_pop_quiz.
Creating or reworking a lesson has a model summarize its sources, plan its quiz
and write its material, and a split writes material for every lesson it makes, so those
lesson changes are held as low as sending a pop quiz,
with the same numbers for the MCP tools create_lesson, update_lesson,
update_lesson_content, generate_lesson_content, split_lesson and
apply_lesson_split.
Publishing a draft has the resource read again from the start, chunked,
embedded and its knowledge extracted, before the people trained on it can be
retrained, so publishing is held as
low as creating a lesson, with the same numbers for the MCP tool
publish_draft.
Filing an issue calls no model, but each one lands
in front of your reviewers, and one assigned to someone notifies them. A person
files a few at a sitting, so it is held well below the other changes, with the
same numbers for the MCP tool create_issue.
Previewing or deleting resources asks the same
questions the library asks before a delete, and is held to the same numbers as
the other content changes. The same numbers apply to the MCP tools
preview_content_deletion and delete_content, counted per tool.
Approving a content review publishes the submission, which can retrain people
and spend a model run when the knowledge base has moved, and each decision
emails the person who submitted it. A reviewer decides a handful at a sitting,
so deciding a review is held as low as
publishing a draft, with the same numbers for the MCP tools
approve_content_review, reject_content_review and
request_content_review_changes.
Deciding an issue dismisses, reopens, assigns,
merges or resolves one, and a new assignment notifies the person or role it
names. Each of those calls, and each of the MCP tools dismiss_issue,
reopen_issue, assign_issue, merge_issue, select_issue and
resolve_content_gap, is held to 10 a minute and 40 an hour.
Inviting someone sends an email or a text, and deactivating or removing someone
ends their access, so managing people is held
to the same numbers. Each route and each of invite_member, set_member_role,
deactivate_member, reactivate_member, remove_member and
set_member_manager has its own budget.
The announcement limits are lower because those acts cost something: planning and
previewing each spend a model call, and sending or withdrawing reaches real
people. The same numbers apply to the MCP tools, counted per tool call and not per
request, so send_announcement is held to five calls a minute however the
requests are made. The MCP endpoint takes one JSON-RPC message per request and
refuses a batch.
Handling a 429
Section titled “Handling a 429”When you exceed a limit, the API responds with HTTP 429 Too Many Requests and
a Retry-After header telling you how many seconds to wait. Respect it:
async function withRetry(makeRequest, maxRetries = 5) { for (let attempt = 0; attempt <= maxRetries; attempt++) { const res = await makeRequest(); if (res.status !== 429) return res; const wait = Number(res.headers.get('Retry-After') ?? 5); await new Promise((r) => setTimeout(r, wait * 1000)); } throw new Error('Still rate-limited after the maximum number of retries');}