Client Logging
The /api/_log endpoint lets browser apps and external clients ship log events back to the server, where they're persisted alongside the API's own event log.
Use sparingly
This is a lightweight logging endpoint, not a full telemetry or observability platform. It has no sampling, no rate limiting, and no structured properties. Reach for it when you want a quick way to see client-side errors and warnings server-side — not for analytics, user behaviour tracking, or verbose debug traces.
Endpoint
POST /api/_log
| Requirement | Value |
|---|---|
| Auth | Required — Bearer token or access cookie. Anonymous calls are rejected with 401. |
| Body | application/json — array of event objects |
| Response | 200 OK on success, 400 Bad Request on malformed JSON |
Request Body
Send a JSON array of events, even if you only have one:
POST /api/_log
Content-Type: application/json
Authorization: Bearer <access-token>
[
{
"severity": 1,
"message": "Uncaught TypeError: cannot read 'id' of undefined"
}
]
Fields
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | The log text. |
severity | int | No | Log level. Defaults to 3 (Info). See table below. |
Severity Levels
| Value | Level |
|---|---|
0 | Fatal |
1 | Error |
2 | Warning |
3 | Info (default) |
4 | Debug |
5 | Trace |
The authenticated user is attached to each event automatically from the request token.
Example: Browser Error Reporter
window.addEventListener("error", (e) => {
fetch("/api/_log", {
method: "POST",
credentials: "include",
headers: { "Content-Type": "application/json" },
body: JSON.stringify([
{
severity: 1,
message: `${e.message} @ ${e.filename}:${e.lineno}`,
},
]),
});
});
Notes
- The endpoint accepts a batch — buffer events on the client and flush periodically to reduce request volume.
- Sample or filter noisy events client-side. Treat each call as something a human will read.