> ## Documentation Index
> Fetch the complete documentation index at: https://docs.labelbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Sign in, create an API key, create an environment and an agent, run a graded session, and read the grader's verdict in about 10 minutes.

In this quickstart, an agent summarizes a short product update in exactly two bullet points. A separate grader checks the summary against your rubric and sends it back until it passes. You'll do each step in the console or with code, and finish with a verdict you can read.

## Before you begin

* **An account.** The first time you sign in, Recursion creates your tenant and its **Default** organization, and makes you the primary owner, so you can do everything on this page. See [Organizations and roles](/managed-agents/organizations-and-roles).
* **For the code path**: Node.js with `@labelbox/recursion-sdk`, or `curl` and `jq`. See [Install the SDK](/managed-agents/api#install-the-sdk). From Python, send the cURL requests with your HTTP client; see [Python and other languages](/managed-agents/api#python-and-other-languages).

## 1. Sign in

1. Open the [Recursion console](https://recursion.labelbox.com).
2. Tick the box to agree to the Terms of Service, Privacy Policy, and Release Agreement.
3. Click **Continue with Google**, and sign in with a verified email address.

The console opens on **Agents**. If you see **Sign-in is limited to approved accounts.**, the email address you used isn't approved to sign in.

## 2. Create an API key

Skip this step if you'll use only the console.

1. In the sidebar, click **API keys**, then **Create key**.
2. Enter `quickstart` in **Name**.
3. Choose **7 days** in **Expires**.
4. In **Scope**, choose **Default** instead of **Tenant**. This makes an organization-scoped key, which needs no extra headers.
5. Click **Create key**, then copy the key. It starts with `rma_` and is shown only once.

Export it in the shell where you'll run the code:

```bash theme={"theme":"css-variables"}
export RECURSION_API_KEY='rma_...'
```

The TypeScript samples below assume the `rl` client from [Client setup](/managed-agents/api#client-setup). Keep the key out of source files and chat messages. See [API keys](/managed-agents/api-keys).

## 3. Create an environment

An environment is where the agent's sandbox runs. This task needs no extra software and no internet access.

<Tabs>
  <Tab title="Console">
    1. In the sidebar, click **Environments**, then **Create environment**.
    2. Enter `Quickstart sandbox` in **Name**.
    3. Choose **Agent runner** in **Runtime**.
    4. Leave **Internet access** set to **No access**, and leave the setup script empty.
    5. Click **Create environment**.
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"theme":"css-variables"}
    const environment = await rl.managedAgents.createEnvironment({
      body: { name: 'Quickstart sandbox', provider: 'runs' },
    });
    console.log(environment.environment_id);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"theme":"css-variables"}
    environment_id=$(curl -sS -X POST 'https://api.recursion.labelbox.com/managed-agents/v1/environments' \
      -H "Authorization: Bearer $RECURSION_API_KEY" \
      -H 'Content-Type: application/json' \
      -d '{"name": "Quickstart sandbox", "provider": "runs"}' | jq -r '.environment_id')
    echo "$environment_id"
    ```
  </Tab>
</Tabs>

The response is the saved environment. With no setup script, it needs no verification run. Some of its fields:

```json theme={"theme":"css-variables"}
{
  "environment_id": "9d3e7b52-1a4c-4f80-b6e9-2c8a5d0f7e13",
  "name": "Quickstart sandbox",
  "provider": "runs",
  "computer_use": false,
  "setup_verification": { "status": "not_applicable", "stale": false }
}
```

## 4. Create an agent

An agent is the model and instructions. Use a `modelId` from `listModels`; `anthropic/claude-sonnet-5` is an example.

<Tabs>
  <Tab title="Console">
    1. In the sidebar, click **Agents**, then **Create agent**.

    2. Click the **Blank** card.

    3. Enter `Update summarizer` in **Name**.

    4. Choose a model in **Model**.

    5. Enter this **System prompt**:

       ```text theme={"theme":"css-variables"}
       Summarize only the facts in the task. Follow the requested format exactly.
       ```

    6. Click **Create agent**.
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"theme":"css-variables"}
    const agent = await rl.managedAgents.createAgent({
      body: {
        name: 'Update summarizer',
        model: 'anthropic/claude-sonnet-5',
        system: 'Summarize only the facts in the task. Follow the requested format exactly.',
      },
    });
    console.log(agent.agent_id);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"theme":"css-variables"}
    agent_id=$(curl -sS -X POST 'https://api.recursion.labelbox.com/managed-agents/v1/agents' \
      -H "Authorization: Bearer $RECURSION_API_KEY" \
      -H 'Content-Type: application/json' \
      -d '{
        "name": "Update summarizer",
        "model": "anthropic/claude-sonnet-5",
        "system": "Summarize only the facts in the task. Follow the requested format exactly."
      }' | jq -r '.agent_id')
    echo "$agent_id"
    ```
  </Tab>
</Tabs>

The response is the saved agent. These are the fields the next step uses:

```json theme={"theme":"css-variables"}
{
  "agent_id": "3f8a2c61-7b4d-4e90-a1c5-6d2e9b0f4a87",
  "latest_agent_version_id": "c2d4e6f8-1a3b-4c5d-8e7f-9a0b1c2d3e4f",
  "name": "Update summarizer"
}
```

## 5. Start a graded session

The task and the facts to summarize go straight into the outcome, so there's nothing to upload. The rubric tells the grader what "done" means.

<Tabs>
  <Tab title="Console">
    1. Open **Update summarizer** under **Agents**, then click **Start session**.

    2. Choose **Quickstart sandbox** in **Environment**.

    3. Under **Task**, tick **Grade this session against a rubric**.

    4. Replace the text in **Rubric** with:

       ```markdown theme={"theme":"css-variables"}
       ## Content
       - The summary states that Enterprise Plus revenue grew 18% year over year.
       - The summary states that North America customer retention fell from 94% to 91%.

       ## Format
       - The summary has exactly two bullet points.
       ```

    5. Enter this in **Opening message**:

       ```text theme={"theme":"css-variables"}
       Summarize this quarterly update in exactly two bullet points for an executive.

       Enterprise Plus revenue grew 18% year over year after the workflow launch.
       North America customer retention fell from 94% to 91% during the same quarter.
       ```

    6. Click **Launch session**. The console opens the session while the sandbox starts.
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"theme":"css-variables"}
    const started = await rl.managedAgents.startSession({
      'Idempotency-Key': 'quickstart-summary-1',
      body: {
        agent_id: agent.agent_id,
        environment_id: environment.environment_id,
        outcome: {
          description: [
            'Summarize this quarterly update in exactly two bullet points for an executive.',
            'Enterprise Plus revenue grew 18% year over year after the workflow launch.',
            'North America customer retention fell from 94% to 91% during the same quarter.',
          ].join('\n\n'),
          rubric: [
            '## Content',
            '- The summary states that Enterprise Plus revenue grew 18% year over year.',
            '- The summary states that North America customer retention fell from 94% to 91%.',
            '## Format',
            '- The summary has exactly two bullet points.',
          ].join('\n'),
          max_iterations: 3,
        },
      },
    });
    console.log(started.session_id);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"theme":"css-variables"}
    session_id=$(jq -n --arg agent "$agent_id" --arg env "$environment_id" '{
      agent_id: $agent,
      environment_id: $env,
      outcome: {
        description: "Summarize this quarterly update in exactly two bullet points for an executive.\n\nEnterprise Plus revenue grew 18% year over year after the workflow launch.\n\nNorth America customer retention fell from 94% to 91% during the same quarter.",
        rubric: "## Content\n- The summary states that Enterprise Plus revenue grew 18% year over year.\n- The summary states that North America customer retention fell from 94% to 91%.\n## Format\n- The summary has exactly two bullet points.",
        max_iterations: 3
      }
    }' | curl -sS -X POST 'https://api.recursion.labelbox.com/managed-agents/v1/sessions' \
      -H "Authorization: Bearer $RECURSION_API_KEY" \
      -H 'Idempotency-Key: quickstart-summary-1' \
      -H 'Content-Type: application/json' \
      -d @- | jq -r '.session_id')
    echo "$session_id"
    ```
  </Tab>
</Tabs>

The start returns `202 Accepted` right away. The agent works in the background.

```json theme={"theme":"css-variables"}
{
  "session_id": "b7e1c9a4-3d62-4f15-8a07-5c2e9f6d1b38",
  "status_path": "/v1/sessions/b7e1c9a4-3d62-4f15-8a07-5c2e9f6d1b38"
}
```

The code samples cap grading at three passes with `max_iterations`. The console sends no cap, so the agent revises until the grader is satisfied.

## 6. Read the verdict

The work is done when the newest outcome's `status` is `terminal`. It passed when `terminal_result` is `satisfied`. This usually takes a minute or two.

<Tabs>
  <Tab title="Console">
    1. Watch the transcript: the agent's two bullet points appear as it works.
    2. Click **Outcome** above the transcript.
    3. Confirm the result is **satisfied** and that each criterion shows **pass** with the grader's rationale.
  </Tab>

  <Tab title="TypeScript">
    ```typescript theme={"theme":"css-variables"}
    const sessionId = started.session_id;
    let outcome;
    while (outcome?.status !== 'terminal') {
      await new Promise((resolve) => setTimeout(resolve, 10_000));
      const session = await rl.managedAgents.getSession({ session_id: sessionId });
      if (session.status === 'failed' || session.status === 'cancelled') {
        throw new Error(`Session ${session.status}: ${session.failure?.code ?? ''}`);
      }
      const { outcomes } = await rl.managedAgents.listSessionOutcomes({ session_id: sessionId });
      outcome = outcomes?.at(-1);
    }
    console.log(outcome.terminal_result, outcome.evaluations?.at(-1)?.criteria);
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"theme":"css-variables"}
    until [ "$(curl -sS "https://api.recursion.labelbox.com/managed-agents/v1/sessions/$session_id/outcomes" \
      -H "Authorization: Bearer $RECURSION_API_KEY" | jq -r '.outcomes[-1].status // empty')" = terminal ]; do
      sleep 10
    done
    curl -sS "https://api.recursion.labelbox.com/managed-agents/v1/sessions/$session_id/outcomes" \
      -H "Authorization: Bearer $RECURSION_API_KEY" | jq '.outcomes[-1]'
    ```
  </Tab>
</Tabs>

A passing result includes these fields. The first grading pass is `iteration` `0`.

```json theme={"theme":"css-variables"}
{
  "outcome_id": "e5a1f3c7-2b9d-4a60-8c14-7f3e2d1b0a96",
  "status": "terminal",
  "terminal_result": "satisfied",
  "max_iterations": 3,
  "evaluations": [
    {
      "iteration": 0,
      "result": "satisfied",
      "criteria": [
        {
          "criterion_id": "r7c41e9a2b3d8.c001",
          "section": "Content",
          "criterion_text": "The summary states that Enterprise Plus revenue grew 18% year over year.",
          "verdict": "pass",
          "rationale": "The first bullet states the 18% year-over-year revenue growth.",
          "weight": 1
        },
        {
          "criterion_id": "r7c41e9a2b3d8.c003",
          "section": "Format",
          "criterion_text": "The summary has exactly two bullet points.",
          "verdict": "pass",
          "rationale": "The response contains two bullet points and no other list items.",
          "weight": 1
        }
      ]
    }
  ]
}
```

## What happened

* The session froze the agent version and the environment, so editing either now won't change this run.
* The agent worked in its own sandbox and answered in the transcript. Every step was recorded as an event.
* After the agent's turn, the grader checked each rubric criterion. A failing criterion would have sent the grader's rationale back to the agent for another attempt.
* `satisfied` means no criterion failed in the final grading pass. The session's `execution_state` is now `completed`, with `stop_reason: "outcome_satisfied"`.

To continue, send a follow-up message from the console composer or with `sendSessionEvents`. The session resumes in the same sandbox if it still exists.

## What can go wrong

| Code or symptom                                      | Cause                                                                                                 | Fix                                                                                                                                 |
| ---------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| **Sign-in is limited to approved accounts.**         | The email address you signed in with isn't approved.                                                  | Sign in with an approved account.                                                                                                   |
| `401 unauthorized`                                   | `RECURSION_API_KEY` isn't set in this shell, was copied incompletely, or has expired or been revoked. | Run `echo ${RECURSION_API_KEY:0:4}` to check it starts with `rma_`. Create a new key if needed.                                     |
| `400 invalid_request` mentioning `x-organization-id` | You chose a **Tenant** scope for the key.                                                             | Add `x-organization-id: default` to every request, or create a key scoped to **Default**. See [API keys](/managed-agents/api-keys). |
| `400 invalid_request` on `model`                     | The model id isn't in your models list.                                                               | Call `listModels` and use a `modelId` it returns.                                                                                   |
| `422 environment_not_verified`                       | You added a setup script and it hasn't passed a verification run.                                     | Save and test the setup, or remove the script. See [Environments](/managed-agents/environments).                                    |
| `409 idempotency_conflict`                           | You changed the start request but reused `quickstart-summary-1`.                                      | Use a new `Idempotency-Key` for a new request.                                                                                      |
| Session stays `queued`                               | The agent is already running as many root sessions as its concurrency cap allows.                     | Wait for one to finish, or raise `max_concurrent_sessions`.                                                                         |
| Session `failed` with `sandbox_provision_timeout`    | Compute wasn't ready within five minutes.                                                             | Send a follow-up message to retry, or start a new session.                                                                          |
| Outcome ends `max_iterations_reached`                | A criterion still failed on the third pass.                                                           | Read each failed criterion's `rationale`, then tighten the prompt or the rubric.                                                    |

See [Troubleshooting](/managed-agents/troubleshooting) and [Errors](/managed-agents/errors) for more, and [Limits](/managed-agents/limits) for every limit.

## Next steps

<CardGroup cols={2}>
  <Card title="How it works" href="/managed-agents/how-it-works">
    See how sessions, credentials, and grading fit together.
  </Card>

  <Card title="Define outcomes" href="/managed-agents/outcomes">
    Write rubrics that grade reliably, and read every grading pass.
  </Card>

  <Card title="Give your agent tools" href="/managed-agents/tools">
    Add web search, MCP servers, and skills.
  </Card>

  <Card title="Store credentials" href="/managed-agents/vaults">
    Give agents tokens and secrets without putting them in a prompt.
  </Card>
</CardGroup>
