Skip to main content

Endpoint

POST /v1/logs Base URL: https://timberlogs-ingest.enaboapps.workers.dev

Supported Formats

The ingestion endpoint accepts logs in multiple formats. Format is resolved by priority:
  1. ?format= query parameter (highest priority)
  2. Content-Type header
  3. Auto-detection via content sniffing (fallback)

Request

Headers

Query Parameters

Default query parameters are useful for formats like plain text and syslog where source and environment may not be present in the log data.

Body (JSON)

The JSON parser also accepts a bare array [...] or a single object {...}.

Body (JSONL)

One JSON object per line. Empty lines are skipped.

Body (Syslog)

RFC 5424:
RFC 3164:
Syslog severity is mapped to log levels: emergency/alert/critical/error → error, warning → warn, notice/info → info, debug → debug. The APP-NAME or TAG becomes source, and HOSTNAME/PROCID are stored in data.

Body (Plain Text)

One log per line. The parser extracts timestamps (ISO 8601, YYYY-MM-DD HH:MM:SS, MM/DD/YYYY HH:MM:SS) and level keywords (ERROR, WARN, WARNING, INFO, DEBUG, case-insensitive). Use ?source= and ?environment= query params to set required fields.

Body (CSV)

First row is the header. Column names must match log schema field names. Tab-delimited files are also accepted (auto-detected). Quoted fields with commas are supported.

Body (OBL)

Open Board Logging (.obl) is a standard format for AAC (Augmentative and Alternative Communication) device logs. Each event in each session becomes a separate log entry. Event types are button, utterance, action, and note. Event mapping:
  • button → message: Button: {label}, data includes spoken, button_id, board_id
  • utterance → message: Utterance: {text}, data includes constituent buttons
  • action → message: Action: {action}, data includes destination_board_id, text
  • note → message: Note: {text}, data includes author_name
The OBL user_id maps to userId, device_id maps to sessionId, and session/event metadata is stored in data. The root source field is used as the log source. Use ?source= and ?environment= query params to set defaults. Files may start with a /* ... */ comment block which is stripped before parsing. Auto-detection works by checking for "open-board-log-" in the JSON.

Log Entry Schema

Required fields can be provided via query parameter defaults when using non-JSON formats.

Batch Limits

  • Minimum: 1 log per request
  • Maximum: 100 logs per request

Response

Success (200)

Error Responses

400 Bad Request - Invalid request body or parse error
How to resolve: Check the error message for details. For JSONL, the line number is included. For JSON, check the issues array. Common causes: invalid level enum value, missing required fields, malformed input, or exceeding the 100-log batch limit. 401 Unauthorized - Invalid or missing API key
How to resolve: See Authentication for details on API key format and usage. 429 Too Many Requests - Rate limit exceeded
How to resolve: Wait retryAfter seconds before retrying. Consider batching logs into fewer requests or upgrading your plan.

Examples

Basic Log (JSON)

JSONL

Syslog

Plain Text

CSV

OBL (AAC Device Logs)

Log with Data

Error Log

Batch Logs

Flow Tracking

Raw Ingestion via SDK

The TypeScript and Python SDKs provide ingestRaw() / ingest_raw() methods that send pre-formatted data directly to this endpoint. The SDK handles Content-Type headers, query parameter encoding, and retry logic automatically.
This is equivalent to:
See the TypeScript SDK and Python SDK docs for full details.

Rate Limits

Rate limits depend on your plan: When rate limited, you’ll receive a 429 response with a retryAfter value indicating when to retry.

Best Practices

  1. Batch logs - Send multiple logs per request to reduce overhead
  2. Use the SDK - The TypeScript and Python SDKs handle batching and retries automatically
  3. Include context - Add userId, sessionId, and requestId for correlation
  4. Use structured data - Put details in data rather than interpolating into message
  5. Tag appropriately - Use consistent tags for filtering
  6. Handle errors - Implement retry logic with exponential backoff
  7. Use explicit formats - Prefer ?format= or Content-Type over auto-detection for reliability
  8. Set defaults for non-JSON formats - Use ?source= and ?environment= query params when sending plain text or syslog