Skip to main content
Every Managed Agents operation follows the same rules for authentication, retries, paging, and errors. Read this page once, then use the Endpoints reference for each operation’s exact schema.

Base URL

Every operation lives under one base path:
Requests and responses are JSON. Most fields use snake_case. A few responses, such as the model list, use camelCase, so follow each operation’s schema in Endpoints.

Authentication

Send an API key as a bearer token on every request:
Create the key in the console under API keys. See API keys for scopes, expiry, and safe storage. A key acts as you, with the role you hold in that organization at the moment of the request. If an admin changes your role, your keys follow on the next request. Once the organization is resolved, the response carries recursion-organization-id and recursion-tenant-id headers that name the scope the request ran in.

Install the SDK

The TypeScript SDK is @labelbox/recursion-sdk:
From Python or any other language, call the REST API directly with your usual HTTP client. Every page shows each request as cURL, and Endpoints has each operation’s exact schema. See Python and other languages.

Client setup

Export your key, then create one client for your process. Every TypeScript sample in these docs assumes the rl client below. Always pass baseUrl as shown.
A successful call returns the models you can use in agents:

Tenant-scoped keys

A tenant-scoped key must name the organization on every request. Use an organization id, or default for your tenant’s default organization.

Call shape

Send every body as JSON. A body in a media type the API doesn’t accept returns 415 unsupported_media_type. Skill bundle uploads are the one exception; they use multipart/form-data. See Skills. A few operations, such as getSkillVersionContent and getSessionImage, have no TypeScript method. Call them over REST, which works from any language.

Python and other languages

There is no Python SDK for this API. Send the same REST requests the cURL samples show, with the bearer header on each one. For example, with httpx:
Translate any cURL sample the same way: the path follows /managed-agents/v1, -d becomes a JSON body, and each -H becomes a header, such as Idempotency-Key on startSession.

Asynchronous session starts

startSession returns 202 Accepted as soon as the session is recorded. It doesn’t wait for the sandbox or the agent.
Follow the session with getSession or by streaming its events. The session record is authoritative. The event stream is written separately and can lag it, so an empty event list doesn’t mean the session is still starting. What success means depends on the work:

Idempotent creates

startSession requires an Idempotency-Key header, and createAgent accepts one. Use a stable key for each logical create, so a retry after a timeout or dropped connection can’t create a second session or agent. Keys hold 1 to 256 visible ASCII characters, sent as exactly one header value. A malformed or repeated header returns 400 invalid_request. Keys share one namespace per organization. A completed key is remembered for about 24 hours, and an abandoned in-progress key can be reused after about 1 hour. In TypeScript, pass 'Idempotency-Key' at the top level of the operation input. Over REST, send the Idempotency-Key header. Retry with the same bytes: reordering JSON keys counts as a different request. createVault takes its retry key in the body instead, as idempotency_key, up to 128 characters.

Pagination

Paged list operations return a continuation token. Each operation documents its own default and maximum page size. A page can hold fewer items than limit and still have a next token, because event pages also have a size budget. A session-list token is valid for one hour and only with the filters and limit it was issued for. A token that’s no longer valid returns 400 invalid_request with details.field set to page_token, so restart the list without it.

Errors

Every error response has the same flat shape:
The TypeScript client throws on any non-2xx response. REST callers check the HTTP status and code. See Errors for every code and what to do about it.

Rate limits

Requests are limited per person, across all your keys and console use. Event streams are also limited in how many can be open at once. Numeric limits aren’t published and can change. When Retry-After is absent, back off exponentially with jitter, starting around one second. See Limits for every other limit.

Request ids

Every response carries an x-request-id header, and error bodies repeat it as details.requestId. You can send your own x-request-id of up to 128 letters, digits, _, ., :, or -, and it’s echoed back so you can match it to your own logs.

Next steps

Quickstart

Create an environment and an agent, run a graded session, and read the verdict.

Errors

Look up every error code with its cause, fix, and retry guidance.

Limits

Find every size, count, and time limit in one place.

Troubleshooting

Match a symptom to its cause and fix.