Skip to Content
LoadersGeneric HTTP Push

Generic HTTP Push

The Generic HTTP Push loader receives events over HTTP instead of pulling from a source on a schedule. Your application posts JSON events to a Zeotap endpoint, and each event is durably captured and loaded into your warehouse — no polling, cron schedule, or source API required.

Use it when you control the producer and want to stream your own events (product analytics, server-side signals, webhooks from other systems) directly into Zeotap with a simple HTTP call.

When to Use It

  • You own the system generating the data and can make an outbound HTTP request from it.
  • You want push-based, near-real-time ingestion rather than a scheduled pull.
  • Your payloads are freeform JSON whose shape may vary between events.
  • You are forwarding webhooks from another platform into your warehouse.

For pull-based ingestion from a SaaS API or database on a schedule, use one of the other loaders instead.

How It Works

Generic HTTP Push flow: client posts to the receiver, which publishes to a durable event stream that a consumer batches and loads into the warehouse
  1. Your client sends a POST request with a JSON event to the receiver, authenticating with a write key.
  2. The receiver durably accepts the event and immediately responds with {"success":true}.
  3. Accepted events are buffered on a durable event stream, tagged with the loader they belong to.
  4. An always-on consumer batches events per loader and loads them into that loader’s configured warehouse.

Because the receiver acknowledges only after the event is durably stored, a success response means the event will be loaded — you do not need to keep it yourself once acknowledged.

Prerequisites

  • A connected warehouse to load events into (BigQuery, Snowflake, Databricks, or ClickHouse).
  • A system that can make an outbound HTTPS request with a JSON body.

Create the Loader

  1. In Zeotap, go to Loaders and click Add Loader.
  2. Choose Generic HTTP Push.
  3. Select the Target Warehouse and Schema where events should land.
  4. Optionally set a Target Table name (defaults to events).
  5. Save the loader.
FieldRequiredDescription
Target WarehouseYesThe warehouse source that received events are loaded into.
SchemaYesThe schema/dataset that holds the events table.
Target TableNoThe table name events land in. Defaults to events.

Mint a Write Key

Requests authenticate with a write key — a per-loader credential you manage in the UI.

  1. Open your Generic HTTP Push loader.
  2. Go to the Write Keys section and click Create Write Key.
  3. Copy the generated key and store it in your application’s configuration.

Write keys are public identifiers (Segment-style): they identify which loader an event belongs to and authorize writes, but they are not secrets that unlock reads. It is safe to embed them in server-side producers. You can create multiple keys per loader (for example, one per environment or service) and revoke any key at any time from the same screen. Revocation takes effect within a few minutes (the receiver briefly caches key lookups).

Sending Events

The receiver exposes two endpoints.

EndpointBodyUse
POST /v1/pushA single JSON event objectSend one event per request.
POST /v1/push/batchA JSON array of events, or an object {"batch":[...]}Send many events in one request.

Authentication

Send your write key with every request. Three options are accepted, in this order of convenience:

  • X-Write-Key header (recommended) — X-Write-Key: <write-key>
  • HTTP Basic Auth — the write key as the username, with an empty password.
  • writeKey query parameter?writeKey=<write-key> (useful where custom headers are hard to set).

Single event

curl -X POST https://composable.zeotap.com/v1/push \ -H "X-Write-Key: YOUR_WRITE_KEY" \ -H "Content-Type: application/json" \ -d '{ "event": "product_viewed", "user_id": "u_123", "properties": { "sku": "ABC-001", "price": 29.99 } }'

Response:

{ "success": true }

Batch of events

Send a JSON array:

curl -X POST https://composable.zeotap.com/v1/push/batch \ -H "X-Write-Key: YOUR_WRITE_KEY" \ -H "Content-Type: application/json" \ -d '[ { "event": "product_viewed", "user_id": "u_123" }, { "event": "product_added", "user_id": "u_123" } ]'

Or wrap the events in a batch object:

{ "batch": [ { "event": "product_viewed", "user_id": "u_123" }, { "event": "checkout_started", "user_id": "u_123" } ] }

The batch endpoint returns the number of events durably accepted:

{ "success": true, "received": 2 }

If some events in the batch could not be accepted, the response still returns HTTP 200 with success: false and an errors array describing the failures, alongside the received count of those that succeeded. Retry the failed events.

How Data Lands in the Warehouse

Events are loaded as freeform JSON — the loader does not require or enforce a schema, so producers can evolve their payloads freely. Each event becomes one row with a fixed set of columns:

ColumnDescription
loader_idThe loader the event was sent to (derived from the write key).
message_idA unique identifier for the event.
workspace_idThe workspace that owns the loader.
received_atThe time the receiver durably accepted the event.
payloadThe complete JSON body you posted, stored as JSON.

Your event’s own fields live inside payload. Extract them downstream in a model using your warehouse’s JSON functions — for example, in BigQuery:

SELECT message_id, received_at, JSON_VALUE(payload, '$.event') AS event, JSON_VALUE(payload, '$.user_id') AS user_id, JSON_VALUE(payload, '$.properties.sku') AS sku FROM events -- your loader's target table (default: events)

Delivery Semantics

Delivery is at-least-once. Every acknowledged event is guaranteed to reach the warehouse, but under retries or transient failures the same event may occasionally be loaded more than once.

  • Producers should retry on network errors or non-2xx responses. A retry after a request that actually succeeded is safe — it may simply produce a duplicate row.
  • De-duplicate downstream if you need exactly-once semantics. Send a stable identifier in your payload (for example an event_id) and deduplicate on it in a model, or use message_id together with your own key.
  • Do not treat a missing response as a failure to store — retry, and reconcile duplicates later rather than dropping events.

Troubleshooting

IssueResolution
401 UnauthorizedThe write key is missing, malformed, or revoked. Confirm you are sending it via X-Write-Key, Basic Auth username, or ?writeKey=, and that the key is still active.
400 Bad RequestThe body is not valid JSON, or a batch request was not an array or {"batch":[...]} object. Check the Content-Type is application/json and the payload parses.
413 Payload Too LargeA single event exceeds 1 MB, or a batch exceeds 10 MB. Split large payloads into smaller batches.
Events accepted but not in the warehouse yetLoading is batched, so there is a short delay between acknowledgement and the row appearing. Confirm the loader’s target warehouse and schema are correct.
Duplicate rowsExpected under at-least-once delivery. Deduplicate downstream on a stable payload identifier or message_id.

Next Steps

Last updated on