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

# Quickstart

> Create an agent and session, send a message, and stream events with the Herm REST API.

The Herm API is a RESTful API at `https://api.herm.run`. This quickstart uses
`curl`; no SDK is required.

## Prerequisites

* A Herm workspace. [Open Herm](https://herm.run/app), sign in, and create or
  select a workspace.
* An API key. Open [Settings → API keys](https://herm.run/app/settings/api-keys),
  create a key, and copy it when it is shown.
* `curl`

Set your key in the shell:

Herm is a Prism product, so examples use the `PRISM_API_KEY` environment
variable. Requests authenticate with the `x-api-key` header.

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
export PRISM_API_KEY="your-api-key-here"
```

Every request must include `x-api-key: $PRISM_API_KEY`. Requests with a body
must also include `Content-Type: application/json`.

<Steps>
  <Step title="Create an agent">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl -X POST "https://api.herm.run/v1/agents" \
      -H "Content-Type: application/json" \
      -H "x-api-key: $PRISM_API_KEY" \
      -d '{
        "name": "Quickstart Agent",
        "modelName": "anthropic/claude-sonnet-4.5",
        "systemPrompt": "You are a helpful product research agent.",
        "skills": [],
        "tools": []
      }'
    ```

    The response contains the agent `id` and its initial immutable version. Save the
    `id` for the next request.
  </Step>

  <Step title="Create a session">
    Create a session using a stable `subjectId` from your application:

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl -X POST "https://api.herm.run/v1/sessions" \
      -H "Content-Type: application/json" \
      -H "x-api-key: $PRISM_API_KEY" \
      -d '{
        "agentId": "agent_123",
        "subjectId": "user_123",
        "title": "First research task"
      }'
    ```

    Reuse the same `subjectId` for the same user or organization. A session records
    the latest agent version when it is created.
  </Step>

  <Step title="Open the event stream">
    In another terminal, open the session's Server-Sent Events stream before sending
    the message:

    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl -N "https://api.herm.run/v1/sessions/session_123/events/stream" \
      -H "x-api-key: $PRISM_API_KEY"
    ```

    Each frame has an SSE `event` name and a JSON event envelope in `data`. Assistant
    text arrives as `agent.message`; turn lifecycle events are
    `session.status_running` and `session.status_idle`.
  </Step>

  <Step title="Send a message">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    curl -X POST "https://api.herm.run/v1/sessions/session_123/events" \
      -H "Content-Type: application/json" \
      -H "x-api-key: $PRISM_API_KEY" \
      -d '{
        "events": [
          {
            "type": "user.message",
            "content": [
              { "type": "text", "text": "Summarize the three most important trends in developer tooling." }
            ]
          }
        ]
      }'
    ```

    The endpoint returns `202 Accepted` with the accepted inbound event. Responses
    arrive on the stream; there is no separate run resource.
  </Step>

  <Step title="Read the response">
    The stream emits frames like:

    ```text theme={"theme":{"light":"github-light","dark":"github-dark"}}
    event: session.status_running
    data: {"type":"session.status_running","payload":{"type":"session.status_running"},...}

    event: agent.message
    data: {"type":"agent.message","payload":{"type":"agent.message","delta":true,"content":[{"type":"text","text":"The first trend"}]},...}

    event: session.status_idle
    data: {"type":"session.status_idle","payload":{"type":"session.status_idle","stop_reason":{"type":"end_turn"}},...}
    ```

    For `agent.message`, render text from `payload.content`. A `delta: true` payload
    is a streaming chunk; durable completed messages use `delta: false`.
  </Step>
</Steps>

## Next steps

<CardGroup cols={2}>
  <Card title="Agents" icon="bot" href="/api-reference/agents">
    Configure models, skills, MCP servers, and tools.
  </Card>

  <Card title="Sessions" icon="messages-square" href="/api-reference/sessions">
    Manage session identity and lifecycle.
  </Card>

  <Card title="Stream events" icon="zap" href="/api-reference/stream-events">
    Handle events, required actions, and reconnection.
  </Card>

  <Card title="Long-running tools" icon="clock" href="/api-reference/long-running-tools">
    Complete application-owned work asynchronously.
  </Card>
</CardGroup>
