The Batch Event Upload API lets you upload large amounts of event data.
The event JSON format follows the HTTP API format, and has the same requirements.
This API uses your API key passed in the body of the request:
api-key=API_KEY
For more information, see Find your API Credentials
Region | Endpoint |
---|---|
Standard server | https://api2.amplitude.com/batch |
EU residency server | https://api.eu.amplitude.com/batch |
options
property.Use this request to bulk upload events to Amplitude.
The Batch Event Upload API has two differences in the request as compared to the HTTP API:
application/json
.events
payload is events
plural, not event
singular.
1# You can also use wget2curl -X POST https://api2.amplitude.com/batch \3 -H 'Content-Type: application/json' \4 -H 'Accept: */*'
1POST https//api2.amplitude.com/batch HTTP/1.12Host: api2.amplitude.com3Content-Type: application/json4Accept: */*
Parameter | Description |
---|---|
body |
Required. UploadRequestBody. A JSON object that contains your API key and an array of events. |
These properties belong to the request's body.
Name | Description |
---|---|
api_key |
Required. String. Amplitude project API key |
events |
Required. Array of events to upload |
options |
Optional. Options for the request. |
1{ 2 "api_key": "my_amplitude_api_key", 3 "events": [ 4 { 5 "user_id": "datamonster@gmail.com", 6 "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D", 7 "event_type": "watch_tutorial", 8 "time": 1396381378123, 9 "event_properties": {10 "load_time": 0.8371,11 "source": "notification",12 "dates": [13 "monday",14 "tuesday"15 ]16 },17 "user_properties": {18 "age": 25,19 "gender": "female",20 "interests": [21 "chess",22 "football",23 "music"24 ]25 },26 "groups": {27 "team_id": "1",28 "company_name": [29 "Amplitude",30 "DataMonster"31 ]32 },33 "app_version": "2.1.3",
34 "platform": "iOS",35 "os_name": "Android",36 "os_version": "4.2.2",37 "device_brand": "Verizon",38 "device_manufacturer": "Apple",39 "device_model": "iPhone 9,1",40 "carrier": "Verizon",41 "country": "United States",42 "region": "California",43 "city": "San Francisco",44 "dma": "San Francisco-Oakland-San Jose, CA",45 "language": "English",46 "price": 4.99,47 "quantity": 3,48 "revenue": -1.99,49 "productId": "Google Pay Store Product Id",50 "revenueType": "Refund",51 "location_lat": 37.77,52 "location_lng": -122.39,53 "ip": "127.0.0.1",54 "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239",55 "idfv": "BCCE52E7-03EE-321A-B3D4-E57123966239",56 "adid": "AEBE52E7-03EE-455A-B3C4-E57283966239",57 "android_id": "BCCE52E7-03EE-321A-B3D4-E57123966239",58 "event_id": 23,59 "session_id": 1396381378123,60 "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841" 61 }62 ]63}
These properties belong to the events
object.
Name |
Description |
---|---|
user_id |
Required. String. A readable ID specified by you. Must have a minimum length of 5 characters. Required unless device_id is present. |
device_id |
Required. String. A device-specific identifier, such as the Identifier for Vendor on iOS. Required unless user_id is present. If a device_id isn't sent with the event, it's set to a hashed version of the user_id . |
event_type |
Required. String. A unique identifier for your event. Note: $identify and $groupidentify are predefined for identification and group identification. More information about the two operations is in the description of "user_properties" and "group_properties". |
time |
Optional. Long. The timestamp of the event in milliseconds since epoch. If time isn't sent with the event, it's set to the request upload time. |
event_properties |
Optional. Object. A dictionary of key-value pairs that represent properties sent along with the event. You can store property values in an array. Date values are transformed into string values. Object depth may not exceed 40 layers. |
user_properties |
Optional. Object. A dictionary of key-value pairs that represent data tied to the user. You can store property values in an array. Date values are transformed into string values. User property operations ($set , $setOnce , $add , $append , $unset ) are supported when event_type is $identify . Object depth may not exceed 40 layers. |
groups |
Optional. Object. This feature is available only to customers who have purchased the Accounts add-on. This field adds a dictionary of key-value pairs that represent groups of users to the event as an event-level group. Note: You can only track up to 5 unique group types and 10 total groups. Any groups past that threshold aren't tracked. |
group_properties |
Optional. Object. This feature is available only to customers who have purchased the Accounts add-on. When "event_type" is $groupidentify , the field is a dictionary of key-value pairs that represent properties tied to the groups listed in the "groups" field. The field is ignored for other event types. Group property operations ($set , $setOnce , $add , $append , $unset ) are also supported. |
$skip_user_properties_sync |
Optional. Boolean. When true user properties aren't synced. Defaults to false . |
app_version |
Optional. String. The current version of your application. |
platform |
Optional. String. Platform of the device. |
os_name |
Optional. String. The name of the mobile operating system or browser that the user is using. |
os_version |
Optional. String. The version of the mobile operating system or browser the user is using. |
device_brand |
Optional. String. The device brand that the user is using. |
device_manufacturer |
Optional. String. The device manufacturer that the user is using. |
device_model |
Optional. String. The device model that the user is using. |
carrier |
Optional. String. The carrier that the user is using. |
country |
Optional. String. The current country of the user. |
region |
Optional. String. The current region of the user. |
city |
Optional. String. The current city of the user. |
dma |
Optional. String. The current Designated Market Area of the user. |
language |
Optional. String. The language set by the user. |
price |
Optional. Float. The price of the item purchased. Required for revenue data if the revenue field isn't sent. You can use negative values for refunds. |
quantity |
Optional. Integer. The quantity of the item purchased. Defaults to 1 if not specified. |
revenue |
Optional. Float. Revenue = (price * quantity). If you send all 3 fields of price, quantity, and revenue, then (price * quantity) is used as the revenue value. You can use negative values to identify refunds. |
productId |
Optional. String. An identifier for the item purchased. You must send a price and quantity or revenue with this field. |
revenueType |
Optional. String. The type of revenue for the item purchased. You must send a price and quantity or revenue with this field. |
location_lat |
Optional. Float. The current Latitude of the user. |
location_lng |
Optional. Float. The current Longitude of the user. |
ip |
Optional. String. The IP address of the user. Use "$remote" to use the IP address on the upload request. Amplitude uses the IP address to reverse lookup a user's location (city, country, region, and DMA). Amplitude can drop the location and IP address from events once it reaches Amplitude servers. You can submit a request to Amplitude Support to configure this for you. |
idfa |
Optional. String. (iOS) Identifier for Advertiser. |
idfv |
Optional. String. (iOS) Identifier for Vendor. |
adid |
Optional. String. (Android) Google Play Services advertising ID |
android_id |
Optional. String. (Android) Android ID (not the advertising ID) |
event_id |
Optional. Integer. An incrementing counter to distinguish events with the same user_id and timestamp from each other. Amplitude recommends that you send an event_id , increasing over time, especially if you expect events to occur simultaneously. |
session_id |
Optional. Long. The start time of the session in milliseconds since epoch (Unix Timestamp), necessary if you want to associate events with a particular system. A session_id of -1 is the same as no session_id specified. |
insert_id |
Optional. String. A unique identifier for the event. Amplitude deduplicates subsequent events sent with an insert_id that has been seen within the past 7 days. Amplitude recommends generating a UUID or using some combination of device_id , user_id , event_type , event_id , and time. |
plan |
Optional. Object. Tracking plan properties. Amplitude accepts only branch, source, version properties. |
plan.branch |
Optional. String. The tracking plan branch name. For example: "main" |
plan.source |
Optional. String. The tracking plan source. For example: "web" |
plan.version |
Optional. String. The tracking plan version. For example: "1", "15" |
These properties belong to the options
object.
Name |
Description |
---|---|
min_id_length |
Optional. Integer. Sets the minimum permitted length for user_id and device_id fields. Default is five. |
Status | Meaning | Description |
---|---|---|
200 | OK | Successful batch upload. |
400 | Bad Request | Invalid upload request. Read the error message to fix the request. |
413 | Payload Too Large | Payload size is too big (request size exceeds 20MB). Split your events array payload in half and try again. The limit per batch is 2000 events. |
429 | Too Many Requests | Too many requests for a user or device. Amplitude throttles requests for users and devices that exceed 1000 events per second or 500,000 events per day. |
1{2 "code": 200,3 "events_ingested": 50,4 "payload_size_bytes": 50,5 "server_upload_time": 13963813781236}
Name |
Description |
---|---|
code | Integer. 200 success code |
events_ingested | Integer. The number of events ingested from the upload request. |
payload_size_bytes | Integer. The size of the upload request payload in bytes. |
server_upload_time | Integer. The time in milliseconds since epoch (Unix Timestamp) that Amplitude's event servers accepted the upload request. |
1{ 2 "code": 400, 3 "error": "Request missing required field", 4 "missing_field": "api_key", 5 "events_with_invalid_fields": { 6 "time": [ 7 3, 8 4, 9 710 ]11 },12 "events_with_missing_fields": {13 "event_type": [14 3,15 4,16 717 ]18 }19}
Name |
Description |
---|---|
code |
400 error code. |
error |
String. Error description |
missing_field |
String. Indicates which request-level required field is missing. |
events_with_invalid_fields |
Object. A map from field names to an array of indexes into the events array indicating which events have invalid values for those fields |
events_with_missing_fields |
Object. A map from field names to an array of indexes into the events array indicating which events are missing those required fields |
1{ 2 "code": 400, 3 "eps_threshold": 100, 4 "error": "Events silenced for device_id", 5 "exceeded_daily_quota_devices": 6 {}, 7 "silenced_devices": 8 [ 9 "silenced_device_id_1",10 "silenced_device_id_2"11 ],12 "silenced_events":13 [14 5,15 616 ],17 "throttled_devices":18 {19 "throttled_device_id_1": 0,20 "throttled_device_id_2": 10021 },22 "throttled_events":23 [24 3,25 426 ]27}
Name |
Description |
---|---|
code |
400 error code |
error |
String. Error description. |
eps_threshold |
Integer. Your app's current events per second threshold. If you exceed this rate your requests will be throttled. |
exceeded_daily_quota_devices |
Integer. A map from device_id to its current number of daily events, for all devices that exceed the app's daily event quota. |
silenced_devices |
[string]. Array of device_ids that have been silenced by Amplitude. |
silenced_events |
[integer]. Array of indexes in the events array indicating events whose device_id got silenced. |
throttled_devices |
Object. A map from device_id to its current events per second rate, for all devices that exceed the app's current threshold. |
throttled_events |
[integer]. Array of indexes in the events array indicating events whose user_id and/or device_id got throttled |
1{2 "code": 413,3 "error": "Payload too large"4}
Name | Description |
---|---|
code |
Integer. 413 error code |
error |
String. Error description. |
1{ 2 "code": 429, 3 "error": "Too many requests for some devices and users", 4 "eps_threshold": 1000, 5 "throttled_devices": { 6 "C8F9E604-F01A-4BD9-95C6-8E5357DF265D": 4000 7 }, 8 "throttled_users": { 9 "datamonster@amplitude.com": 400010 },11 "exceeded_daily_quota_users": {12 "datanom@amplitude.com": 50020013 },14 "exceeded_daily_quota_devices": {15 "A1A1A000-F01A-4BD9-95C6-8E5357DF265D": 50090016 },17 "throttled_events": [18 3,19 4,20 721 ]22}
Name |
Description |
---|---|
code |
Integer. 429 error code |
error |
String. Error description. |
eps_threshold |
Integer. Your app's current events per second threshold. If you exceed this rate your requests are throttled. |
throttled_devices |
Object. A map from device_id to its current events per second rate, for all devices that exceed the app's current threshold. |
throttled_users |
Object. A map from user_id to their current events per second rate, for all users that exceed the app's current threshold |
throttled_events |
[integer]. Array of indexes in the events array indicating events whose user_id or device_id got throttled |
Amplitude rejects a request with a 429 status, it means that a device or user in that request was throttled. The error response has the details, so logging the response lets you investigate which users or devices were the cause of throttling.
Because device_id
and user_id
are the attributes that trigger throttling, partitioning work on one of these attributes helps isolate throttling to a specific partition of work. This way partitions which aren't being throttled can still make progress.
Amplitude measures the rate of events for each deviceID and each userID for a project. Amplitude calls these rates events per device second (EPDS) and events per user second (EPUS), respectively. These values are both averaged over a period of 30 seconds.
To reach an EPDS limit of 1000, a device must send 30,000 events in a 30-second period. This causes the device to be throttled and responds with a HTTP status 429.
In general, your app shouldn't measure EPDS or EPUS itself. Send requests to Amplitude as fast as possible. When you receive a 429, wait for a short period (for example, 15 seconds) before trying to send that request again.
In addition to the per-second limit, there is daily limit to prevent against spam and abuse. This limit is hard to exceed. Events starts counting toward the daily limit after Amplitude determines that a user/device is spamming the system. After a project reaches the limit, Amplitude enforces a daily limit of 500,000 events uploaded per rolling 24 hours. The 24 hour rolling period applies in one-hour intervals. The daily limit applies for each deviceID and each user_id
for a project.
The daily limit is independent of the EPDS/EPUS. After a user or device has hit the 500,000 event daily limit for a particular project, Amplitude rejects batches that contain the user or device ID. In those cases, the request returns a 429 response with a body indicating "exceeded_daily_quota_users" or "exceeded_daily_quota_devices" with list of deviceIDs and userIDs. Retry the batch when there are less than 500,000 events uploaded for a user or device in the previous 24 hour period.
Thanks for your feedback!
May 21st, 2024
Need help? Contact Support
Visit Amplitude.com
Have a look at the Amplitude Blog
Learn more at Amplitude Academy
© 2024 Amplitude, Inc. All rights reserved. Amplitude is a registered trademark of Amplitude, Inc.