Skip to main content

About App Events

App Events let you send information about what's happening in your app to Shopify. When something meaningful occurs in your app, like a merchant starting and completing onboarding, or an SMS is sent that could be billed for, you can send that event to Shopify.

You can send events in two ways:

  • From your app backend: Send events to the App Events API. Use this method for billing events and custom events.
  • From UI extensions: Checkout and Customer Account UI extensions that set api_version = "2027-01" or later in shopify.extension.toml can send custom events and declared standard events with shopify.appEvents.emit(). The extension doesn't need network access or an access token. Learn more about sending events from UI extensions.

Events from both methods appear in the Dev Dashboard. Every event is tied to a specific shop, giving you per-merchant visibility into how your app is being used.

Billing events must first be configured in usage-based billing and are then validated and added as a charge to a merchant's invoice.

To make app activity available to merchants in Shopify Analytics, declare standard or custom events in your app's Analytics App Events configuration. You can define custom attributes and metrics to describe and summarize that activity.


App events give you a centralized view in the Dev Dashboard to help you understand your whole app business:

  • Centralized logging: View all your app's events in one place alongside webhook and function logs in the Dev Dashboard.
  • Power usage-based pricing: Report billing events that feed into Shopify App Pricing to calculate usage-based charges.
  • Send custom events: See how merchants interact with your app, track errors and failures, and identify friction points to improve the quality and reliability of your app.
  • Merchant-facing analytics: Make standard and custom app events available to merchants in Shopify Analytics.

You can send the following types of events to Shopify:

Billing events are tied to your usage-based subscriptions. Once you configure your pricing and send a billing event, Shopify uses it to calculate usage-based charges for the merchant. Examples include:

  • Messages sent: SMS notifications, emails, or push notifications sent on behalf of a merchant.
  • Orders processed: Orders recovered, fulfilled, or synced through your app.
  • AI generations: AI tokens, image generations, or content created.
  • Premium features used: Advanced reports generated, exports created, or premium tools accessed.

Learn more about usage-based subscriptions.

Custom events let you track anything else that's meaningful for your app. Use them to understand merchant behavior, monitor operational health, or debug issues. Here are some examples:

Business events

  • A merchant completed your app's onboarding flow.
  • A merchant activated or deactivated a feature.
  • A merchant created, updated, or deleted a resource in your app (campaigns, rules, templates).
  • A merchant completed a bulk operation or workflow.

Operational events

  • A data sync failed for a merchant.
  • A connection to a third-party service timed out.
  • A background job completed or failed.
  • Your app encountered a rate limit or API error.

Other events

  • A merchant viewed a specific page or dashboard in your app.
  • A merchant exported data or generated a report.
  • A scheduled task ran for a merchant.

Custom events are for monitoring in the Dev Dashboard and don't need a declaration. To make a custom event available in Shopify Analytics, declare it in your Analytics App Events configuration.

Standard events are Shopify-defined activities with shared attributes and metrics. For example, marketing apps can report shopify.marketing.email_sent, and merchants can compare the emails_sent metric by app.

Choose an event from the standard event registry, declare its full handle in your Analytics App Events configuration, and use the same handle in API requests. Shopify supplies the standard fields. You can add custom attributes and metrics without changing those definitions.

Caution

Don't include any data in attributes that, alone or in combination with other data, could identify an individual. This includes names, email addresses, phone numbers, and customer IDs.


Sending app events follows a straightforward flow:

  1. Your app sends one event per request to the App Events API endpoint (batch requests aren't supported):

    https://api.shopify.com/app/{API_VERSION}/events
  2. Shopify ingests and stores the events. Events are retained for 30 days.

  3. Events appear in the Dev Dashboard under Logs, where you can filter, search, and analyze them.

  4. For billing events, Shopify aggregates usage and calculates charges based on your pricing structure. You must first set up usage-based pricing in the app submission form before Shopify can process billing events.

If an event matches a released Analytics App Events declaration, then Shopify also processes it for Shopify Analytics, where merchants can query it with ShopifyQL through FROM app_events. Analytics processing is asynchronous, so a 202 Accepted response doesn't confirm that the event is available in Shopify Analytics.


Anchor to Send events from UI extensionsSend events from UI extensions

Checkout and Customer Account UI extensions that set api_version = "2027-01" or later in shopify.extension.toml can send custom events and declared standard events with shopify.appEvents.emit(). The extension doesn't need network access, an access token, or a shop ID. Shopify adds your app and the shop to each event. Events don't identify the extension that sent them.

shopify.appEvents.emit("offer_viewed", {
offer_id: "summer_bundle",
placement: "order_summary",
});

Events from UI extensions appear in the Dev Dashboard under Logs, together with the events that your app sends through the App Events API. The host sends each event only when the buyer has allowed analytics processing.

Events from UI extensions aren't processed for billing. To report usage for Shopify App Pricing, send a billing event from your app backend through the App Events API.

If the event handle matches a released Analytics App Events declaration, then Shopify also processes the event for Shopify Analytics.

For parameters, return values, consent behavior, and rate limits, refer to Send events from Checkout UI extensions and Send events from Customer Account UI extensions.


Before you start sending events, make sure you have the following:

  • An authenticated Shopify app with a valid access token
  • Your app's client ID (available in the Dev Dashboard under your app's App settings)
  • To use App Events in Analytics, a released analytics_app_events configuration in your app's shopify.extension.toml

All App Events API requests require a valid bearer token.

API keys created in the Dev Dashboard provide a client ID and secret that can be used to generate a JWT token.

POST

https://api.shopify.com/auth/access_token

curl --request POST \
--url https://api.shopify.com/auth/access_token \
--header 'Content-Type: application/json' \
--data '{
"client_id": "{your_client_id}",
"client_secret": "{your_client_secret}",
"grant_type": "client_credentials"
}'

The response will contain:

  • access_token: A JWT access token that can be used to interact with the App Events API.
  • token_type: The type of the access token. This is always Bearer.

{} Response

{
"access_token": "f8563253df0bf277ec9ac6f649fc3f17",
"token_type": "Bearer"
}

If a request returns a 403 response with the message You do not have permission to access this website, then make sure the request includes a User-Agent header.

Include your token as a Authorization: Bearer {token} header on all API requests. Access tokens expire after 60 minutes. You can use a JWT decoder tool like jwt.io to investigate more details related to how Shopify issues this token. Request a new token before the current one expires.


FieldDescription
shop_idThe shop ID as a numeric string ("23423423") or GID ("gid://shopify/Shop/23423423").
event_handleThe event name, such as onboarding_completed for a monitoring event. For Analytics, use the exact declared name, such as shopify.marketing.email_sent or example-app.workflow_completed. The shopify. prefix is reserved for standard events. For billing, use the meter handle from your pricing configuration.
timestampThe ISO 8601 timestamp when the event occurred.
idempotency_keyA unique key to prevent duplicate events. Maximum 64 characters. The API enforces a 24-hour idempotency window. For billing events, idempotency is enforced permanently.
attributesA required JSON object containing the event data. For billing events, must include a non-zero value field specifying the quantity to add to the meter (use a negative value to reverse reported usage). For Analytics events, use attributes that match the declared schema. For monitoring events, include key/value pairs that help you troubleshoot.
POST

https://api.shopify.com/app/unstable/events

curl -X POST \
'https://api.shopify.com/app/unstable/events' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer {BEARER_TOKEN}' \
-d '{
"shop_id": "gid://shopify/Shop/23423423",
"event_handle": "sms_sent",
"timestamp": "2026-01-27T14:30:00Z",
"idempotency_key": "evt_55667788",
"attributes": {
"value": 1
}
}'

Anchor to View events in the Dev DashboardView events in the Dev Dashboard

After sending events, you can view and analyze them in the Dev Dashboard. Events are retained for 30 days.

  1. Open the Dev Dashboard and click the app you want to monitor.
  2. Navigate to Logs for detailed event records. Set the Type filter to App Event to see the event volume graph for aggregated data.

Anchor to Filter events in logsFilter events in logs

In the Logs view, all events sent through the App Events API appear alongside your functions and webhooks. Use the Type filter to narrow down what you see:

  • App Event: Shows all events sent to the App Events API, including standard, custom, and billing events.
  • App Billing Event: Shows only events that have been processed by Shopify App Pricing as usage-based billing events.

You can also filter by time range, status, and shop to investigate specific issues.

Info

The App Events API always returns a 202 response when it receives your request, even if the event fails billing validation. There's no synchronous billing error response and no webhooks for billing validation failures. The Dev Dashboard is the only place to see billing errors. Go to Logs and filter by App Billing Event to check for failures.

Anchor to Troubleshooting with eventsTroubleshooting with events

  • Investigate errors: Filter by a merchant's shop domain, then look for events with error-related handles (for example, http_error or job_failure). Inspect the event metadata for details like status codes and error messages.
  • Monitor after deployments: Set the time range to the last day and watch for increases in error rates or unusual changes in event volume.
  • Track feature adoption: Filter by event types related to a specific feature to see adoption trends over time.

  • Be consistent with event types: Use a naming convention for your event_handle values (for example, snake_case) so they're easy to filter and search in the Dev Dashboard.
  • Include accurate timestamps: Always set timestamp to the time the event actually happened in your app, not the time you sent it to Shopify. This keeps your logs and monitoring data accurate even if events are batched or delayed.
  • Keep metadata structured: Include relevant context in your event attributes so you can filter and troubleshoot effectively without needing to cross-reference other systems.
  • Separate behavioral and troubleshooting events: Use distinct event_handle values for behavioral tracking versus error monitoring. This makes it easier to set up focused views in the dashboard.
  • Use unique idempotency keys: Always include a unique idempotency_key to prevent duplicate events if you need to retry a request.
  • Test in development: Use a development store to verify your events work correctly before going live.
  • Use standard events accurately for analytics: Only use a standard event when your app's activity matches the event definition, and include all attributes that the standard event registry requires.

The App Events API has a rate limit of 500 requests per second per app. If you exceed this limit, requests are throttled and return a 429 Too Many Requests response.

To stay within limits:

  • Implement exponential backoff when you receive 429 responses.
  • Queue events in your app and send them sequentially rather than all at once. Each request sends a single event. Batch requests aren't supported.

Common error responses from the App Events API:

Status codeDescription
202 AcceptedThe event was received successfully.
401 UnauthorizedYour access token is missing or invalid.
429 Too Many RequestsYou've exceeded the rate limit. Retry with exponential backoff.
5xxAn internal Shopify error. Check the Shopify status page for more information.

For a complete list, refer to the API status response and error codes.


By using the App Events API, you agree to the App Events API Terms of Service. Don't submit personal information such as names, email addresses, or any data that identifies a natural person.



Was this page helpful?