> ## Documentation Index
> Fetch the complete documentation index at: https://logixlysia-claude-elysia-v2-open-beta-i2faib.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Axiom

> Ship logs to an Axiom dataset via the ingest API

Send logs to [Axiom](https://axiom.co). Axiom indexes every field of an event without a schema, so the nested structure Logixlysia sends — `request.method`, `context.requestId`, your custom context — is queryable as-is with APL.

## Setup

1. Create a dataset in the [Axiom console](https://app.axiom.co).
2. Generate an API token with **ingest** permission for that dataset.
3. Set the environment variables:

```bash theme={null}
AXIOM_API_KEY=xaat-your-token
AXIOM_DATASET=your-dataset
```

4. Wire the transport:

```ts theme={null}
import { Elysia } from 'elysia'
import logixlysia from 'logixlysia'
import { createAxiomTransport } from 'logixlysia/axiom'

const app = new Elysia()
  .use(
    logixlysia({
      config: {
        transports: [createAxiomTransport()]
      }
    })
  )
  .get('/', () => 'ok')
  .listen(3000)
```

5. Trigger a request and query the dataset in Axiom.

## Environment Variables

| Variable        | Required                   | Description                                   |
| --------------- | -------------------------- | --------------------------------------------- |
| `AXIOM_API_KEY` | Yes                        | API token with ingest permission (`xaat-…`)   |
| `AXIOM_DATASET` | Yes                        | Target dataset name                           |
| `AXIOM_ORG_ID`  | For personal access tokens | Organization ID                               |
| `AXIOM_URL`     | No                         | API base URL (default `https://api.axiom.co`) |

## Options

Options passed to `createAxiomTransport()` override environment variables:

```ts theme={null}
const axiom = createAxiomTransport({
  dataset: 'production-logs',
  timeout: 10_000
})
```

| Option    | Type     | Default                | Description                                 |
| --------- | -------- | ---------------------- | ------------------------------------------- |
| `apiKey`  | `string` | `AXIOM_API_KEY`        | API token with ingest permission            |
| `dataset` | `string` | `AXIOM_DATASET`        | Target dataset name                         |
| `orgId`   | `string` | `AXIOM_ORG_ID`         | Required when using a personal access token |
| `baseUrl` | `string` | `https://api.axiom.co` | API base URL                                |

Plus the shared batching options: `maxBatchSize`, `flushIntervalMs`, `timeout`, `retries` — see the [overview](/docs/adapters/overview#shared-behavior).

## Payload

Each log becomes one event in `POST /v1/datasets/{dataset}/ingest`:

```json theme={null}
{
  "_time": "2026-08-22T12:00:00.000Z",
  "level": "INFO",
  "message": "",
  "request": { "method": "GET", "url": "http://localhost:3000/users" },
  "status": 200,
  "durationMs": 12.4,
  "context": { "requestId": "0d5e…" }
}
```

Query it in Axiom with APL, e.g. `['your-dataset'] | where level == "ERROR" and durationMs > 1000`.

## Troubleshooting

* **`401`** — the token is invalid or expired; generate a new one in Axiom settings.
* **`403` with a personal access token** — set `AXIOM_ORG_ID` (personal tokens are not scoped to an organization).
* **Nothing arrives** — logs flush in batches (2 s by default); check that the process lived long enough, or call `flush()` before exit.
