Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 25 additions & 20 deletions reference/import-events.mdx
Original file line number Diff line number Diff line change
@@ -1,27 +1,30 @@
---
openapi: /openapi/identity.openapi.yaml POST /import
title: Import Events
title: "Import Events"
openapi: "/openapi/ingestion.openapi.yaml POST /import"
---

Use this API to send batches of events from your servers to Mixpanel.

Check warning on line 6 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L6

Did you really mean 'Mixpanel'?

## Request Format

Each request ingests a batch of events into Mixpanel. We accept up to 2000 events and 10MB uncompressed per request. Events are part of the request body.

Check warning on line 10 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L10

Did you really mean 'Mixpanel'?

We support Content-Type `application/json` or `application/x-ndjson`:

<CodeGroup>

```json JSON
[
{"event": "Signup", "properties": {"time": 1618716477000,"distinct_id": "91304156-cafc-4673-a237-623d1129c801","$insert_id": "29fc2962-6d9c-455d-95ad-95b84f09b9e4","Referred by": "Friend","URL": "mixpanel.com/signup"}},

Check warning on line 18 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L18

Did you really mean 'insert_id'?
{"event": "Purchase", "properties": {"time": 1618716477000,"distinct_id": "91304156-cafc-4673-a237-623d1129c801","$insert_id": "935d87b1-00cd-41b7-be34-b9d98dd08b42","Item": "Coffee", "Amount": 5.0}}

Check warning on line 19 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L19

Did you really mean 'insert_id'?
]
```

```json ndJSON
{"event": "Signup", "properties": {"time": 1618716477000,"distinct_id": "91304156-cafc-4673-a237-623d1129c801","$insert_id": "29fc2962-6d9c-455d-95ad-95b84f09b9e4","Referred by": "Friend","URL": "mixpanel.com/signup"}}

Check warning on line 24 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L24

Did you really mean 'distinct_id'?

Check warning on line 24 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L24

Did you really mean 'insert_id'?
{"event": "Purchase", "properties": {"time": 1618716477000,"distinct_id": "91304156-cafc-4673-a237-623d1129c801","$insert_id": "935d87b1-00cd-41b7-be34-b9d98dd08b42","Item": "Coffee", "Amount": 5.0}}
```

</CodeGroup>

We also support `Content-Encoding: gzip` to reduce network egress.
Expand All @@ -38,12 +41,12 @@

### High-level requirements

* Each event must be properly formatted JSON.
* Each event must contain an event name, time, distinct\_id, and \$insert\_id. These are used to deduplicate events so that this endpoint can be safely retried.
* Each event must be smaller than 1MB of uncompressed JSON.
* Each event must have fewer than 255 properties.
* All nested object properties must have fewer than 255 keys and a max nesting depth is 3.
* All array properties must have fewer than 255 elements.
- Each event must be properly formatted JSON.
- Each event must contain an event name, time, distinct\_id, and \$insert\_id. These are used to deduplicate events so that this endpoint can be safely retried.
- Each event must be smaller than 1MB of uncompressed JSON.
- Each event must have fewer than 255 properties.
- All nested object properties must have fewer than 255 keys and a max nesting depth is 3.
- All array properties must have fewer than 255 elements.

### Example of an event

Expand All @@ -52,7 +55,7 @@
"event": "Signed up",
"properties": {
"time": 1618716477000,
"distinct_id": "91304156-cafc-4673-a237-623d1129c801",

Check warning on line 58 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L58

Did you really mean 'distinct_id'?
"$insert_id": "29fc2962-6d9c-455d-95ad-95b84f09b9e4",
"ip": "136.24.0.114",
"Referred by": "Friend",
Expand All @@ -65,7 +68,7 @@

This is the name of the event. If you're loading data from a data warehouse, we recommend using the name of the table as the name of the event.

We recommend keeping the number of unique event names relatively small and using properties for any variable context attached to the event. For example, instead of tracking events with names "Paid Signup" and "Free Signup", we would recommend tracking an event called "Signup" and having a property "Account Type" with the value "paid" or "free".

Check warning on line 71 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L71

Did you really mean 'Signup'?

#### properties

Expand All @@ -79,15 +82,15 @@

##### properties.distinct\_id

`distinct_id` identifies the user who performed the event. distinct\_id must be specified on every event, as it is crucial for Mixpanel to perform behavioral analysis (unique users, funnels, retention, cohorts) correctly and efficiently.

Check warning on line 85 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L85

Did you really mean 'Mixpanel'?

If the event is not associated with any user, set distinct\_id to the empty string. Events with an empty distinct\_id will be excluded from all behavioral analysis.

If no distinct\_id is provided, Mixpanel will use the ip address of the incoming request and compute a distinct\_id using a hash function.

Check warning on line 89 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L89

Did you really mean 'Mixpanel'?

Check warning on line 89 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L89

Did you really mean 'ip'?

To prevent accidental implementation mistakes, we disallow the following values for distinct\_id:

```
```text
- 00000000-0000-0000-0000-000000000000
- anon
- anonymous
Expand All @@ -109,7 +112,7 @@

##### properties.\$insert\_id

We require that \$insert\_id be specified on every event. \$insert\_id provides a unique identifier for the event, which we use for deduplication. Events with identical values for (event, time, distinct\_id, \$insert\_id) are considered duplicates and only one of them will be surfaced in queries.

Check warning on line 115 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L115

Did you really mean 'deduplication'?

\$insert\_ids must be ≤ 36 bytes and contain only alphanumeric characters or "-". We also disallow any value for \$insert\_id from the list of invalid IDs provided for distinct\_id above.

Expand Down Expand Up @@ -144,19 +147,20 @@

## GeoIP Enrichment

If you supply a property `ip` with an IP address, Mixpanel will automatically do a GeoIP lookup and replace the `ip` property with geographic properties (City, Country, Region). These properties can be used in our UI to segment events geographically.

Check warning on line 150 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L150

Did you really mean 'Mixpanel'?

If you do not supply an `ip` property in your event payload, the IP address of the request will be used to parse for geolocation. You can set manually set the value of `ip` to `0` and our API will skip the geolocation parsing for that event.

This is an example of an event before and after enrichment:

<CodeGroup>

```json Pre-Enrichment
{
"event": "Signed up",
"properties": {
"time": 1618716477000,
"distinct_id": "91304156-cafc-4673-a237-623d1129c801",

Check warning on line 163 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L163

Did you really mean 'distinct_id'?
"$insert_id": "29fc2962-6d9c-455d-95ad-95b84f09b9e4",
"ip": "136.24.0.114",
"Referred by": "Friend",
Expand All @@ -170,7 +174,7 @@
"event": "Signed up",
"properties": {
"time": 1618716477000,
"distinct_id": "91304156-cafc-4673-a237-623d1129c801",

Check warning on line 177 in reference/import-events.mdx

View check run for this annotation

Mintlify / Mintlify Validation (mixpanel-edb78807) - vale-spellcheck

reference/import-events.mdx#L177

Did you really mean 'distinct_id'?
"$insert_id": "29fc2962-6d9c-455d-95ad-95b84f09b9e4",
"Referred by": "Friend",
"URL": "mixpanel.com/signup",
Expand All @@ -180,32 +184,33 @@
}
}
```

</CodeGroup>

## Rate Limit

To ensure real-time ingestion and quality-of-service, we have a rate limit of 2GB of uncompressed JSON/minute or \~30k events per second, measured on a rolling 1 minute basis.
To ensure real-time ingestion and quality-of-service, we have a rate limit of 2GB of uncompressed JSON/minute or ~30k events per second, measured on a rolling 1 minute basis.

We recommend the following when it comes to sending data to our API at scale:

* Send data as quickly as possible with concurrent clients until the server returns 429. We see the best results with 10-20 concurrent clients sending 2K events per batch.
* When you see 429s, employ an [exponential backoff with jitter](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) strategy. We recommend starting with a backoff of 2s and doubling backoff until 60s, with 1-5s of jitter.
* We recommend gzip compression and using `Content-Encoding: gzip` to reduce network egress and transfer time.
* In the rare event that our API returns a 502 or 503 status code, we recommend employing the same exponential backoff strategy as with 429s.
* Please do not retry validation errors (400 status code), as they will consistently fail and count toward the rate limit.
- Send data as quickly as possible with concurrent clients until the server returns 429. We see the best results with 10-20 concurrent clients sending 2K events per batch.
- When you see 429s, employ an [exponential backoff with jitter](https://docs.aws.amazon.com/general/latest/gr/api-retries.html) strategy. We recommend starting with a backoff of 2s and doubling backoff until 60s, with 1-5s of jitter.
- We recommend gzip compression and using `Content-Encoding: gzip` to reduce network egress and transfer time.
- In the rare event that our API returns a 502 or 503 status code, we recommend employing the same exponential backoff strategy as with 429s.
- Please do not retry validation errors (400 status code), as they will consistently fail and count toward the rate limit.

If you are an enterprise customer and require a higher limit for a 1-time backfill, please reach out to your sales representative with your project\_id and use-case.

## Common Issues

`$insert_id` is required on all events. This makes it safe to retry `/import` requests. If your events don't already have a unique ID (eg: a UUID/GUID), we recommend computing a hash of some set of properties that make the event semantically unique (eg: distinct\_id + timestamp + some other property) and using the first 36 characters of that hash as the \$insert\_id.
`$insert_id` is required on all events. This makes it safe to retry `/import` requests. If your events don't already have a unique ID (eg: a UUID/GUID), we recommend computing a hash of some set of properties that make the event semantically unique (eg: distinct\_id \+ timestamp \+ some other property) and using the first 36 characters of that hash as the \$insert\_id.

We truncate all strings down to 255 characters. Here's what we recommend for the various cases in which this typically happens:

* URLs: We recommend parsing the URL and tracking its individual components (host, path, url params) as properties. This is more useful in analysis, as you can segment events by hostname or a particular URL parameter.
* JSON encoded strings: Sometimes a long string may be a JSON object encoded as a string. We recommend parsing the JSON and flattening it into properties to send with the event. This is similarly much more useful in analysis, as you can filter or breakdown by any key within the JSON.
* Free text / user generated content: Some long fields may include full-text (eg: a search term or a comment). If this property isn't useful for analysis, we recommend excluding it from tracking to Mixpanel to avoid accidentally sending over any PII.
- URLs: We recommend parsing the URL and tracking its individual components (host, path, url params) as properties. This is more useful in analysis, as you can segment events by hostname or a particular URL parameter.
- JSON encoded strings: Sometimes a long string may be a JSON object encoded as a string. We recommend parsing the JSON and flattening it into properties to send with the event. This is similarly much more useful in analysis, as you can filter or breakdown by any key within the JSON.
- Free text / user generated content: Some long fields may include full-text (eg: a search term or a comment). If this property isn't useful for analysis, we recommend excluding it from tracking to Mixpanel to avoid accidentally sending over any PII.

## Guides

See our Cloud Ingestion guides for example usage of this API to integrate with [Google Pub/Sub](/docs/tracking-methods/integrations/google-pubsub), [Amazon S3](/docs/tracking-methods/integrations/amazon-s3), or [Google Cloud Storage](/docs/tracking-methods/integrations/google-cloud-storage).
See our Cloud Ingestion guides for example usage of this API to integrate with [Google Pub/Sub](/docs/tracking-methods/integrations/google-pubsub), [Amazon S3](/docs/tracking-methods/integrations/amazon-s3), or [Google Cloud Storage](/docs/tracking-methods/integrations/google-cloud-storage).