Skip to main content
Web apps can’t easily connect to a custom TCP port, so the HTTP source provides an alternative ingestion path with JSONL and binary support. This is what the JavaScript SDK uses.

Endpoints

The JSONL endpoints accept one JSON object per line. The binary endpoint accepts pre-encoded FlatBuffer batches — the same wire format the TCP source uses. Content types application/octet-stream and application/x-tell are also accepted on the binary endpoint.

Authentication

Three ways to authenticate, in precedence order:
  1. Authorization: Bearer <key> header
  2. X-API-Key: <key> header
  3. ?token=<key> query parameter
The query parameter option exists for browser SDKs that need to avoid CORS preflight requests on simple POST requests.
Keys are 32 hex characters. See API keys for creating and managing them.

Responses

202 Accepted — all items ingested successfully:
207 Multi-Status — partial success (some items rejected):
400 Bad Request — all items rejected or invalid format. 401 Unauthorized — missing or invalid API key. 413 Payload Too Large — request body exceeds max_payload_size. 429 Too Many Requests — rate limited after repeated auth failures. 503 Service Unavailable — pipeline backpressure (channel full).

CORS and browser clients

CORS is enabled by default so browser SDKs work without extra setup. The source mirrors the request’s Origin header and allows Authorization, Content-Type, X-API-Key, and X-Workspace-ID headers. To restrict allowed origins:

TLS

Tell supports HTTPS natively via rustls. Provide PEM-encoded certificate and key files:
When both paths are set, the source binds as HTTPS. Omit them to run plain HTTP (the default). For production, you can also terminate TLS at a reverse proxy like Caddy instead — see Reverse proxy below.

Reverse proxy

Running Caddy in front of Tell is the simplest way to get automatic HTTPS with Let’s Encrypt certificates and zero TLS configuration:
Caddy handles certificate provisioning, renewal, and TLS termination automatically. Enable trust_proxy in Tell so the real client IP is captured from X-Forwarded-For:
This also works with nginx or any reverse proxy that sets X-Forwarded-For. Only enable trust_proxy when the HTTP source is behind a trusted proxy — clients can forge the header otherwise.

Rate limiting

Authentication failures are rate-limited per IP. After 10 failures within 60 seconds, the IP is temporarily blocked with 429 Too Many Requests. The rate limiter cleans up expired entries every 5 minutes.

Safety limits

JSONL endpoints enforce two limits to prevent denial-of-service:
  • 10,000 lines per request — requests with more lines are rejected
  • 32 levels of JSON nesting — deeply nested objects are rejected before parsing
These limits are not configurable. Malformed JSON lines are skipped individually — a single bad line won’t reject the entire request (you’ll get a 207 response with per-line errors).

Configuration reference

What’s next

  • TCP source — higher throughput for native SDKs
  • JavaScript SDK — the primary client for the HTTP source
  • API keys — create and manage streaming keys
  • Routing — control where HTTP data goes after ingestion