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

# Create a Research Agent session

`POST /sessions/agents`

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`.

This endpoint is in early access. It returns `404 not_found` unless the Research Agent API has been enabled for the authenticated account or organization.

### 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. **(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.
- `unknown` — status could not be determined (legacy sessions only).

All errors return the standard `{ "error": { "code", "message" } }` envelope.

### 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?"}'

# 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. Attached files are made available to the research agent exactly as uploads made in the web interface are.
    - `file_id` string, uuid, required — The file_id returned by POST /api/v2/files for a previously uploaded file.

## 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 and continue the session in the Elicit web interface.

## Other responses

- `400` — Invalid request. `query` must contain 1–2,000 characters.
- `401` — Authentication failed. The API key is missing, invalid, revoked, or expired.
- `402` — Insufficient quota.
- `403` — API access is not available on your current plan. Upgrade to Pro or above to use the API.
- `404` — Research Agent API early access is not enabled for this account.
- `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 after a short delay.

---

[API](https://skmtc.dev/elicit/apis/elicit-api.md) · [All operations](https://skmtc.dev/elicit/apis/elicit-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/elicit/elicit-api/revisions/2b42624536e5/schema)
