Skip to main content
import { createClient } from "@mailsai/sdk";

const client = createClient(); // reads MAILS_API_KEY

const result = await client.logs.list({ limit: 10 });
console.log(result);
{
  "data": [
    {
      "id": "aud_01JZX8K3M9Q4P7VN2YB6RTDC0E",
      "category": "<category>",
      "action": "<action>",
      "target_resource_id": "<target_resource_id>",
      "metadata": {},
      "ip_address": "<ip_address>",
      "user_agent": "<user_agent>",
      "created_at": "2026-10-04T12:00:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": "<next_cursor>"
}

List audit logs

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).
GET/v1/logsscope · read
import { createClient } from "@mailsai/sdk";

const client = createClient(); // reads MAILS_API_KEY

const result = await client.logs.list({ limit: 10 });
console.log(result);
{
  "data": [
    {
      "id": "aud_01JZX8K3M9Q4P7VN2YB6RTDC0E",
      "category": "<category>",
      "action": "<action>",
      "target_resource_id": "<target_resource_id>",
      "metadata": {},
      "ip_address": "<ip_address>",
      "user_agent": "<user_agent>",
      "created_at": "2026-10-04T12:00:00.000Z"
    }
  ],
  "has_more": false,
  "next_cursor": "<next_cursor>"
}

Query Parameters

limitinteger

Page size (1–100).

Default: 25

cursorstring

Opaque cursor from a previous page's next_cursor.

categorystring

Filter by audit category.

actionstring

Filter by audit action.

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.

Response

dataobject[]

The items on this page, at most limit of them.

Show propertiesHide properties
idstring

Entry id (aud_…). Ids sort by time, and the list is newest first.

categorystring

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.

actionstring

What happened, such as agent.created, api_key.revoked, draft.sent, subscription.past_due or request.refused.

target_resource_idstring

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.

metadataobject

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_addressstring

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_agentstring

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_atstring

When the entry was recorded (UTC).

has_moreboolean

True when more items follow this page: pass next_cursor as cursor to get them.

next_cursorstring

Pass as cursor to fetch the next page. Absent on the last page.

Was this page helpful?