On this page

Batch Event Upload API

Regions

The base URL depends on your project's data residency. In all examples on this page, use the default base URL unless your project uses Amplitude's EU data center—in that case use the EU base URL in this table.

This API uses the event ingestion host api2.amplitude.com (default) or api.eu.amplitude.com (EU). Other Amplitude APIs use different hostnames (for example api.amplitude.com, core.amplitude.com, data-api.amplitude.com, or experiment.amplitude.com). The https://analytics.amplitude.com hostname is the Analytics web app (browser UI), not an ingestion endpoint.

Limits and considerations

Rate limiting

Amplitude rate limits individual users (by Amplitude ID) that update their user properties more than 1,800 times per hour. This limit applies to user property syncing, not event ingestion. Amplitude continues to ingest events, but may drop user property updates for that user.

  • The JSON serialized payload must not exceed 20MB in size.
  • Device IDs and user IDs must be strings of 5 characters or more. If an event has an ID that's too short, the ID value is dropped from the event. If an event has no user or device ID, the API may reject the upload with a 400 error. You can change the minimum ID length using the options property.
  • Each API key can send up to 1000 events per second for any individual device ID or user ID. If you exceed that rate, the API rejects the upload and returns a 429 response. Check the response summary for more information.

Request

The Batch Event Upload API request differs from the HTTP API in two ways:

  • Content-type must be application/json.
  • The key for the events payload is events plural, not event singular.
curl
# You can also use wget
curl -X POST https://api2.amplitude.com/batch \
  -H 'Content-Type: application/json' \
  -H 'Accept: */*'

Body

These properties belong to the request's body.

json
{
  "api_key": "my_amplitude_api_key",
  "events": [
    {
      "user_id": "datamonster@gmail.com",
      "device_id": "C8F9E604-F01A-4BD9-95C6-8E5357DF265D",
      "event_type": "watch_tutorial",
      "time": 1396381378123,
      "event_properties": {
        "load_time": 0.8371,
        "source": "notification",
        "dates": ["monday", "tuesday"]
      },
      "user_properties": {
        "age": 25,
        "gender": "female",
        "interests": ["chess", "football", "music"]
      },
      "groups": {
        "team_id": "1",
        "company_name": ["Amplitude", "DataMonster"]
      },
      "app_version": "2.1.3",
      "platform": "iOS",
      "os_name": "Android",
      "os_version": "4.2.2",
      "device_brand": "Verizon",
      "device_manufacturer": "Apple",
      "device_model": "iPhone 9,1",
      "carrier": "Verizon",
      "country": "United States",
      "region": "California",
      "city": "San Francisco",
      "dma": "San Francisco-Oakland-San Jose, CA",
      "language": "English",
      "price": 4.99,
      "quantity": 3,
      "revenue": -1.99,
      "productId": "Google Pay Store Product Id",
      "revenueType": "Refund",
      "location_lat": 37.77,
      "location_lng": -122.39,
      "ip": "127.0.0.1",
      "idfa": "AEBE52E7-03EE-455A-B3C4-E57283966239",
      "idfv": "BCCE52E7-03EE-321A-B3D4-E57123966239",
      "adid": "AEBE52E7-03EE-455A-B3C4-E57283966239",
      "android_id": "BCCE52E7-03EE-321A-B3D4-E57123966239",
      "event_id": 23,
      "session_id": 1396381378123,
      "insert_id": "5f0adeff-6668-4427-8d02-57d803a2b841"
    }
  ]
}

Event

These properties belong to the events object.

  • user_id
    • Description:
      • Required. String. A readable ID specified by you. Must have a minimum length of 5 characters.
      • Required unless device_id is present.
  • device_id
    • Description: 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
    • Description:
      • Required. String. A unique identifier for your event.
      • Note that $identify and $groupidentify are predefined for identification and group identification. For more information about these two operations, refer to the descriptions of user_properties and group_properties.
  • time
    • Description: 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
    • Description: Optional. Object. A dictionary of key-value pairs that represent properties sent with the event. Property values can be stored in an array. Date values are transformed into string values. Object depth may not exceed 40 layers.
  • user_properties
    • Description: Optional. Object. A dictionary of key-value pairs that represent data tied to the user. Property values can be stored 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
    • Description: Optional. Object. Available only to customers who 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 that you can track up to 5 unique group types and 10 total groups. Amplitude doesn't track any groups past that threshold.
  • group_properties
    • Description: Optional. Object. Available only to customers who 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
    • Description: Optional. Boolean. When true user properties aren't synced. Defaults to false.
  • app_version
    • Description: Optional. String. The current version of your application.
  • platform
    • Description: Optional. String. Platform of the device.
  • os_name
    • Description: Optional. String. The name of the mobile operating system or browser that the user is using.
  • os_version
    • Description: Optional. String. The version of the mobile operating system or browser the user is using.
  • device_brand
    • Description: Optional. String. The device brand that the user is using.
  • device_manufacturer
    • Description: Optional. String. The device manufacturer that the user is using.
  • device_model
    • Description: Optional. String. The device model that the user is using.
  • carrier
    • Description: Optional. String. The carrier that the user is using.
  • country
    • Description: Optional. String. The current country of the user.
  • region
    • Description: Optional. String. The current region of the user.
  • city
    • Description: Optional. String. The current city of the user.
  • dma
    • Description: Optional. String. The current Designated Market Area of the user.
  • language
    • Description: Optional. String. The language set by the user.
  • price
    • Description: 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
    • Description: Optional. Integer. The quantity of the item purchased. Defaults to 1 if not specified.
  • revenue
    • Description: Optional. Float. Revenue = (price * quantity). If you send all three fields (price, quantity, and revenue), Amplitude uses (price * quantity) as the revenue value. You can use negative values to identify refunds.
  • productId
    • Description: Optional. String. An identifier for the item purchased. You must send a price and quantity or revenue with this field.
  • revenueType
    • Description: Optional. String. The type of revenue for the item purchased. You must send a price and quantity or revenue with this field.
  • currency
    • Description: Optional. String. The currency for the purchased item, specified as a 3-character uppercase ISO 4217 code (for example, USD, EUR).
  • location_lat
    • Description: Optional. Float. The current Latitude of the user.
  • location_lng
    • Description: Optional. Float. The current Longitude of the user.
  • ip
    • Description: 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 after they reach Amplitude servers. You can submit a request to Amplitude Support to configure this for you.
  • idfa
    • Description: Optional. String. (iOS) Identifier for Advertiser.
  • idfv
    • Description: Optional. String. (iOS) Identifier for Vendor.
  • adid
    • Description: Optional. String. (Android) Google Play Services advertising ID
  • android_id
    • Description: Optional. String. (Android) Android ID (not the advertising ID)
  • event_id
    • Description: Optional. Integer. An incrementing counter to distinguish events with the same user_id and timestamp from each other. Amplitude recommends sending an event_id that increases over time, especially if you expect events to occur simultaneously.
  • session_id
    • Description: Optional. Long. The start time of the session in milliseconds since epoch (Unix Timestamp), needed to associate events with a particular system. A session_id of -1 is the same as no session_id specified.
  • insert_id
    • Description: Optional. String. A unique identifier for the event. Amplitude deduplicates subsequent events sent with an insert_id seen within the past 7 days. Amplitude recommends generating a UUID or using a combination of device_id, user_id, event_type, event_id, and time.
  • plan
    • Description: Optional. Object. Tracking plan properties. Amplitude accepts only branch, source, version properties.
  • plan.branch
    • Description: Optional. String. The tracking plan branch name. For example: "main"
  • plan.source
    • Description: Optional. String. The tracking plan source. For example: "web"
  • plan.version
    • Description: Optional. String. The tracking plan version. For example: "1", "15"

Options

These properties belong to the options object.

Responses

SuccessSummary

json
{
  "code": 200,
  "events_ingested": 50,
  "payload_size_bytes": 50,
  "server_upload_time": 1396381378123
}

InvalidRequestError

json
{
  "code": 400,
  "error": "Request missing required field",
  "missing_field": "api_key",
  "events_with_invalid_fields": {
    "time": [3, 4, 7]
  },
  "events_with_missing_fields": {
    "event_type": [3, 4, 7]
  }
}

SilencedDeviceID

json
{
  "code": 400,
  "eps_threshold": 100,
  "error": "Events silenced for device_id",
  "exceeded_daily_quota_devices": {},
  "silenced_devices": ["silenced_device_id_1", "silenced_device_id_2"],
  "silenced_events": [5, 6],
  "throttled_devices": {
    "throttled_device_id_1": 0,
    "throttled_device_id_2": 100
  },
  "throttled_events": [3, 4]
}

PayloadTooLargeError

json
{
  "code": 413,
  "error": "Payload too large"
}

TooManyRequestsForDeviceError

json
{
  "code": 429,
  "error": "Too many requests for some devices and users",
  "eps_threshold": 1000,
  "throttled_devices": {
    "C8F9E604-F01A-4BD9-95C6-8E5357DF265D": 4000
  },
  "throttled_users": {
    "datamonster@amplitude.com": 4000
  },
  "exceeded_daily_quota_users": {
    "datanom@amplitude.com": 500200
  },
  "exceeded_daily_quota_devices": {
    "A1A1A000-F01A-4BD9-95C6-8E5357DF265D": 500900
  },
  "throttled_events": [3, 4, 7]
}

Code 429 explained

When Amplitude rejects a request with a 429 status, 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 caused the 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. Partitions that aren't throttled can still make progress.

EPDS and EPUS

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. Both values are 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. The device is throttled and the API responds with 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.

Daily limit

In addition to the per-second limit, a daily limit prevents spam and abuse. This limit is hard to exceed. Events start counting toward the daily limit after Amplitude determines that a user or 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 EPDS and EPUS. After a user or device hits the 500,000 event daily limit for a 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 a list of deviceIDs and userIDs. Retry the batch when fewer than 500,000 events were uploaded for the user or device in the previous 24-hour period.

Was this helpful?