Audit log
Audit log
The Audit log is your organization's who‑did‑what trail. Every authenticated request that changes something — creating an agent, revoking an API key, allocating a number, editing billing — is recorded with who did it, against which endpoint, when, and what came back. It's the page you (or your auditors) open during a SOC 2 / ISO review, or when you need to answer "who turned this off?"
Everything here is self‑serve from the dashboard — no help from Telenow is needed.
Where to find it
Open Audit log in the sidebar, under the Admin section (next to Workplace).
Owner / admin only. The link only appears for members with the manage_org permission — that's the owner and admin roles. A developer, viewer, or plain member who navigates to the page directly sees "You need owner or admin role to view the audit log." and a link back to the dashboard. There's nothing to enable — the log records continuously in the background for every org.
What gets recorded
A row is written for every mutating HTTP request anywhere under /api — POST, PUT, PATCH, and DELETE. Read‑only traffic (GET, HEAD, OPTIONS) is not logged, so a quiet org that only reads data will have few rows. This keeps the trail focused on changes that actually matter for compliance.
Each row captures the request envelope — not the business action behind it:
| Column (UI) | Field | What it tells you |
|---|---|---|
| Timestamp | created_at | When the request happened (shown in your local time; stored as UTC). |
| Actor | actor_user_email / actor_api_key | Who made the call — a person's email, or an API key id. |
| Method | method | The HTTP verb (POST / PUT / PATCH / DELETE). |
| Path | path | The endpoint that was hit, e.g. /api/orgs/{orgId}/api-keys. |
| Status | status_code | The response code the caller received (2xx success, 4xx rejected, 5xx error). |
| Latency | latency_ms | How long the server took to handle it, in milliseconds. |
| IP | ip | The client's IP address (honors the X-Forwarded-For header, so it's the real caller behind a proxy). |
The row also stores the request's User‑Agent (shown in the CSV export) and the acting user's internal id.
Your request bodies are never stored. Telenow computes a SHA‑256 hash of the body internally so a security review can prove "the same payload was sent" — but the actual contents (which may contain PII) are never retained. There's no way to read back what was in a request from the audit log, only that it was made.
How the actor is attributed
Who shows up in the Actor column depends on how the request authenticated:
- A person (dashboard / JWT): their email is shown.
- An API key: the row is attributed to the API key's id rather than an email. Match it against your keys on the Developers page to see which key it was.
- Unauthenticated: all actor fields are blank (shown as
—). The request is still logged with its status — handy for spotting rejected or forbidden attempts.
Filtering the log
The filter bar at the top of the page narrows the table. All filters combine (AND) and refresh the list as you type or change them — there's no "Apply" button.
| Filter | What it does |
|---|---|
| Method | Pick one of All, GET, POST, PUT, PATCH, DELETE. |
| Path contains | A prefix match on the endpoint — e.g. typing /api/orgs shows everything under that path, or /api/orgs/{orgId}/api-keys shows just API‑key changes. |
| Since | Only show entries at or after this date/time (inclusive). |
| Until | Only show entries strictly before this date/time. |
Results are shown newest first, 50 per page. Use the ‹ › arrows in the footer to page through; the footer tells you which rows you're viewing out of the total match count.
A note on the Method = GET filter.
GETappears in the dropdown for completeness, but because read‑only requests aren't logged, filtering byGETalways returns an empty list. To find changes, leave it on All or pick a mutating verb.
Reading the status badge
The Status column is colour‑coded so problems jump out:
- Green —
2xx, the request succeeded. - Amber —
4xx, the request was rejected (bad input, missing permission, etc.). - Red —
5xx, a server error.
Pulling a date range and scanning for amber/red badges is the quickest way to find failed or forbidden attempts.
Export to CSV
Click Export CSV in the top‑right to download the filtered trail as a CSV file (named audit-YYYY-MM-DD.csv). The export applies the same filters that are currently set in the bar, so narrow the view first if you only want a slice. Compliance teams ask for this in nearly every SOC 2 / ISO review.
The export is server‑capped at 50,000 rows. If you have more activity than that in your selected window, narrow the Since / Until dates and export in batches.
The CSV has 9 columns, in this order:
| # | Column | Notes |
|---|---|---|
| 1 | at | Timestamp (RFC 3339) |
| 2 | method | HTTP method |
| 3 | path | Request path |
| 4 | status | HTTP status code |
| 5 | latency_ms | Latency in milliseconds |
| 6 | actor_email | Acting user's email, or empty for key/anonymous calls |
| 7 | actor_api_key | Acting API key id, or empty |
| 8 | ip | Client IP, or empty |
| 9 | user_agent | Request User-Agent, or empty |
The CSV intentionally does not include the internal metadata field — only the nine fixed columns above. For long‑term retention beyond what the dashboard shows, export on a schedule and load the files into your own log store or SIEM.
Common questions the log answers
Because every change keys on the request path, a path filter plus the Method tells you the action:
- "Who created or revoked API keys?" — filter Path contains
/api/orgs/{orgId}/api-keys.POSTrows are creations,DELETErows are revocations. - "Who changed a teammate's role or removed a member?" — filter on the members path (see Team & workplace). Member, role, and access changes are recorded here.
- "Were there any rejected attempts last night?" — set Since/Until to the window and scan for amber (
4xx) and red (5xx) status badges. - "What did this API key do?" — pull a date range and look down the Actor column for the key's id.
API access
The same data is available over the dashboard API for programmatic pulls into your own systems — same filters, the same paginated list endpoint (50 rows per page by default — pass limit/offset to page through), and the 50,000‑row CSV export. See the Audit log API for the full endpoint reference, field names, and curl examples.
In short:
GET /api/orgs/{orgId}/audit # paginated JSON, newest first
GET /api/orgs/{orgId}/audit/export # filtered CSV (9 columns)
Both require a user JWT plus X-Org-Id and the owner/admin role, and the path {orgId} must match your X-Org-Id header (a mismatch returns 403).
Tips
- Reserve the log for proof, not monitoring. It records what was changed (the endpoint and result), not a friendly description. Pair it with Webhooks if you want real‑time notifications of specific events.
- Filter by path before exporting. A focused CSV (e.g. just API‑key or member changes) is far easier to hand to an auditor than a dump of everything.
- Watch the actor column for shared API keys. If many changes come from one key id, consider issuing separate keys per integration so the trail stays attributable.
Troubleshooting
- "You need owner or admin role to view the audit log." — The page is gated by manage_org. Ask an owner to raise your base role, or have them pull the trail for you.
- The list is empty. — Only mutating requests are logged, so an org with read‑only traffic has nothing to show. Also check your Method isn't stuck on
GET(which never matches) and that your date filters aren't too narrow. - The CSV looks truncated. — Exports are capped at 50,000 rows. Narrow the Since/Until window and export in batches.
403from the API. — Either your role isn't owner/admin, or yourX-Org-Idheader doesn't match the{orgId}in the path.
See also the Audit log API, Team & workplace, Compliance, and Data protection, GDPR & DPA.