List logs
GET /v1/logs · permission logs:read
Lists the environment's log records (sign-ins, sessions, tokens, MFA, attack protection and more) with cursor pagination, newest first. Records older than your plan's retention window (Free 7, Startup 14, Business 30, Enterprise 90 days) are never returned.
Request
| Parameter | In | Required | Description |
|---|---|---|---|
limit |
query | no | Page size, 1 to 100. Default 20. |
after |
query | no | Opaque cursor from list_metadata.after (older records). Exclusive with before. |
before |
query | no | Opaque cursor from list_metadata.before (newer records). Exclusive with after. |
from |
query | no | RFC 3339 time; records at or after it. Must be inside the retention window. |
to |
query | no | RFC 3339 time; records before it. Must be later than from. |
type |
query | no | Log type prefix such as authentication. or session.created. Repeat the parameter for up to 20 values; a record that matches any of them is returned. |
outcome |
query | no | success, failure, denied or error. |
user_id, org_id, application_id, connection_id, directory_id, session_id |
query | no | Exact match on the prefixed id (usr_, org_, app_, conn_, dir_, ses_). |
request_id |
query | no | Idp-Request-Id of a request (UUID), for example the id shown on a hosted sign-in error page. |
correlation_id |
query | no | Idp-Correlation-Id of a workflow (UUID). |
ip |
query | no | IP address or CIDR block (203.0.113.0/24). Requires audit-events:read_ip. |
ip_country |
query | no | Country of the IP, ISO 3166-1 alpha-2 in upper case (DE). |
q |
query | no | Prefix of the masked identifier hint (j***@). Requires users:read_pii. |
Records are always ordered by occurred_at, newest first; there is no order parameter (order=desc is accepted, any other value fails with validation_failed). A cursor is only valid with the filters it was issued for.
The ip and q filters need their permission even though they only narrow the result: without it the request fails with 403 insufficient_permissions before any search, so a key cannot probe values it is not allowed to read.
Response
200 OK. data holds the records on the page; list_metadata.after points to older records and list_metadata.before to newer ones (null when there are none). No total count is returned. Empty fields are null.
ip, ip_asn, user_agent and user_agent_family are present only when the key has the audit-events:read_ip permission, and identifier_hint only when it has users:read_pii. Without the permission the field is left out entirely (no masked value). ip_country is always returned.
{
"data": [
{
"id": "evt_01j9xk3m7q8r2s4t6v8w0y2z4a",
"occurred_at": "2026-10-01T08:15:42.120Z",
"type": "authentication.password.failed",
"outcome": "failure",
"reason_code": "invalid_credentials",
"user_id": "usr_0a1b2c3d4e5f6g7h8j9k0m1n2p",
"org_id": null,
"application_id": "app_01j9xk3m7q8r2s4t6v8w0y2z4b",
"connection_id": "conn_01j9xk3m7q8r2s4t6v8w0y2z4c",
"directory_id": null,
"session_id": null,
"identifier_hint": "a***@e***.com",
"ip": "203.0.113.7",
"ip_country": "DE",
"ip_asn": 64500,
"user_agent": "Mozilla/5.0 (X11; Linux x86_64)",
"user_agent_family": "Firefox",
"risk": null,
"auth_context": null,
"act_chain": null,
"details": {"attempt": 3},
"request_id": "0192a6c1-7d3e-7a10-9b2c-3d4e5f607182",
"correlation_id": null,
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}
],
"list_metadata": {
"before": null,
"after": "<opaque cursor>"
}
}
Errors
Every error is an application/problem+json body with a stable code.
| HTTP | code |
When |
|---|---|---|
| 400 | invalid_cursor |
The cursor is malformed or was not issued for this request. |
| 400 | invalid_filter |
The log service rejected a filter or the cursor. |
| 400 | range_outside_retention |
from is earlier than the retention window of your plan. |
| 422 | validation_failed |
A query parameter is invalid (limit out of range, bad timestamp, to not after from, more than 20 type values, malformed id or IP, repeated parameter). |
| 401 | unauthenticated |
The API key is missing, invalid or revoked. |
| 403 | insufficient_permissions |
The key lacks logs:read, or uses ip without audit-events:read_ip or q without users:read_pii (required_permissions lists what the request needs). |
| 429 | rate_limited |
The rate limit was exceeded; honor Retry-After. |
| 503 | service_unavailable |
A dependency is temporarily unavailable; retry later. |
Example
curl "https://api.eu.keenauth.com/v1/logs?type=authentication.&outcome=failure&from=2026-10-01T00:00:00Z" \
-H "Authorization: Bearer $KEENAUTH_SECRET_KEY"
Personal data
This endpoint carries personal data: environment logs. Personal data in the KeenAuth APIs describes what is stored, how long it is kept and how it is deleted. Do not send special categories of personal data (health, biometric data, religion, political opinions, sexual orientation) in any field.