HTTP ingest API
Last updated
Use the ingest API when there's no Metrickle SDK for your platform, or to send events from your own servers, such as an order confirmed by your back end. The SDKs use this same endpoint, so events you send this way work in goals, funnels, journeys and protected flows like any other. Read Events, people and properties first for what to send.
Send a batch
POST https://in.metrickle.com/v1/batch
# Any other platform (server, game engine, desktop): POST batches of events
curl -X POST https://in.metrickle.com/v1/batch \
-H "content-type: application/json" \
-H "x-metrickle-key: mk_pub_YOUR_WRITE_KEY" \
-d '{
"sentAt": '$(date +%s000)',
"context": { "library": { "name": "my-sdk", "version": "1.0" }, "platform": "ios",
"app": { "version": "2.3.0" }, "device": { "type": "mobile", "os": "iOS" } },
"events": [{
"id": "'$(uuidgen | tr A-Z a-z)'", "type": "screen", "name": "$screen", "ts": '$(date +%s000)',
"anonymousId": "device-uuid", "sessionId": "session-uuid", "path": "Onboarding/Step1"
}]
}'
Send JSON with content-type: application/json. Put the app's write key (mk_pub_…, from the app's Settings page) in the x-metrickle-key header. If you can't set headers, for example with navigator.sendBeacon, put it in the body as writeKey instead.
A write key can only add events to its app, so it's safe to ship inside an app.
The batch
| Field | Type | Notes |
|---|---|---|
sentAt | number, required | When you sent the batch, in Unix milliseconds. Used to correct the sender's clock |
context | object, required | Where the events come from (below). Applies to every event in the batch |
events | array, required | 1 to 100 events |
writeKey | string | The write key, when you can't send the header |
Context
| Field | Type | Notes |
|---|---|---|
library | object, required | { "name", "version" } of the code sending the batch, such as { "name": "my-sdk", "version": "1.0" } |
platform | string, required | web, ios, android, react-native, flutter or server |
app | object | { "version", "build" } of your app. A new version is marked as a release |
device | object | type (desktop, mobile, tablet, tv or other), model, os, osVersion |
screen | object | { "width", "height" } in whole points or pixels |
locale | string | A language tag such as en-GB |
timezone | string | An IANA time zone such as Europe/London |
a11y | array of strings | Accessibility flags seen on the device, such as screen_reader. Unknown flags are ignored. See accessibility context |
When you leave out device, Metrickle reads the device type and operating system from the request's User-Agent.
Events
| Field | Type | Notes |
|---|---|---|
id | UUID, required | Made by you, new for each event. Sending the same id again doesn't store the event twice, so retries are safe |
type | string, required | page, screen, track or identify |
name | string, required | Up to 128 characters, such as $pageview, $screen, $identify or your own event name |
ts | number, required | When it happened, in Unix milliseconds |
anonymousId | string | A random id for the device or install, up to 64 characters |
userId | string | Your id for the signed-in person, up to 128 characters |
sessionId | string | Up to 64 characters |
path | string | The page path or screen name |
url | string | The full page address. The query string is used for UTM tags, then dropped |
title | string | The page or screen title |
referrer | string | Where the visitor came from |
properties | object | Up to 64 flat key–value pairs. Values are strings up to 1,024 characters, finite numbers, booleans or null |
traits | object | On identify events: facts about the person, with the same rules as properties |
Send at most 256 KB per request.
Visitors and sessions
- Send the same
anonymousIdfor every event from one device or install, anduserIdonce the person has signed in. Metrickle then counts one person as one visitor across devices. See people and sessions. - If you leave out
anonymousId, Metrickle makes a visitor id from the request's IP address and user agent, which changes daily. From a server, every event would then look like the same visitor, so always send an id. - If you leave out
sessionId, a session is each 30-minute period of a visitor's activity.
Timestamps
Metrickle uses sentAt to correct for a sender whose clock is wrong. A time in the future is moved to the moment the batch arrived. A time more than 7 days in the past is moved to 7 days ago, so you can't use this API to import older history.
Revenue
Put a numeric revenue property on one of your own events. Send a refund as negative revenue with the same userId. See revenue.
Responses
| Status | Body | What to do |
|---|---|---|
202 | { "ok": true, "accepted": 3 } | Done |
400 | { "error": "invalid_json" } | Fix the body |
400 | { "error": "invalid_batch", "issues": [...] } | Fix the fields listed in issues (up to 10) |
401 | { "error": "missing_write_key" } or "unknown_write_key" | Check the key, and that the app hasn't been archived |
403 | { "error": "origin_not_allowed" } | The request came from a browser page whose domain isn't in the app's allowed origins |
413 | { "error": "payload_too_large" } | Split the batch |
429 | { "error": "rate_limited" } | Wait and send again |
Treat any 2xx, and any 4xx other than 429, as finished: sending the same batch again won't change the answer. After a 429, a 5xx or a network error, keep the events and try again with a growing delay, for example 1 second doubling up to a minute.
Requests are limited to about 600 a minute for each write key and sending address.
When a workspace is far over its plan's monthly events, Metrickle keeps a steady share of visitors and the response includes "sampled": true. See plans and billing.
Allowed origins and bots
- An app with allowed origins set accepts browser requests only from those domains and their subdomains. Requests without an
Originheader, such as from a server or a native app, are always accepted. - Batches with
platformset towebare checked for crawlers and headless browsers by theirUser-Agent. They get a202but nothing is stored. Batches from other platforms aren't checked this way, so sendserverfrom your own back end.
What needs an SDK
The ingest API takes events you can describe yourself. Friction signals, accessibility settings, surveys, feedback, heatmaps and session replay come from the device, so they need a Metrickle SDK. See Web and React Native, iOS, Android or Flutter.