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

# Mortem Ingest API: base URL, auth, and endpoints

> The Mortem Ingest API accepts trace batches, finalizes traces, and streams live events over SSE. Most teams use the SDK rather than calling it directly.

The Mortem Ingest API is the HTTP service that the `@mortemlabs/sdk` uses to deliver traces from your agent to Mortem's storage and analysis pipeline. You can call it directly if you need lower-level control, want to send traces from a language the SDK doesn't support, or are building your own instrumentation layer. For most TypeScript agents, the [SDK](/sdk/installation) handles everything described on this page automatically.

## Base URL

All Ingest API requests go to:

```
https://ingest.mortem.dev
```

For local development against a self-hosted stack, replace this with your local ingest address (default `http://localhost:4001`).

## Authentication

Pass your agent API key in the `Authorization` header on every request:

```
Authorization: Bearer <MORTEM_API_KEY>
```

The API key is shown once during agent onboarding in the dashboard. If you lose it, rotate the key from **Agent settings**. You can also pass the key in the `x-mortem-api-key` header if your HTTP client does not support the `Authorization` header.

<Warning>
  Your API key identifies the agent that owns every trace you send. Do not share it or commit it to source control. If a key leaks, rotate it immediately from the dashboard — old batches sent with the revoked key will be rejected.
</Warning>

## Endpoints

| Method | Path                      | Description                                                                  |
| ------ | ------------------------- | ---------------------------------------------------------------------------- |
| `GET`  | `/healthz`                | Health check. Returns `200 OK` with `{ "ok": true }` when the service is up. |
| `POST` | `/v1/traces/batch`        | Ingest a batch of trace and event data.                                      |
| `POST` | `/v1/traces/:id/complete` | Mark a trace as completed or errored and write its final fields.             |
| `GET`  | `/v1/agents/:id/live`     | Open a Server-Sent Events stream for real-time trace updates.                |

## Rate limiting

The API rate-limits requests per agent using a per-minute sliding bucket. When you exceed the limit, the API returns `429 Too Many Requests`. The SDK backs off and retries automatically; if you're calling the API directly, wait until the current minute window resets before retrying.

The rate limit is scoped to your `agentId`, not your IP address. Running multiple processes with the same agent key shares the same bucket.

## Error responses

The API returns standard HTTP error codes with a JSON body that contains an `error` field describing the problem.

| Status                     | Meaning                                                                    |
| -------------------------- | -------------------------------------------------------------------------- |
| `400 Bad Request`          | The request body failed schema validation.                                 |
| `401 Unauthorized`         | The API key is missing or does not match any agent.                        |
| `403 Forbidden`            | The authenticated identity does not have access to the requested resource. |
| `404 Not Found`            | The trace or agent ID in the path does not exist for this API key.         |
| `422 Unprocessable Entity` | The batch was parseable but contained logically invalid data.              |
| `429 Too Many Requests`    | The per-minute rate limit for this agent has been exceeded.                |

```json theme={null}
{ "error": "Rate limit exceeded" }
```

<Note>
  The SDK swallows ingest errors and routes them to your configured logger rather than throwing into agent code. If you are calling the API directly, implement your own retry logic for `429` and transient `5xx` responses.
</Note>
