---
title: "Create Custom Event"
method: POST
path: "/custom/event"
tags: ["custom"]
---

# Create Custom Event

`POST /custom/event`

## Request

- Base URL: `//staging.mr-in.com/v1` (relative, and the document’s source URL is not known)
- URL: `//staging.mr-in.com/v1/custom/event`
- Auth: none declared

Custom events can be any arbitrary JSON as long as you provide Event Metadata

MetaRouter requires a small set of structured metadata to accept and deliver events. In most cases, providing 2 fields
is all we need to process your data: `writeKey` and `eventName`.

Event Metadata is added to each event with the top-level key `_metarouter`.

The Event Metadata consists of the following required and optional fields:

All field types are strings.

| Field       | Required                            | Description                                                                                                                                                                               |
|-------------|-------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| writeKey    | required                            | Write Key is your API key.                                                                                                                                                                |
| eventName   | required                            | Event Name is an arbitrary category for the event. Examples: "order created", "page view", "sign in"                                                                                      |
| eventID     | optional (auto-generated if absent) | Event ID is a guid/uuid for tracing the lifecycle of an event. If absent, MetaRouter creates a random UUIDv4.                                                                             |
| timestamp   | optional (auto-generated if absent) | Timestamp is when the event was created. Must be a string in [ISO 8601 format](https://en.wikipedia.org/wiki/ISO_8601). If absent, MetaRouter sets this field to the current server time. |
| anonymousID | optional                            | Anonymous ID is used for tracking and attribution. It should be a persistent, unique identifier (like a uuid) for an unauthenticated user.                                                |
| userID      | optional                            | User ID is used for tracking and attribution. It should be a persistent, unique identifier (like a hashed email or database id) for an authenticated user.                                |
| ip          | optional (set if absent)            | IP address. If absent, system adds IP address of the http request.                                                                                                                        |

Inside an event, the event metadata is referenced as a simple JSON object with reserved key `_metarouter`.
The `_metarouter` key must be part of the root object.

```json
{
  "_metarouter": {
    "writeKey": "abc123",
    "eventName": "page view",
    "eventID": "123e4567-e89b-12d3-a456-426614174000",
    "timestamp": "2021-08-17T15:10:33Z",
    "anonymousID": "456e4567-e89b-12d3-a456-426614174000",
    "userID": "98765"
  },
  "event": "my event fields",
  "json": "whatever json you want"
}
```

You're free to omit optional fields or fields that MetaRouter auto-generates.

```json
{
  "_metarouter": {
    "writeKey": "abc123",
    "eventName": "page view"
  },
  "event": "my event fields",
  "json": "whatever json you want"
}
```

## JSONPath

To reduce burden on clients, you can use [JSONPath](https://goessner.net/articles/JsonPath/) expressions to use values
from your event to populate the Event Metadata.

JSONPath syntax resources:

* [goessner/jsonpath](https://goessner.net/articles/JsonPath/)
* [smartbear/jsonpath](https://support.smartbear.com/alertsite/docs/monitors/api/endpoint/jsonpath.html)
* [baeldung/jsonpath](https://www.baeldung.com/guide-to-jayway-jsonpath)

Note the `_metarouter.eventName` is a JSONPath expression. In English, this JSONPath query says "use the value at
productCategory as the eventName".

```bash
curl -X POST https://staging.mr-in.com/v1/custom/event \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{
  "_metarouter": {
    "writeKey": "example",
    "eventName": "{ ..productCategory }"
  },
  "event": "my event fields",
  "productCategory": "kitchen"
}'
```

Notice the `_metarouter.eventName` is set to 'kitchen'. Returns 201 response:

```json
{
  "event": {
    "_metarouter": {
      "eventID": "a4d896bb-f425-4dac-a214-31940cf94006",
      "eventName": "kitchen",
      "writeKey": "example",
      "timestamp": "2021-08-17T18:08:09Z"
    },
    "event": "my event fields",
    "productCategory": "kitchen"
  },
  "success": true
}
```

## Request Header

Placing an `"_metarouter": {}` object in your event is one way to submit events to the Ingest API.

You can also set the `X-Event-Metadata` header to provide a metadata object

```bash
curl -X POST https://staging.mr-in.com/v1/custom/event \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-Event-Metadata: {"writeKey": "example", "eventName": "{ ..productCategory }"}' \
  -d '{"event": "my event fields", "productCategory": "kitchen" }'
````

Returns 201 response:

```json
{
  "event": {
    "_metarouter": {
      "eventID": "defc1d32-01d7-416e-b9ba-534e04c13121",
      "eventName": "kitchen",
      "writeKey": "example",
      "timestamp": "2021-08-17T18:08:38Z"
    },
    "event": "my event fields",
    "productCategory": "kitchen"
  },
  "success": true
}
```

## Request Query Params

Placing an `"_metarouter": {}` object in your event is one way to submit events to the Ingest API.

Finally, you can place the Event Metadata in the request query params.

```bash
curl -X POST https://staging.mr-in.com/v1/custom/event?writeKey=example&eventName=%7B%20..productCategory%20%7D \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{"event": "my event fields", "productCategory": "kitchen" }'
```

Returns 201 response:

```json
{
  "event": {
    "_metarouter": {
      "eventID": "89e4438d-471e-4993-88b5-7e5692239da2",
      "eventName": "kitchen",
      "writeKey": "example",
      "timestamp": "2021-08-17T18:09:06Z"
    },
    "event": "my event fields",
    "productCategory": "kitchen"
  },
  "success": true
}
```

## Metadata Precedence

If an object is present in `X-Event-Metadata` header or the query params, the metadata is *merged* with
any `_metarouter`
object in the event. Matching fields in the header or params overrides any existing values in the `_metarouter` object.

If you submit both an `X-Event-Metadata` header and query params, the header takes precedence and the query params are
ignored.

## Legacy _mrSchema

Previously, event metadata was an object at `_mrSchema`. To preserve backwards compatability, the legacy `_mrSchema`
object is also included in the final event. `_mrSchema` will be deprecated in the future. At this time, there is no
timetable for deprecation. MetaRouter will ensure all pipelines and playbooks are updated before deprecating.

The object at `_mrSchema` is identical to `_metarouter`.

## Query parameters

- `anonymousID` string
- `eventID` string
- `eventName` string
- `ip` string
- `timestamp` string
- `userID` string
- `writeKey` string

## Headers

- `X-Event-Metadata` string

## Response `200`

OK

- V1SuccessResponse
  - `event` EventCustom
  - `success` boolean

## Other responses

- `400`: Bad Request
- `422`: Unprocessable Entity
- `default`

---

[API](https://skmtc.dev/metarouter/apis/ingest-api.md) - [All operations](https://skmtc.dev/metarouter/apis/ingest-api/llms.txt) - [OpenAPI document](https://skmtc.dev/metarouter/apis/ingest-api/revisions/59ef14f52d10?raw)
