# Export audit logs

import { Steps } from "@astrojs/starlight/components"

The **audit logs** Platform API returns a paginated, filterable history of actions in your Mindflow organization—flows,
deployments, credentials, permissions, and more. Org Admins copy the organization **API Key** from Studio, then call
`GET /v1/audit-logs` with that Bearer token. There is no export download button in Studio; use the API (or your SIEM
connector) to pull logs before they expire.

## When to use

- You need a machine-readable export for compliance, forensics, or a SIEM.
- You want to filter by category, time range, or selected fields.
- Prefer Studio run history and designer changelog when you only need interactive debugging inside one flow.

Before you begin, you need **Org Admin** rights to view the organization API key. Treat the key as an administrative
secret—it can perform organization-level API actions, including log export.

## Guide

### Copy the organization API key

The **API Key** section on the Organization page authenticates organization-level Mindflow API requests.

<ol>
<li>

**Open Organization.** In Studio, open your profile menu, then choose **Organization**.

</li>
<li>

**Open API Key.** Scroll to **API Key** and copy the key for use as a Bearer token. Store it in your secret manager—do
not commit it to source control.
<div class="docs-screenshot-compact">

![Organization API Key section for authenticating Platform API requests](./assets/organization-api-key.png)

</div>

</li>
</ol>
### Call GET /audit-logs

Base URL: `https://api-{tenant}.mindflow.io/v1` (replace `{tenant}` with your tenant slug). Some environments use a
different root domain—use the API host Mindflow gave you.

| Method | Path          | Purpose                                      |
| ------ | ------------- | -------------------------------------------- |
| GET    | `/audit-logs` | Paginated, filterable list of audit entries. |

Every request needs:

```text title="Authorization header"
Authorization: Bearer YOUR_ORGANIZATION_API_KEY
```

Requests without a valid token receive **401**.

<ol>
<li>

**List recent logs.** Call the endpoint with your key:

```bash title="Basic list"
curl -X GET "https://api-acme-corp.mindflow.io/v1/audit-logs" \
  -H "Authorization: Bearer $API_KEY"
```

</li>
<li>

**Filter by category (optional).** Pass `category` when you only need one area:

```bash title="Filter by category"
curl -X GET "https://api-acme-corp.mindflow.io/v1/audit-logs?category=flow" \
  -H "Authorization: Bearer $API_KEY"
```

</li>
<li>

**Select fields and a time window (optional).** Use `fields` (max 6), `after` or `before` (ISO 8601), and `limit`
(required with `before` / `after`):

```bash title="Fields and date window"
curl -X GET \
  "https://api-acme-corp.mindflow.io/v1/audit-logs?fields=auditLogId,category,timestamp&after=2024-03-19T00:00:00Z&limit=50" \
  -H "Authorization: Bearer $API_KEY"
```

</li>
</ol>
### Filter and paginate

| Parameter  | Type                      | Description                                                     |
| ---------- | ------------------------- | --------------------------------------------------------------- |
| `category` | enum                      | Filter by category. Omit for all.                               |
| `fields`   | string[]                  | Subset of fields (max 6).                                       |
| `limit`    | int (1–1000, default 100) | Page size. **Required** with `before` or `after`.               |
| `cursor`   | string (Base64)           | Opaque page cursor. **Cannot** combine with `before` / `after`. |
| `before`   | ISO 8601                  | Events before this time (exclusive). Requires `limit`.          |
| `after`    | ISO 8601                  | Events after this time (exclusive). Requires `limit`.           |

Allowed `fields` values: `auditLogId`, `category`, `type`, `timestamp`, `expiresAt`, `metadata`.

**Categories:** `flow`, `flow-deployment`, `credential`, `environment`, `permission`, `mcp`, `team`, `organization`.

Pagination strategies:

| Strategy             | How                                                                                       | When to use             |
| -------------------- | ----------------------------------------------------------------------------------------- | ----------------------- |
| Date window + cursor | Pass `before` or `after` with `limit`; follow `pagination.nextCursor` in the same window. | Time-bounded export     |
| Pure cursor          | Pass `limit` and the previous `nextCursor`.                                               | Stream the full history |

Results sort by `timestamp` (newest first). Max page size is **1000**. If no logs match for a continuous **72 hours**,
the API can return an empty page—keep paginating or widen the window.

:::note
Do not send `cursor` together with `before` or `after`.
:::

### Read the response

```json title="Response shape"
{
  "auditLogs": [
    {
      "auditLogId": "AUDI-57b858ed-ec60-4507-b2ef-ea58244ac742",
      "category": "flow",
      "type": "step_update",
      "timestamp": "2024-03-20T15:30:45.123Z",
      "createdAt": "2025-03-13T15:24:22.092Z",
      "expiresAt": "2025-03-27T15:24:23.379Z",
      "metadata": {}
    }
  ],
  "pagination": {
    "nextCursor": "eyJsYXN0S2V5IjoiMTIzNCJ9"
  }
}
```

| Field        | Notes                                     |
| ------------ | ----------------------------------------- |
| `auditLogId` | `AUDI-{UUIDv4}`                           |
| `category`   | See categories above                      |
| `type`       | Snake_case event name for that category   |
| `timestamp`  | When the action occurred                  |
| `createdAt`  | When the log record was written           |
| `expiresAt`  | Retention / automatic deletion time       |
| `metadata`   | Context (user, IP, flow ids, and similar) |

<details>
<summary>Event types by category</summary>

#### `flow-deployment`

| Event type           | Description                        |
| -------------------- | ---------------------------------- |
| `deploy_queued`      | Flow deployment deploy queued      |
| `deploy_started`     | Flow deployment deploy started     |
| `deploy_completed`   | Flow deployment deploy completed   |
| `deploy_failed`      | Flow deployment deploy failed      |
| `run_queued`         | Flow deployment run queued         |
| `run_started`        | Flow deployment run started        |
| `run_completed`      | Flow deployment run completed      |
| `run_failed`         | Flow deployment run failed         |
| `step_run_queued`    | Flow deployment step run queued    |
| `step_run_started`   | Flow deployment step run started   |
| `step_run_completed` | Flow deployment step run completed |
| `step_run_failed`    | Flow deployment step run failed    |

#### `flow`

| Event type                     | Description                              |
| ------------------------------ | ---------------------------------------- |
| `step_create`                  | Creation of a new step in a flow         |
| `step_update`                  | Update to an existing step in a flow     |
| `step_delete`                  | Deletion of a step from a flow           |
| `link_create`                  | Creation of a new link between steps     |
| `link_update`                  | Update to an existing link between steps |
| `link_delete`                  | Deletion of a link between steps         |
| `flow_create`                  | Creation of a new flow                   |
| `flow_update`                  | Update to an existing flow               |
| `flow_delete`                  | Deletion of a flow                       |
| `flow_move`                    | Moving a flow between environments       |
| `flow_duplicate`               | Duplicating a flow                       |
| `import_export`                | Importing entities into the system       |
| `ai_generate_flow_description` | AI generation of a playbook description  |
| `ai_generate_flow`             | AI generation of a flow                  |
| `revert`                       | Reverting a changelog action             |

#### `permission`, `credential`, `environment`, `team`, `organization`

Shared lifecycle types: `create_completed`, `create_failed`, `update_completed`, `update_failed`, `delete_completed`,
`delete_failed`. Credentials also include `update_value_completed`, `update_value_failed`, `get_completed`, and
`get_failed`.

#### `mcp`

| Event type             | Description                                 |
| ---------------------- | ------------------------------------------- |
| `invocation_completed` | MCP JSON-RPC request completed successfully |
| `invocation_failed`    | MCP JSON-RPC request failed                 |

</details>

### Handle errors and rate limits

| Status | When                                             |
| ------ | ------------------------------------------------ |
| 400    | Invalid parameters (for example cursor + before) |
| 401    | Missing or incorrect Bearer token                |
| 429    | Rate limit; honor `Retry-After`                  |
| 500    | Unexpected server error—retry later              |

Rate-limit response headers can include `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, and
`Retry-After`. Use backoff or a queue when you stream large exports.

## Example

A compliance engineer copies the organization API key, then exports one day of `flow` events into object storage:

1. **Copy the API key** from Organization → API Key into a secret store.
2. **Page with `after` and `limit`.** Start at midnight UTC; follow `nextCursor` until it is null.
3. **Write each page** to durable storage before the entries hit `expiresAt`.

## Keep in mind

- Pull data before `expiresAt` if you need long-term retention outside Mindflow.
- Prefer small date chunks and `fields=` when you only need ids and timestamps.
- Audit metadata can include personal or sensitive data—protect the token and the export files.

Related: [Monitor quotas](../quotas-admin-only/), [Manage permissions (RBAC)](../../manage-access/manage-permissions-rbac/).
