Error envelope
{
"error": {
"code": "asset_not_found",
"message": "No asset with id 42 for this shop",
"status": 404,
"request_id": "req_..."
}
}
Include the request id when contacting support.
Common error codes
| HTTP | Code | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed JSON or missing field. |
| 400 | idempotency_key_required | Write request missing Idempotency-Key. |
| 401 | unauthorized | Missing, invalid, unknown, or revoked token. |
| 402 | plan_required | The shop is on the Free plan. The external API requires a paid plan. For a product update notification it also means the shop's subscription is not active, and a campaign stopped for either reason after it was queued reports error: plan_required on GET /notifications/{id}. |
| 403 | forbidden | The external API is switched off (the global kill switch), the API key is missing a scope the request needs, or, on the product update notification routes, Alva has switched those notifications off as an emergency brake. Contact us if a correctly scoped key gets it. |
| 403 | notifications_suspended | Product update notifications are suspended for this shop after spam complaints on earlier campaigns. No retry helps — contact support. |
| 404 | asset_not_found, mapping_not_found, order_not_found, category_not_found, job_not_found | The resource is missing or belongs to another shop. |
| 404 | notification_not_found | The product update notification is missing or belongs to another shop. |
| 409 | idempotency_conflict | The same key was reused with a different request. |
| 409 | stamping_in_progress | Resend is blocked while PDF stamping is pending. |
| 409 | delivery_not_yet_released | The product has a download delivery delay configured and the buyer's files have not unlocked yet. error.details.release_at is the ISO 8601 instant they unlock; the merchant can release the order early with the grant-downloads endpoint. |
| 409 | notification_not_cancellable | Only a queued product update notification can be cancelled. This one has already started sending, finished, failed or was cancelled — error.details.status says which. |
| 409 | app_not_installed | Alva has no active Shopify session for the shop, usually because the app was uninstalled, so a request that needs Shopify cannot run — a mapping write, or a product update notification whose note names a metafield or that sends variant_ids. Open or reinstall the app in the Shopify admin, then retry. |
| 409 | multiple_mappings_match | A Shopify id matches more than one mapping, so Alva cannot tell which one you mean. On POST /products/{id}/notifications, error.details.ambiguous_variant_ids lists the requested variants that more than one mapping serves. |
| 409 | personalized_product | The product is personalized. Personalization is set for the whole product, so POST /mappings with shopify_variant_ids cannot add a variant-specific mapping to it (nothing is written), and POST /products/{id}/notifications cannot notify its buyers, because each order has its own file. |
| 422 | storage_quota_exceeded | The upload or import would exceed storage quota. |
| 422 | key_limit_reached | The shop already holds the maximum of 25 active API keys; revoke one first. |
| 422 | withdrawal_consent_required | The shop has EU withdrawal-right consent enabled and the order has no consent record yet; download URLs are issued once the customer consents. |
| 422 | email_disabled | Customer emails are turned off in the app's email settings. Returned by an order email resend, by POST /orders/{id}/assignments with send_email: true (nothing is created), by POST /products/{id}/notifications, and as the notify_customers outcome on a mapping write (the mapping itself is still saved). Turn them on, then retry. |
| 422 | invalid_message | The product update note broke a rule: blank, too long (also once its variables are filled in), an unknown or unclosed variable, more than five different metafields, a link or email address (also inside a metafield value), or a metafield that is missing, too long or of a type that cannot be shown in an email. error.details.errors[] names each rule; error.details.max_length is the cap (2,000). Nothing was sent or written. On a mapping write with notify_customers, only the rules about the note's own text refuse the write; a metafield problem is reported in data.notification after the mapping is saved. |
| 422 | no_downloadable_content | No targeted mapping has files, packs or links to announce; keys-only and personalized mappings cannot be the subject of a product update. With variant_ids, when the product has another mapping that could be notified, error.details.mapping_ids names the mappings those variants resolved to. |
| 422 | no_eligible_recipients | Nobody to email: no buyer of the targeted mappings is opted in. error.details.opted_out_count says how many have opted out. A brand-new mapping has no buyers yet. |
| 429 | rate_limited | The API key or order resend limit was reached. |
| 429 | notification_cooldown | One product update notification per product per 7 days, across all of its variants and every source — or a campaign for the product is still queued or sending. This is not the token bucket: Retry-After can be up to seven days and error.details.next_available_at is the instant the product is free again. Do not retry automatically — schedule the next call at next_available_at. Cancelling a campaign does not reset the limit; use dry_run to check a note before sending. |
| 429 | too_many_active_notifications | The shop already has 5 product update notifications queued or sending, across every product and source. error.details.limit is the cap and error.details.active_notification_ids lists those campaigns, oldest first. There is no Retry-After: poll GET /notifications/{id} for one of them and retry once it has finished. A dry run is refused the same way; on a mapping write it is reported in data.notification instead. |
| 500 | internal_error | Unexpected server error. On POST /products/{id}/notifications every 500 releases the Idempotency-Key, so retry the same request with the same key. Three cases there are expected: Shopify could not return the product's metafields for the note, Shopify could not confirm the requested variant_ids, or the create waited more than 8 seconds behind the shop's other creates. If the failed attempt did queue the campaign after all, the retry is refused with 429 notification_cooldown instead of starting a second one. |
API docs
Was this helpful?
Last updated 2026-10-20