API Reference

The Lumber REST API base URL is https://api.lumber.infinitetoken.com.

Most developers should use the Node.js SDK rather than calling the API directly. The SDK handles encryption, queuing, retries, and authentication automatically. The only endpoint documented for direct use is log ingestion. The rest of the API serves the Lumber app.

Authentication

Log ingestion is authenticated with an app API key in the Authorization header:

Authorization: Bearer your_api_key

API keys are created in the Lumber app on your app's Secrets screen. See Authentication.

Log Ingestion

POST /logs

Ingest a single encrypted log entry. Send one request per log - there is no batch format. Authenticated with an app API key. Send the body as JSON with a Content-Type: application/json header.

Request body:

{
  "level": 2,
  "encrypted": {
    "nonce": "base64encodedIV",
    "payload": "base64encodedAuthTagAndCiphertext",
    "keyVersion": 1
  }
}
FieldTypeDescription
levelnumberLog level (see below). Stored unencrypted.
encrypted.noncestringBase64 of the 12-byte AES-GCM IV
encrypted.payloadstringBase64 of the 16-byte GCM auth tag followed by the ciphertext
encrypted.keyVersionnumberKey version. The SDK always sends 1.

The plaintext is the JSON-encoded log payload (level, message, and optional requestId, traceId, context, and metadata), encrypted with AES-256-GCM using the app's 32-byte encryption key.

Log levels:

ValueName
0debug
1info (default for lumber.log())
2warn
3error
4fatal

Response: 201 Created with the stored record:

{
  "data": {
    "id": "6f1c2a9e-...",
    "appId": "0b7d4e12-...",
    "level": 2,
    "encrypted": {
      "nonce": "base64encodedIV",
      "payload": "base64encodedAuthTagAndCiphertext",
      "keyVersion": 1
    },
    "createdAt": "2026-10-15T14:32:01.452Z"
  },
  "metadata": {
    "requestId": "a3e1c7d0-...",
    "durationMs": 12
  }
}

Error responses:

StatusDescription
400Malformed JSON, or a missing or invalid field (level, encrypted, encrypted.nonce, encrypted.payload, encrypted.keyVersion)
401Missing Authorization header, or an invalid or deleted API key
413Request body larger than 100 KB
500Server error

Response format

Successful responses use a consistent envelope:

{
  "data": { ... },
  "metadata": {
    "requestId": "string",
    "durationMs": 0
  }
}

requestId echoes the X-Request-Id request header when you send one, and is a generated UUID otherwise.

Error responses use standard HTTP status codes with a JSON body containing a message:

{
  "message": "Invalid token"
}

Server errors (5xx) always return { "message": "Internal Server Error" }.