---
title: "List audit logs"
method: GET
path: "/v1/logs"
tags: ["Logs"]
---

# List audit logs

`GET /v1/logs`

## Request

- Base URL: `https://api.mails.ai`
- URL: `https://api.mails.ai/v1/logs`
- Auth: HTTP bearer

**Requires scope:** `read`. Read-only audit trail of state-changing operations, and of requests the API refused with a 4xx once it knew the workspace (category `api`, action `request.refused`). A refusal before that, such as a missing or unknown key, is not recorded. The same refusal again (the same key, method, path and code) is recorded at most once a minute, a 429 once a minute per code, and a workspace records at most 30 refusals a minute.

## Query parameters

- `limit` integer
- `cursor` string
- `category` string
- `action` string

## Response `200`

A page of audit log entries.

- object
  - `data` object[], required: The items on this page, at most `limit` of them.
    - `id` string, required: Entry id (`aud_…`). Ids sort by time, and the list is newest first.
    - `category` string, required: The area the entry is filed under: `auth`, `agent`, `domain`, `api_key`, `suppression`, `billing`, `abuse`, `security`, `lifecycle`, `admin` or `api`. `agent` also holds message, draft, thread, label and webhook actions; `api` holds requests the API refused.
    - `action` string, required: What happened, such as `agent.created`, `api_key.revoked`, `draft.sent`, `subscription.past_due` or `request.refused`.
    - `target_resource_id` string: Id of what the action applied to, such as an agent, API key, draft, label or webhook. Absent when the action has no single target.
    - `metadata` object: Extra detail recorded with the action; its keys depend on `action`. Absent when none was recorded. A `request.refused` entry holds `method`, `path` (without the query string), `status`, `code`, `request_id`, `key_id`, `mode` and, for a key tied to an agent, `agent_id`: never the request's body or anything from a message.
    - `ip_address` string: IP address the request came from. Absent on entries written without a request, such as scheduled jobs and billing events from Stripe. Left out when an app connected by sign-in reads the log; the mails CLI gets it.
    - `user_agent` string: The request's `User-Agent` header. Absent when the request sent none, and on entries written without a request. Left out for an app connected by sign-in, as ip_address is.
    - `created_at` string, date-time, required: When the entry was recorded (UTC).
  - `has_more` boolean, required: True when more items follow this page: pass `next_cursor` as `cursor` to get them.
  - `next_cursor` string: Pass as `cursor` to fetch the next page. Absent on the last page.

## Other responses

- `400`: Invalid request — malformed JSON or a field failed validation. Also `feature_not_enabled` when this server has a feature switched off (custom domains before they are available).
- `401`: Missing or invalid API key.
- `403`: The API key lacks the required scope (`insufficient_scope`), or the token belongs to an app connected by sign-in and this operation is closed to connected apps (`connected_app_not_allowed`).
- `500`: Internal server error.

---

[API](https://skmtc.dev/mails/apis/mails-ai-api.md) · [All operations](https://skmtc.dev/mails/apis/mails-ai-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mails/apis/mails-ai-api/revisions/4d4930a8c33b?raw)
