Skip to main content

Create an event

Send billing events or custom events to Shopify.

Use this endpoint to report usage for billing meters or track custom events for monitoring in the Dev Dashboard.


This endpoint lets you send events happening in your app to Shopify. All events are visible in the Dev Dashboard. Events sent to this API as part of Shopify App Pricing are processed for billing to merchants.


shop_id•stringRequired

The ID of the merchant's shop that the event is associated with. For example, gid://shopify/Shop/23423423 or 23423423. Both a Shopify GID and a numeric shop ID (as a string) are accepted.


event_handle•stringRequired

The name of the event. For billing events, this must match a meter handle defined in your pricing configuration. For custom events, use a descriptive name (for example, onboarding_completed, sync_failed).


timestamp•stringRequired

The ISO 8601 timestamp of when the event occurred in your app. The timestamp can't be more than 5 minutes in the future. Billing events outside the current cycle reject with RESULT_STATUS_FAILURE and a result_details message with details about the allowable window.


idempotency_key•stringRequired

An app-generated unique key to prevent duplicate events. Maximum 64 characters. The API enforces a 24-hour idempotency window — requests with a previously seen key within that window return the original response. For billing events, idempotency is enforced permanently.


attributes•objectRequired

A JSON object of key/value pairs containing the event data. For billing events, the value field is required and must be greater than 0. It specifies the quantity to add to the meter. Don't include any data that, alone or in combination with other data, could identify an individual. The attributes object has the following restrictions:

  • Maximum 15 keys in the attributes object
  • Keys are limited to 64 characters and can only contain alphanumeric ASCII characters, underscores (_), periods (.), and hyphens (-)
  • String values are limited to 128 characters (UTF-8)
  • Only scalar values are allowed (strings, numbers, booleans). Arrays and nested objects aren't supported.

Info

The only difference between a custom event and a billing event is whether the event_handle matches a meter handle in your pricing configuration. The API call is identical — Shopify determines how to process the event based on your app's pricing setup.

Info

The App Events API always returns a 202 response when it receives your request, even if the event fails billing validation. There is no synchronous billing error response and no webhooks for billing validation failures. To verify that your billing events are being processed correctly, go to the Dev Dashboard, navigate to Logs, and select App Billing Event filter under Type.

Info

After a merchant uninstalls your app, you have 24 hours to submit any remaining billing events for usage that occurred before the uninstall. After 24 hours, the billing period for that merchant is closed and new events reject with RESULT_STATUS_FAILURE and a result_details message with details about the allowable window.

Send a billing event to increment a pricing meter.

Billing events require an event_handle that matches a meter handle in your pricing configuration. The attributes.value field specifies the quantity to add to the meter and must be greater than 0.

Send custom events to monitor app behavior in the Dev Dashboard.

Custom Events let you track feature usage, error patterns, and merchant onboarding. Include any relevant data in the attributes field.


The Create an event endpoint accepts a single event per request — batch requests aren't supported. To report multiple events, send a separate request for each one.

Represents an event sent to Shopify, used for either billing or monitoring purposes.


shop_id•stringRequired

The ID of the merchant's shop that the event is associated with. For example, gid://shopify/Shop/23423423 or 23423423. Both a Shopify GID and a numeric shop ID (as a string) are accepted.


event_handle•stringRequired

The name of the event. For billing events, this must match a meter handle defined in your pricing configuration. For custom events, use a descriptive name (for example, onboarding_completed, sync_failed).


timestamp•stringRequired

The ISO 8601 timestamp of when the event occurred in your app. The timestamp can't be more than 5 minutes in the future. Billing events outside the current cycle reject with RESULT_STATUS_FAILURE and a result_details message with details about the allowable window.


idempotency_key•stringRequired

An app-generated unique key to prevent duplicate events. Maximum 64 characters. The API enforces a 24-hour idempotency window — requests with a previously seen key within that window return the original response. For billing events, idempotency is enforced permanently.


attributes•objectRequired

A JSON object of key/value pairs containing the event data. For billing events, the value field is required and must be greater than 0. It specifies the quantity to add to the meter. Don't include any data that, alone or in combination with other data, could identify an individual. The attributes object has the following restrictions:

  • Maximum 15 keys in the attributes object
  • Keys are limited to 64 characters and can only contain alphanumeric ASCII characters, underscores (_), periods (.), and hyphens (-)
  • String values are limited to 128 characters (UTF-8)
  • Only scalar values are allowed (strings, numbers, booleans). Arrays and nested objects aren't supported.


When a request is rejected, the API returns a non-2xx status code with a JSON body containing success: false, a top-level error message, and an errors array with field-level detail:

{
"success": false,
"error": "Invalid request",
"errors": [
{
"field": "shop_id",
"code": "missing",
"message": "is missing"
}
]
}

Each entry in errors includes:

FieldDescription
fieldThe request field that failed validation, or null for request-level errors.
codeA machine-readable error code such as missing, invalid, invalid_type, or not_installed.
messageA human-readable description of the error.

The App Events API has a rate limit of 500 requests per second per app. After the limit is exceeded, all requests are throttled.


Was this page helpful?