Sendry Docs
API Reference

API Logs

Inspect every request made to the Sendry API for your organization — historical list + a real-time SSE stream.

Sendry persists one row in api_request_logs for every authenticated /v1/* request your organization makes, including method, path, status code, duration, user agent, and a scrubbed copy of the request / response bodies. The endpoints below let you list historical rows and subscribe to a real-time tail.

All endpoints require read_only scope.

Sensitive fields (key, secret, token, password, apiKey, api_key) and bulk content fields (html, text) are redacted in the persisted bodies. Recipient arrays (to, cc, bcc) are reduced to a count string. /v1/analytics/*, tracking endpoints, and the /v1/logs/* endpoints themselves are intentionally not logged.


List API request logs

GET /v1/logs/api-requests

Requires read_only scope.

Query parameters

ParameterTypeDefaultDescription
limitnumber50Results per page (1–100).
cursorstringOpaque cursor from a previous response's next_cursor.
methodstringFilter by HTTP method (GET, POST, PATCH, DELETE).
status_codenumberFilter by exact status code.
pathstringFilter by request path (substring match).
qstringCase-insensitive search across path and method.

Example request

curl -G https://api.sendry.online/v1/logs/api-requests \
  -H "Authorization: Bearer $SENDRY_API_KEY" \
  --data-urlencode "method=POST" \
  --data-urlencode "limit=50"

Response

{
  "data": [
    {
      "id": "log_abc123",
      "org_id": "org_xyz789",
      "api_key_id": "key_def456",
      "method": "POST",
      "path": "/v1/emails",
      "status_code": 200,
      "request_body": {
        "from": "noreply@example.com",
        "to": "[1 recipient]",
        "subject": "Welcome",
        "html": "[redacted]"
      },
      "response_body": { "id": "email_ghi789" },
      "duration_ms": 142,
      "user_agent": "sendry-sdk/0.4.1",
      "created_at": "2026-05-31T14:22:01.412Z"
    }
  ],
  "has_more": true,
  "next_cursor": "log_abc123",
  "total": 12483
}

Stream API request logs (Server-Sent Events)

GET /v1/logs/api-requests/stream

Requires read_only scope.

Opens a long-lived Server-Sent Events stream. On connect the server emits a single connected event, then one data: line per persisted API request for your organization, plus a :heartbeat comment every 15s to keep proxies and load balancers from idling out the connection.

For lightweight delivery the streamed payload omits request_body and response_body. To inspect a body, take the id from the stream and fetch the row via the list endpoint (or store it client-side and GET /v1/logs/api-requests with a cursor that includes it).

The stream is read-only and per-organization. Closing the underlying connection (browser tab close, network drop, HTTP timeout) tears down the Redis subscription server-side.

Example: curl

curl -N https://api.sendry.online/v1/logs/api-requests/stream \
  -H "Authorization: Bearer $SENDRY_API_KEY"
event: connected
data: {"ok":true}

data: {"id":"log_abc123","org_id":"org_xyz789","api_key_id":"key_def456","method":"POST","path":"/v1/emails","status_code":200,"duration_ms":142,"user_agent":"sendry-sdk/0.4.1","created_at":"2026-05-31T14:22:01.412Z"}

:heartbeat

data: {"id":"log_abc124","org_id":"org_xyz789","api_key_id":"key_def456","method":"GET","path":"/v1/domains","status_code":200,"duration_ms":11,"user_agent":"sendry-sdk/0.4.1","created_at":"2026-05-31T14:22:04.108Z"}

Example: browser EventSource

const es = new EventSource("/v1/logs/api-requests/stream", {
  withCredentials: true,
});

es.addEventListener("connected", () => {
  console.log("live");
});

es.onmessage = (e) => {
  const log = JSON.parse(e.data);
  console.log(log.method, log.path, log.status_code, `${log.duration_ms}ms`);
};

es.onerror = () => {
  // EventSource auto-reconnects; surface a UI indicator here if desired.
};

Streamed event shape

FieldTypeDescription
idstringLog row id (matches the row in the list).
org_idstringYour organization id.
api_key_idstring | nullThe key that signed the request (if any).
methodstringHTTP method.
pathstringRequest path.
status_codenumberResponse status.
duration_msnumber | nullServer-side request duration.
user_agentstring | nullRequest User-Agent header.
created_atstringISO 8601 timestamp.

Errors

StatusCodeWhen
401unauthorizedMissing or invalid API key
403forbiddenAPI key lacks read_only scope
422validation_errorInvalid query parameter

On this page