Skip to main content
- Error handling

API errors

Every API failure returns a JSON error envelope with a stable code, HTTP status, message, and request id for support.

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

HTTPCodeMeaning
400invalid_requestMalformed JSON or missing field.
400idempotency_key_requiredWrite request missing Idempotency-Key.
401unauthorizedMissing, invalid, unknown, or revoked token.
402plan_requiredThe 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}.
403forbiddenThe 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.
403notifications_suspendedProduct update notifications are suspended for this shop after spam complaints on earlier campaigns. No retry helps — contact support.
404asset_not_found, mapping_not_found, order_not_found, category_not_found, job_not_foundThe resource is missing or belongs to another shop.
404notification_not_foundThe product update notification is missing or belongs to another shop.
409idempotency_conflictThe same key was reused with a different request.
409stamping_in_progressResend is blocked while PDF stamping is pending.
409delivery_not_yet_releasedThe 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.
409notification_not_cancellableOnly a queued product update notification can be cancelled. This one has already started sending, finished, failed or was cancelled — error.details.status says which.
409app_not_installedAlva 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.
409multiple_mappings_matchA 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.
409personalized_productThe 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.
422storage_quota_exceededThe upload or import would exceed storage quota.
422key_limit_reachedThe shop already holds the maximum of 25 active API keys; revoke one first.
422withdrawal_consent_requiredThe shop has EU withdrawal-right consent enabled and the order has no consent record yet; download URLs are issued once the customer consents.
422email_disabledCustomer 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.
422invalid_messageThe 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.
422no_downloadable_contentNo 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.
422no_eligible_recipientsNobody 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.
429rate_limitedThe API key or order resend limit was reached.
429notification_cooldownOne 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.
429too_many_active_notificationsThe 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.
500internal_errorUnexpected 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?

Still stuck? Email admin@alvaapps.com.

Last updated 2026-10-20