---
title: "Create a Research Agent session"
method: POST
path: "/sessions/agents"
tags: ["Research Agent"]
---

# Create a Research Agent session

`POST /sessions/agents`

## Request

- Base URL: `https://elicit.com/api/v2`
- URL: `https://elicit.com/api/v2/sessions/agents`
- Auth: HTTP bearer

Start a stateful Research Agent session. Elicit investigates the query asynchronously, reports its activity as structured events, and may produce downloadable artifacts.

The response returns immediately with a `sessionId`. Use the events endpoint to follow the research, then send messages to refine or continue it. The session is also available at the returned `url`.

### Project context

Optionally pass `projectId` to start inside an existing project you own. Find one with `GET /api/v2/projects`, or create one first with `POST /api/v2/projects` and a body such as `{"name":"GLP-1 safety review","goal":"Compare cardiovascular outcomes"}`. Then pass the returned `id` to this endpoint. MCP supports the same workflow with `list_projects`, `create_project`, and `create_agent_session`.

The session becomes a project item before its first turn starts, and the agent receives the project context from the initial query. The response includes `projectId`. Shared projects are not supported, even with writer access. A missing, removed, deleted, or non-owned project returns `400 invalid_request` before creating a session or charging workflow quota. Omission preserves standalone creation. Creating a project is a separate operation; a failed session creation leaves the project available to reuse.

### Research depth

Optionally set `researchDepth` to `fastest`, `fast`, `balanced`, `smart`, or `smartest` when creating a session (also supported by MCP's `create_agent_session`). Omission preserves the existing account/model default. The selected preset is applied through the same server-side configuration and entitlement checks as the web interface. Plan and contract limits still apply: unavailable depths are reduced to the allowed ceiling, so `smartest` becomes `smart` on Pro, and Enterprise accounts without higher-depth access are limited to `balanced`. `custom` and arbitrary model configuration are not supported. This option is only available at creation, not on follow-up messages.

### End-to-end workflow

A full research task may involve several requests against a single session. To drive it end to end:

1. **(Optional) Upload files.** POST /api/v2/files, PUT the bytes to the presigned URL, and keep each `file_id` (see the Upload endpoint).
2. **Create the session.** POST /api/v2/sessions/agents with your `query` and any `attachments`. The response is immediate with `status: "processing"` and a `sessionId`.
3. **Poll for activity.** GET /api/v2/sessions/agents/:sessionId/events. Pass the returned `cursor` unchanged on each subsequent poll to receive immutable event occurrences not observed at that checkpoint. Append them in response order and deduplicate retries by `eventId`. Poll every 3–10 seconds while the top-level `status` is `processing`.
4. **Detect idle.** The agent is ready for another request when a `session_idle` event appears and the top-level `status` returns to `completed`. For a Research Agent session, `completed` means **idle and awaiting input** — not that the session is permanently closed. Watch for these events along the way:
   - `question` — the agent needs input; answer it with a follow-up message.
   - `error` — the agent encountered an error; `retryable` indicates whether resending is worthwhile.
   - `session_paused` — the account hit its usage limit; the status becomes `pausedForInsufficientQuota`. Resolve the limit, then resume the session via POST /api/v2/sessions/:sessionId/resume (or the Elicit web interface) before continuing.
5. **Send a follow-up.** POST /api/v2/sessions/agents/:sessionId/messages with your message (and any `attachments`). Correlate the returned `messageId` with the matching `user_message` event, then return to step 3.
6. **Retrieve artifacts.** GET /api/v2/sessions/agents/:sessionId/artifacts to list what the agent produced: files appear under `artifacts` (GET .../artifacts/:artifactId/download for a short-lived presigned download URL — treat it as a credential), and interactive outputs (tables, prose, presentations, figures) appear under `deliveredOutputs` (GET .../artifacts/:artifactId/content for their contents).
7. **Retrieve cited sources.** GET /api/v2/sessions/agents/:sessionId/sources for every source the session cited, listed once each with its abstract. Join it to the citations on the events feed by `sourceRef`.
8. **(Optional) Stop early.** POST /api/v2/sessions/agents/:sessionId/stop to interrupt a running turn, then poll the events endpoint for the `session_stopped` event.

### Session status

The list, detail, and events endpoints all report the same top-level `status`:

- `processing` — the agent is working (or the session has not started yet).
- `completed` — idle and awaiting input; the latest work finished successfully.
- `failed` — the latest work ended with an error.
- `pausedForInsufficientQuota` — paused at the account usage limit; resume once the limit clears.

The shared session-status schema also includes `unknown` for legacy reports and systematic reviews. Agent endpoints return the four statuses above: when no execution outcome is available and the session is not quota-paused, they report `processing` rather than `unknown`.

Application errors use the standard `{ "error": { "code", "message" } }` envelope. The edge rate limit's `429` response is the flat format described under Error Handling.

### Example

```bash
# Minimal
curl -X POST https://elicit.com/api/v2/sessions/agents \
  -H "Authorization: Bearer elk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"query":"What are the effects of GLP-1 receptor agonists on cardiovascular outcomes?"}'

# Start inside an owned project
curl -X POST https://elicit.com/api/v2/sessions/agents \
  -H "Authorization: Bearer elk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"query":"Compare the latest trials.","projectId":"9c1f6a7e-5d24-4a3b-9f0e-1b2c3d4e5f60"}'

# Select a research depth
curl -X POST https://elicit.com/api/v2/sessions/agents \
  -H "Authorization: Bearer elk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"query":"Compare randomized trials of GLP-1 receptor agonists.","researchDepth":"smart"}'

# With an uploaded file attached to the initial turn
curl -X POST https://elicit.com/api/v2/sessions/agents \
  -H "Authorization: Bearer elk_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"query":"Summarize the attached trial and compare it to the current literature.","attachments":[{"file_id":"a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"}]}'
```

## Request body

- object
  - `query` string, required: The initial query for the research agent. Elicit creates a stateful research session that investigates the query. The session is continuable in the Elicit web interface.
  - `attachments` object[]: Files to attach to this turn, each referencing a file_id from POST /api/v2/files. A session can hold at most 100 distinct files totaling 10GB across all turns. An already-attached file can be referenced again in the same session without consuming additional capacity, but not claimed by another session or import. Duplicate file_ids within one request are rejected.
    - `file_id` string, uuid, required: The file_id returned by POST /api/v2/files for a previously uploaded file.
  - `projectId` string, uuid: Start the session in an existing project you own. Use GET /api/v2/projects (MCP: list_projects) to find an owned project, or POST /api/v2/projects (MCP: create_project) to create one first. Shared projects are not supported, even with writer access. Omit to start a standalone session.
  - `researchDepth` 'fastest' | 'fast' | 'balanced' | 'smart' | 'smartest': Research-depth preset for the initial query: fastest, fast, balanced, smart, or smartest. Omit to use the existing account/model default. Plan and contract limits still apply: unavailable depths are reduced to the allowed ceiling (for example, smartest becomes smart on Pro). Custom model configuration is not supported.

## Response `202`

Session creation accepted. The Research Agent is processing the initial query asynchronously.

- CreateAgentSessionResponse
  - `sessionId` string, required: Unique identifier for the research agent session.
  - `status` 'processing', required: Initial status is always processing.
  - `url` string, required: URL to view the session in the Elicit web interface. Only the owner can continue it.
  - `projectId` string, uuid: The project containing the new session. Omitted for standalone sessions.

## Other responses

- `400`: Invalid request: query/message must contain 1–20,000 characters and attachments must satisfy the schema (invalid_request). Attachment checks can also return file_not_uploaded if the upload cannot be verified, or file_size_mismatch if the uploaded byte length differs from size_bytes.
- `401`: Authentication failed. The API key is missing, invalid, revoked, or expired.
- `402`: Insufficient quota. For credits-based accounts, and for organization members with a weekly workflow-run limit, `error.details.reason` says why (`credits_exhausted` or `spend_limit_reached`) and `error.details.resetsAt` when the block lifts.
- `403`: API access is not available on your current plan. Upgrade to Pro or above to use the API.
- `404`: An attachment file_id does not exist or belongs to another user (attachment_not_found).
- `409`: An attachment belongs to another session/import (attachment_already_used), adding files would exceed the 100-file session cap (too_many_files), or their combined size would exceed 10GB (total_upload_size_exceeded).
- `410`: An unclaimed upload expired. Stage and upload it again before attaching it.
- `429`: Rate limit exceeded. More than 100 requests per minute were received from your IP address; further requests are blocked for 5 minutes.
- `500`: An unexpected error occurred. Retry reads with backoff; before retrying a write, check whether it took effect. See Error Handling for retry guidance.
- `504`: Session startup exceeded the 30-second deadline (timeout). Check the session list before retrying; do not assume a network timeout means no work was created.

## Changes

- **2026-10-20** `d75d82fcc944`: 1 info
  - the `query` request property's maxLength was increased from `2000` to `20000`
- **2026-10-19** `01e18335df05`: 2 info
  - added the new optional request property `projectId`
  - added the optional property `projectId` to the response with the `202` status
- **2026-10-16** `22847bf7e65d`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/elicitlabs/apis/elicit-labs-api/changes/sessions/agents/post.md)

---

[API](https://skmtc.dev/elicitlabs/apis/elicit-labs-api.md) - [All operations](https://skmtc.dev/elicitlabs/apis/elicit-labs-api/llms.txt) - [OpenAPI document](https://skmtc.dev/elicitlabs/apis/elicit-labs-api/revisions/cbbe29509d04?raw)
