Overview

This document covers the basic structure of MetaRouter's HTTP Tracking API endpoints and how to connect and send information into the platform via the API.

Getting Started

Authentication (optional)

You will need to supply your pipeline's writeKey with each request using HTTP Basic Auth.

Basic Auth base64 encodes a username:password and prepends it with the string Basic. The native libraries should handle this for you, but if they do not you will need to base64 encode a string, where the username is the writeKey and the password is empty. You can base64 encode your writeKey here.

For example, if your writeKey is ILoveData123, that will be encoded to SUxvdmVEYXRhMTIz. Then, your encoded authentication line in your header will look like this:

Authorization: Basic SUxvdmVEYXRhMTIz

Content-Type

Make sure to set the content-type header to application/json.

Errors and Error responses

The HTTP Tracking API uses several response codes to validate requests sent to the API. The following are response codes rendered by the server and an explanation for each:

Status CodeExplanation
200 OKEvent data is valid and has been accepted in the platform.
207 Multi-StatusUsed by the batch endpoint to signify partial success, indicating some events were valid while others failed.
400 Bad RequestEvent data contains errors and can not be processed by the platform.
413 Request Entity Too LargeUsed to signify the event payload is too large to be received.

Error responses render JSON bodies that can help determine the reason the event was rejected by the system. The following is an example of a typical error response. The Errors key contains an array of error objects with a list of all of the errors encountered by the platform.

{
  "Error": "Bad Request",
  "Message": "Invalid or missing writekey",
  "Details": ""
}

Batch error endpoints return errors in a slightly different format. The Errors key contains an array of error objects with a list of all of the errors encountered by the platform.

{
  "Success": false,
  "Errors": [
    {
      "Error": "Bad Request",
      "Message": "Error reading request body",
      "Details": "HTTP request too large"
    }
  ]
}

Max Request Size

The MetaRouter HTTP API limits call sizes to a maximum of 32KB per call. The batch endpoint accepts a maximum of 500KB per batch and 32KB per call. The API will respond with a "413 request entity too large" response if these limits are exceeded.

Common Fields

This section contains fields that are common across all events and descriptions for each.

General Event Fields

FieldRequiredTypeExplanation
anonymousIdoptional (if userId exists)StringA pseudo-unique substitute for a User ID. For cases when you do not include your own unique identifier. At minimum, a userId OR an anonymousId is required.
contextoptionalObjectDictionary of extra information that provides useful context about a message, but is not directly related to the API call, such as IP addresses or locales. You can find more information on Context fields here.
messageIdrequiredStringA unique identifier for each message and can be used to find an individual message anywhere within the MetaRouter platform.
receivedAtimplicitDateAutomatically set by the HTTP Tracking API. The timestamp of when a message is received by the API. This timestamp is represented as an ISO-8601 date string.
sentAtoptionalDateTimestamp representing when a message is sent to HTTP Tracking API. This is used for clock skew correction and is set automatically by the MetaRouter tracking libraries. This timestamp is represented as an ISO-8601 date string.
timestampoptionalDateTimestamp when the message itself was generated. This is defaulted to the current time by the HTTP Tracking API and is represented as a ISO-8601 format date string. If the event is produced and sent to MetaRouter in real-time, you do not need to include this field, as MetaRouter will add it to the payload using the server’s time. If you are importing data from the past, make sure to provide this timestamp field.
typerequiredStringType of message, corresponding to the API method: identify, group, track, page, or screen.
userIdoptional (if anonymousID is set instead)StringUnique identifier for the user in your database. A userId or an anonymousId is required.

Context Object Fields

FieldTypeExplanation
activeBoolWhether a user is active. This is usually used to flag an .identify() call to update traits but not last seen.
appObjectDictionary of information about the current application, containing name, version and build. This is collected automatically from our mobile libraries when possible.
campaignObjectDictionary of information about the campaign that resulted in the API call, containing name, source, medium, term, and content. This maps directly to common UTM campaign parameters.
deviceObjectDictionary of information about the device containing the ID, manufacturer, model, name, type and version.
ipStringCurrent user’s IP address.
libraryObjectDictionary of information about the library making the requests to the API, containing name and version.
localeStringLocale string for the current user. For example, en-US.
locationObjectDictionary of information about the user’s current location, containing city, country, latitude, longitude, region, and speed.
networkObjectDictionary of information about the current network connection, containing Bluetooth, carrier, cellular, and Wi-Fi.
osObjectDictionary of information about the operating system, containing name and version.
pageObjectDictionary of information about the current page in the browser, containing hash, path, referrer, search, title, and URL. Page information is automatically collected by Analytics.js.
referrerObjectDictionary of information about the way the user was referred to the website or app, containing type, name, URL, and link.
screenObjectDictionary of information about the device’s screen, containing density, height, and width.
timezoneStringTimezones are sent as tzdata strings to add user timezone information which might be stripped from the timestamp. For example, America/New_York.
groupIdStringGroup / Account ID. This is primarily useful for B2B use cases, where you need to attribute your non-group calls to a company or account. It is relied upon by several Customer Success and CRM tools.
traitsObjectDictionary of traits of the current user. This is useful in cases where you need to track an event, but also associate information from a previous identify call. You should fill this object the same way you would fill traits in an identify call.
userAgentStringUser-agent of the device making the request.

Standard Calls

See the list of POST calls and their use cases below to determine the calls that you need to make. We have also included examples of how you would call specific objects using the HTTP API.

Identify

The identify method helps you associate your users and their actions to a unique and recognizable userID and any optional traits that you know about them. We recommend calling identify a single time; when the user's account is first created, and only again when their traits change.

POST to https://e.metarouter.io/v1/i or https://e.metarouter.io/v1/identify

FieldRequiredTypeExplanation
traitsoptionalObjectFree-form dictionary of traits of the user, like email or name
{
  "userId": "1234qwerty",
  "traits": {
    "name": "Arthur Dent",
    "email": "[email protected]",
    "hasGalaxyMap": True,
  }
  "timestamp": "2020-11-10T00:45:23.412Z",
  "type": identify
}

Track

To create to a more complete event tracking analytics setup, you can add a track call to your website. This will provide MetaRouter with the actions your users are performing on your site. Each track call triggers an event with a set of associated properties, such as A/B testing variables, products purchased, or other related attributes you would like to track.

POST to https://e.metarouter.io/v1/t or https://e.metarouter.io/v1/track

PropertyRequiredTypeExplanation
eventrequiredStringName of the action that a user has performed.
propertiesoptionalObjectFree-form dictionary of properties of the event, like revenue.
{
  "userId": "1234qwerty",
  "event": "Added File",
  "properties": {
    "fileTitle": "Life, the Universe, and Everything",
    "fileSize": "42kb",
    "fileType": "PDF"
  },
  "timestamp": "2020-11-10T00:45:23.412Z",
  "type": "track"
}

Page

The page method allows you to record page views on your website. It also allows you to pass additional information about the pages your users are viewing.

POST to https://e.metarouter.io/v1/p or https://e.metarouter.io/v1/page

PropertyRequiredTypeExplanation
nameoptionalStringName of the page. For example, most websites have a “Signup” page that can be useful to tag, so you can see users as they move through your funnel.
propertiesoptionalObjectFree-form dictionary of properties of the event, like revenue.
{
  "userId": "1234qwerty",
  "section": "Blog",
  "name": "10 Questions with Marvin",
  "properties": {
    "referrer": "http://reddit.com/r/AMA"
  }
  "type": page
}

Group

The group method associates an identified user with a company, organization, project, etc.

POST to https://e.metarouter.io/v1/g or https://e.metarouter.io/v1/group

PropertyRequiredTypeExplanation
groupIdrequiredStringA unique identifier for the group in your database.
traitsoptionalObjectFree-form dictionary of traits of the group, like email or name.
{
  "userId": "1234qwerty",
  "groupId": "5678dvorak",
  "traits": {
    "name": "The Hitchhikers",
    "relativePosition": "[39.1000 N, 84.5167 W]"
    }
  "type": group
}

Utility Endpoints

The HTTP API offers additional event collection endpoints to help with specific implementation use-cases.

Batch

The batch method allows for submitting multiple events with one request. The events follow the standard message formats from above and allow for context and timestamps to be injected as top-level keys.

POST to https://e.metarouter.io/v1/batch or https://e.metarouter.io/v1/import

{
  "batch": [
    {
      "anonymousId": "cf09e649-fd0b-46b6-9fc1-53ab9cd05c47",
      "messageId": "317b11a8-8cd3-40ad-b3fb-622835c42cfd",
      "sentAt": "2020-03-02T18:29:53.661Z",
      "timestamp": "2020-03-02T18:29:27.333Z",
      "type": "track",
      "writeKey": "test1",
      "event": "example 1 event",
      "sentAt": "2020-03-02T18:29:53.661Z",
      "context": {
    		"page": {
      		"path": "/mycart/home",
      		"referrer": "https://www.example.com/",
      		"title": "Example - Shopping Cart",
      		"url": "https://www.example.com/mycart/home",
      	}	
      }
    },
    {
      "anonymousId": "cf09e649-fd0b-46b6-9fc1-53ab9cd05c47",
      "messageId": "317b11a8-8cd3-40ad-b3fb-123d417b11a8",
      "sentAt": "2020-03-02T18:29:53.661Z",
      "timestamp": "2020-03-02T18:29:27.333Z",
      "type": "track",
      "writeKey": "test1",
      "event": "example 1 event"
    }
  ],
  "context": {
    "page": {
      "path": "/mycart/home",
      "referrer": "https://www.example.com/",
      "title": "Example - Shopping Cart",
      "url": "https://www.example.com/mycart/home"
    },
    "userAgent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36"
  },
  "integrations": {
    "All": true,
  },
  "sentAt": "2020-03-02T18:29:53.661Z"
}

Tracking Pixel

The API also exposes a /v1/pixel/... route for each of our single event POST requests to allow you to send data via a GET request. This option requires you to include the JSON payload as a Base64 encoded query parameter.

For example, the following payload for a Track Event:

{
  "event": "example event",
  "messageId": "1234567890",
  "type": "track",
  "writeKey": "example",
  "userId": "0987654321"
}

Would be sent as a Tracking Pixel by calling the following URL:

https://e.metarouter.io/v1/pixel/track?data=ewogICJldmVudCI6ICJleGFtcGxlIGV2ZW50IiwKICAibWVzc2FnZUlkIjogIjEyMzQ1Njc4OTAiLAogICJ0eXBlIjogInRyYWNrIiwKICAid3JpdGVLZXkiOiAiZXhhbXBsZSIsCiAgInVzZXJJZCI6ICIwOTg3NjU0MzIxIgp9

The following are the supported Tracking Pixel routes:

  • /v1/pixel/track
  • /v1/pixel/page
  • /v1/pixel/identify
  • /v1/pixel/group

Important Note: Ensure your tracking pixels contain the required fields

While the MetaRouter Platform's Ingestion API will provide feedback for errors, the most common mistake is to miss required properties of the data you encode into the pixel's URL.

The following are example payloads for the minimum required payload for every supported pixel type that you may use as a starting point. Refer to the Standard Calls section for all available fields, including the properties field that tends to do the most lifting for tracking user details, as tracking pixel calls will have the same structure as their equivalent HTTP Post requests.

Track

{
  "type": "track",
  "writeKey": "example",
  "event": "example event",
  "userId": "0987654321"
}

Page

{
  "type": "page",
  "writeKey": "example",
  "name": "10 Questions with Marvin",
  "userId": "0987654321"
}

Identify

{
  "type": "identify",
  "writeKey": "example",
  "userId": "0987654321",
  "anonymousId": "1234567890"
}

Group

{
  "type": "group",
  "writeKey": "example",
  "userId": "0987654321",
  "groupId": "QWERTYUIOP"
}

Webhook Endpoint

Our API is able to receive Analytics.js formatted data from other systems from a general POST route, normally used for other platforms that can send data in this format as a Webhook.

Set the URL to be used as https://e.metarouter.io/v1/webhook or https://e.metarouter.io/v1/w and add a query parameter to set the writeKey for the MetaRouter Platform to overwrite the incoming data with.

For example, https://e.metarouter.io/v1/webhook?writeKey=abcdefg where the writeKey is replaced with that of the writeKey you have configured.

Using Non-Analytics.js Event Specifications

If your organization is using an event spec other than Analytics.js, MetaRouter can process those events without configuration. The HTTP API is able to accept events that do not conform to the analytics.js specification. Using this feature requires two things to be true: a _metarouter metadata to be present and for events to be directed to the /v1/custom/event endpoint.

If provided within the transmission of an event JSON object, _metarouter allows for the normalization of fields required by the platform in order to accurately route events.

{
	_metarouter: {
		writeKey: "mr_platform_pipeline", // required
		eventName: "Page", // required
		eventID: "123-456-78910", // optional, autogenerated if absent
		timestamp: "2021-08-17T15:10:33Z", // optional, autogenerated if absent
		anonymousID: "456e4567-e89b-12d3-a456-426614174000", // required if userID is not present
		userID: "98765" // required if anonymousID is not present
	},
	custom: "client",
	event: {payloads: "and properties"},
	...
}

The MetaRouter Schema Metadata can be located in any of the three locations below:

  • Within the Event JSON: Located at the root of the event object, with the key _metarouter
  • Within the Request Headers: Located within the custom X-Event-Metadata header with stringified JSON as the value
  • Within Query Parameters: Matching the keys within the _metarouter example

If you need further guidance for how to format your non-Analytics.js events, don't hesitate to get in touch with the MetaRouter team for additional guidance.