Logs

Send log entries without the SDK, one at a time or in batches of up to 100.

Use these when the SDK doesn’t fit, for example from another language or a log shipper. Authentication and errors are described in the API overview.

Send a batch

POST
/api/v1/{projectId}/logs/batch

X-API-Key required. What the SDK uses.

Terminal
curl -X POST "https://apperioserver.onrender.com/api/v1/your-project-id/logs/batch" \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d @logs.json
logs.json
{
  "logs": [
    {
      "level": "info",
      "message": "Order placed",
      "timestamp": "2026-01-15T12:00:00.000Z",
      "service": "billing",
      "environment": "production",
      "release": "2.4.1",
      "data": { "orderId": "order-123" }
    },
    {
      "level": "error",
      "message": "Payment failed",
      "service": "billing",
      "environment": "production",
      "error": {
        "name": "CardError",
        "message": "Card declined",
        "stack": "CardError: Card declined\n    at charge (billing/charge.py:42)"
      }
    }
  ]
}

Entry fields

FieldTypeNotes
levelstring, requiredtrace, debug, info, warn, error or fatal
messagestring, required1 to 5,000 characters
timestampstringISO 8601 in UTC ending in Z, such as 2026-01-15T12:00:00.000Z. Offsets like +01:00 are rejected. Defaults to the time Apperio receives it.
dataobjectAnything you want stored with the entry
errorobjectname (up to 200), message (up to 1,000), and optional stack (up to 10,000), url, lineNumber, columnNumber
servicestringUp to 100 characters
environmentstringUp to 50 characters
releasestringUp to 100 characters
contextobjectShared details, such as a user ID
metadataany
eventTypestringerror, performance, interaction, network, console, pageview, web-vital, breadcrumb, message or system
sessionIdstringUp to 100 characters. Groups entries into a session.
traceId, spanId, correlationIdstringUp to 100 characters each
url, referrerstringUp to 2,000 characters each
userAgentstringUp to 500 characters

Fields not in this list are dropped.

Limits

  • 1 to 100 entries per request.
  • The whole request is rejected with 400 if any entry breaks a rule above. Fix the entry and send the batch again.
  • Request bodies can be up to 5 MB.

Response

201, with a result for each entry, in order:

JSON
{
  "status": "success",
  "message": "Batch processing complete: 2 succeeded, 0 failed",
  "data": {
    "success": 2,
    "failed": 0,
    "results": [
      { "index": 0, "success": true, "logId": "log-id-1" },
      { "index": 1, "success": true, "logId": "log-id-2" }
    ]
  }
}

An entry that passes validation but can’t be stored is reported with "success": false and an error message, while the rest are saved.

Send one entry

POST
/api/v1/{projectId}/logs

X-API-Key required.

The body is one entry with the fields above. Here only the required fields and the allowed values of level and eventType are checked; the length limits apply to batches. The response is 201 with the stored entry in data.

Terminal
curl -X POST "https://apperioserver.onrender.com/api/v1/your-project-id/logs" \
  -H "X-API-Key: your-api-key" \
  -H "Content-Type: application/json" \
  -d '{"level":"warn","message":"Disk 90% full","service":"worker","environment":"production"}'

Sampling

The project’s Settings › Sampling applies to this endpoint only. When an entry is sampled out, the response is 202 with "message": "Log sampled out" and nothing is stored. Batches, and so the SDK, aren’t sampled.

What happens to a log

  • It is stored as you sent it. Nothing is redacted on the server.
  • Entries at error or fatal are grouped into issues and can notify the project owner, exactly like errors from the SDK. Include error.name, error.message and error.stack for good grouping.
  • Every entry is checked against your alert rules.
  • Logs are kept for the project’s retention period, 30 days by default.