Assets
| Methode | Pad | Doel |
|---|---|---|
| POST | /assets | Een externe URL als asset importeren. |
| POST | /assets/uploads | Een directe upload starten. |
| POST | /assets/uploads/{uploadId}/complete | Een directe upload afronden. |
| GET | /assets | Assets weergeven. |
| GET/PATCH/DELETE | /assets/{id} | Een asset lezen, bijwerken of verwijderen. |
Categorieën, koppelingen, packs, links en tags
| Methode | Pad | Doel |
|---|---|---|
| GET/POST | /categories | Platte categorieën weergeven of aanmaken. |
| GET/PATCH/DELETE | /categories/{id} | Een categorie lezen, hernoemen of verwijderen. |
| GET/POST | /mappings | Shopify-productkoppelingen weergeven of upserten. |
| GET/PUT/DELETE | /mappings/{id} | Een koppeling lezen, vervangen of verwijderen. |
| GET/POST | /packs | Packs weergeven of aanmaken. |
| GET/DELETE | /packs/{id} | Een pack lezen of verwijderen. |
| GET/POST | /links | Links weergeven of aanmaken. Aanmaken vereist een betaald abonnement; bezoeklimieten en vervaldatum blijven alleen via de admin. |
| GET/POST | /license-key-tags | Licentiecode-tags weergeven of aanmaken. |
POST /mappings en PUT /mappings/{id} accepteren een optioneel object notify_customers ({}, of { "message": "…", "variant_ids": [ … ] }). Nadat de schrijfactie is gecommit, zet Alva een productupdatemelding in de wachtrij voor de kopers van de koppeling die je hebt geschreven — dezelfde campagne als POST /products/{shopify_product_id}/notifications hieronder, met dezelfde notitieregels en dezelfde 7-dagenlimiet per product. Alleen de controles op de eigen tekst van de notitie worden vóór de schrijfactie uitgevoerd: een notitie die leeg of te lang is, een onbekende of misvormde variabele gebruikt, meer dan vijf metavelden noemt of een link in de tekst heeft, is 422 invalid_message en er wordt niets geschreven. Elke andere weigering wordt in de response gerapporteerd als data.notification met created: false en een error-code — nooit als een 4xx, dus de schrijfactie op de koppeling zelf slaagt gewoon. Daaronder vallen een probleem met een metaveld (invalid_message met errors[]: een metaveld dat ontbreekt, een niet-ondersteund type heeft, te lang is of een link bevat, of een notitie die te lang is zodra de variabelen zijn ingevuld), notification_cooldown met next_available_at, too_many_active_notifications met limit en active_notification_ids, no_eligible_recipients, email_disabled, en archive_not_queued wanneer de bestandsopbouw niet in de wachtrij kon worden gezet. Een gloednieuwe koppeling heeft nog geen kopers en rapporteert no_eligible_recipients. data.notification is alleen aanwezig wanneer je de vlag hebt meegestuurd. De vlag voegt geen ratelimit-kosten toe: de schrijfbewerking voor de koppeling kost de gebruikelijke 2 tokens. Dezelfde Idempotency-Key opnieuw afspelen geeft de opgeslagen response terug zonder tweede campagne; om alleen de melding opnieuw te proberen, roep je POST /products/{shopify_product_id}/notifications aan met een nieuwe sleutel en variant_ids met de varianten van de geschreven koppeling, of met dezelfde variant_ids die de vlag had. Zonder variant_ids stelt dat endpoint de kopers van alle koppelingen van het product op de hoogte, niet alleen die van de koppeling die je hebt geschreven.
Eén vlag per product, niet één per variant. De vlag mailt alleen de kopers van de koppeling die je hebt geschreven, maar gebruikt de 7-dagenlimiet van het hele product. Schrijf je de variantkoppelingen van een product één voor één met de vlag op elke schrijfactie, dan houdt de eerste campagne de 7 dagen van het product vast, zodat de andere notification_cooldown rapporteren. Zet de vlag in plaats daarvan op één schrijfactie, de laatste, zodat de campagne ook wacht op de opbouw die de eerdere schrijfacties in de wachtrij hebben gezet. Noem in variant_ids elke variant waarvan de kopers ervan moeten horen, ook die van de geschreven koppeling zelf: variant_ids vervangt het standaardbereik in plaats van eraan toe te voegen.
Bestellingen en toegang
| Methode | Pad | Doel |
|---|---|---|
| GET | /orders/{shopify_order_id} | De downloadstatus van een bestelling lezen. |
| GET/POST | /orders/{shopify_order_id}/assignments | Toewijzingen op productniveau weergeven of aanmaken. |
| GET | /orders/{shopify_order_id}/assignments/{purchaseId}/download-urls | Download-URL's aanmaken. |
| POST | /orders/{shopify_order_id}/revoke | Toegang uitschakelen. |
| POST | /orders/{shopify_order_id}/restore | Toegang herstellen. |
| POST | /orders/{shopify_order_id}/grant-downloads | Extra downloads toekennen. |
| POST | /orders/{shopify_order_id}/resend | De leverings-e-mail opnieuw versturen. |
Het download-urls-endpoint retourneert 422 withdrawal_consent_required wanneer de shop EU-herroepingstoestemming heeft ingeschakeld en de bestelling nog geen toestemmingsregistratie heeft; download-URL's worden uitgegeven zodra de klant toestemming geeft.
De endpoints download-urls en resend retourneren 409 delivery_not_yet_released wanneer voor het product een vertraging van de downloadlevering is ingesteld en de bestanden van de koper nog niet zijn vrijgegeven. De waarde error.details.release_at is het ISO 8601-moment van vrijgave en het grant-downloads-endpoint geeft de bestelling vervroegd vrij.
Productupdatemeldingen
Mail de kopers van een product dat het is bijgewerkt — dezelfde campagne die een merchant start met Klanten op de hoogte stellen op de pagina van een product in de app — vanuit je eigen systeem. Beschikbaar in elk betaald abonnement; 403 forbidden betekent dat de API voor de app is uitgeschakeld (de globale noodschakelaar) of dat Alva de functie heeft uitgeschakeld — neem contact met ons op als je dit antwoord krijgt. In het pad is {shopify_product_id} het kale numerieke product-id (aanbevolen) of een GID die procentgecodeerd is als één padsegment (gid%3A%2F%2Fshopify%2FProduct%2F123); een letterlijke gid://shopify/Product/123 vormt meerdere padsegmenten en bereikt de route niet.
| Methode | Pad | Doel |
|---|---|---|
| POST | /products/{shopify_product_id}/notifications | Een campagne in de wachtrij zetten voor elke in aanmerking komende koper van het product (202). Stuur { "dry_run": true } om dezelfde controles uit te voeren en het aantal ontvangers, het onderwerp en de gerenderde notitie te krijgen zonder iets te verzenden (200). Kost in beide gevallen 10 ratelimit-tokens. |
| GET | /notifications/{notificationId} | Een campagne lezen: status, aantallen, waiting_for_archive, error. Campagnes die vanuit de app zijn gestart, verschijnen ook. |
| POST | /notifications/{notificationId}/cancel | Een campagne annuleren die nog in de wachtrij staat (200, status cancelled). De 7-dagenlimiet van het product blijft staan. |
Request-body (elk veld optioneel; {} meldt het hele product zonder notitie). message: een notitie in platte tekst van maximaal 2.000 tekens, getoond als "Een bericht van {je winkel}:" boven de downloadknop. De notitie is bedoeld om te beschrijven wat er aan het product is veranderd — correcties, nieuwe bestanden, wat er opnieuw gedownload moet worden — en mag niet worden gebruikt voor promoties of kortingen. Mag {customer.first_name}, {shop.name}, {product.title} en {product.metafields.<namespace>.<key>} gebruiken (maximaal vijf metavelden van het type tekst, getal, datum of lijst met tekst; andere typen worden geweigerd). Links zijn nergens in de notitie toegestaan — webadressen, www., losse domeinnamen en e-mailadressen worden geweigerd, ook in de waarde van een metaveld — en een onbekende variabele wordt geweigerd in plaats van als tekst te blijven staan. Een aanwezig maar leeg message wordt geweigerd; laat het veld weg voor geen notitie. variant_ids: beperk de campagne tot de koppelingen die die varianten bedienen (losse id's of GID's, maximaal 100); laat het weg voor het hele product. Een lege array is 400 invalid_request, nooit "alles". dry_run: zie de tabel.
Wie wordt gemaild. Standaard elke koppeling van het product die bestanden, packs of links heeft; keys-only en gepersonaliseerde koppelingen worden overgeslagen. Een koper telt één keer, hoeveel beoogde varianten die ook heeft gekocht, en de knop opent de meest recente aankoop. Kopers die zich hebben afgemeld voor productupdatemail worden overgeslagen en geteld in opted_out_count.
Eén campagne per product per 7 dagen, over al zijn varianten en elke bron — dit endpoint, de vlag notify_customers bij het schrijven van een koppeling, en de eigen knop van de merchant. Binnen die week, en zolang er nog een campagne voor het product in de wachtrij staat of wordt verzonden, is het antwoord 429 notification_cooldown met Retry-After (seconden, tot zeven dagen) en error.details.next_available_at. Dit is niet de token bucket per sleutel: probeer het niet automatisch opnieuw — een retry-lus die op 429 reageert, draait een week lang door. Plan de volgende aanroep op next_available_at. Een campagne annuleren geeft het product zijn 7 dagen niet terug; gebruik dry_run om een notitie te controleren voordat je verzendt. Een campagne die mislukt met nul verzendingen geeft de limiet wél vrij, dus die kun je gewoon opnieuw proberen.
Maximaal 5 campagnes per shop tegelijk. Een shop kan maximaal 5 campagnes tegelijk in de wachtrij of in verzending hebben, over al zijn producten en elke bron. Een zesde is 429 too_many_active_notifications: error.details.limit is het maximum en error.details.active_notification_ids somt de campagnes van deze shop op die in de wachtrij staan of worden verzonden, de oudste eerst. Er is geen Retry-After; poll GET /notifications/{id} voor een ervan en probeer het opnieuw zodra die klaar is. Een dry run wordt op dezelfde manier geweigerd. Bij het schrijven van een koppeling wordt het gerapporteerd in data.notification, nooit als een 4xx.
Eén productupdatemail per koper per dag. Een koper krijgt binnen 24 uur maximaal één productupdatemail van een shop, geteld per e-mailadres, over elke campagne, elk product en elke bron. Dit wordt toegepast wanneer de campagne verzendt: een koper die er al een heeft gekregen, wordt overgeslagen, en overslaan is geen mislukking. Overgeslagen kopers worden niet meegeteld in sent_count, failed_count of suppressed_count, dus recipient_count kan hoger zijn dan hun som. Een campagne waarin elke koper is overgeslagen, eindigt als failed met error: recipients_recently_notified en gebruikt de 7 dagen van het product niet. Een campagne waarin slechts enkele kopers zijn overgeslagen, wordt gewoon voltooid en gebruikt ze wel.
Het wachten op het archief. Wordt het ZIP-archief van een beoogde koppeling opnieuw opgebouwd — je hebt net de bestanden vervangen — dan wacht de campagne tot die opbouw klaar is, zodat geen koper het oude archief downloadt: waiting_for_archive: true op de 202 en op GET. Alleen een koppeling die een ZIP-archief levert, laat een campagne wachten. Een opbouw die mislukt, of die 60 minuten lang niet vordert terwijl die loopt (6 uur terwijl die nog wacht op de start of op een nieuwe poging), geteld vanaf de laatste statuswijziging van de opbouw, niet vanaf het moment waarop de campagne is aangemaakt, laat de campagne mislukken met nul verzendingen (error is archive_build_failed of archive_not_ready) en geeft de limiet vrij; herstel de bestanden en probeer het opnieuw.
Idempotentie. Een 202 wordt 24 uur lang opnieuw afgespeeld onder dezelfde sleutel (dezelfde id, geen tweede campagne). Weigeringen worden nooit opgeslagen, dus een nieuwe poging met dezelfde sleutel na next_available_at wordt opnieuw beoordeeld. Gebruik per dry run een nieuwe Idempotency-Key: een opnieuw afgespeelde sleutel geeft het opgeslagen voorbeeld terug, en dezelfde sleutel met en zonder dry_run is 409 idempotency_conflict.
Status bij GET. queued → processing → completed, failed of cancelled. completed met partial: true betekent dat sommige verzendingen zijn mislukt of onderdrukt (zie sent_count, failed_count, suppressed_count), of dat het verzenden tussentijds is gestopt (zie hieronder). Bij failed is error een van interrupted, worker_crashed, send_aborted, archive_build_failed, archive_not_ready, email_disabled, invalid_message, plan_required, notifications_suspended, notifications_switched_off, nothing_sent, recipients_recently_notified, no_eligible_recipients, failed. source is admin, api of api_mapping.
Controles tijdens het verzenden. Vóór elke batch van maximaal 500 e-mails controleert de campagne de shop opnieuw. Ze stopt als het abonnement inactief is geworden of de shop is overgestapt op het Free-abonnement (plan_required), klant-e-mails zijn uitgezet (email_disabled), het verzenden is opgeschort na klachten (notifications_suspended), of Alva meldingen heeft uitgeschakeld (notifications_switched_off). Stopt de campagne voordat er iemand is gemaild, dan is ze failed met die error en worden de 7 dagen van het product vrijgegeven. Stopt ze nadat er al kopers zijn gemaild, dan is ze completed met partial: true. nothing_sent betekent dat elke verzending is mislukt, zodat niemand is gemaild; ook dan worden de 7 dagen vrijgegeven. no_eligible_recipients betekent dat er niemand meer over was om te mailen toen de campagne verzond (elke koper had zich afgemeld of geen downloadtoegang meer), dus er is niets verzonden en de 7 dagen worden vrijgegeven.
Weigeringen. 402 plan_required (de shop heeft het Free-abonnement of het abonnement is niet actief), 403 forbidden (de API is voor de app uitgeschakeld of Alva heeft de functie uitgeschakeld — neem contact met ons op), 403 notifications_suspended (verzenden is opgeschort na klachten — neem contact op met de ondersteuning), 404 mapping_not_found (geen koppeling voor het product, of een variant die geen koppeling bedient of die Shopify niet als een van de varianten van het product vermeldt — error.details.unresolved_variant_ids), 409 multiple_mappings_match (error.details.ambiguous_variant_ids), 409 personalized_product, 422 invalid_message (error.details.errors[] benoemt elke geschonden regel, error.details.max_length is het maximum), 422 email_disabled (klant-e-mail staat uit in de app), 422 no_downloadable_content, 422 no_eligible_recipients (error.details.opted_out_count), 429 notification_cooldown, 429 too_many_active_notifications (error.details.limit, error.details.active_notification_ids), 409 app_not_installed (de notitie noemt een metaveld of je hebt variant_ids meegestuurd, en Alva heeft geen actieve Shopify-sessie voor de shop, meestal omdat de app is verwijderd), 500 internal_error (bijvoorbeeld wanneer Shopify de metavelden van het product voor de notitie niet kon teruggeven of de gevraagde varianten niet kon bevestigen, of het aanmaken meer dan 8 seconden wachtte achter de andere aanmaakverzoeken van de shop: elke 500 van dit endpoint geeft de Idempotency-Key vrij, dus probeer hetzelfde verzoek opnieuw met dezelfde sleutel; heeft de mislukte poging de campagne toch in de wachtrij gezet, dan wordt de nieuwe poging geweigerd met 429 notification_cooldown in plaats van een tweede te starten). GET en cancel antwoorden 404 notification_not_found voor een ontbrekende of vreemde id, en cancel antwoordt 409 notification_not_cancellable met error.details.status zodra een campagne de wachtrij heeft verlaten. Zie de foutenpagina voor wat je bij elke code kunt doen.
Gezondheid en status
| Methode | Pad | Doel |
|---|---|---|
| GET | /health | De beschikbaarheid van de API controleren. |
| GET | /ping | De authenticatie controleren. |
| GET | /jobs/{jobId} | De status van een asynchrone job lezen. |
API-documentatie
Was dit nuttig?
Laatst bijgewerkt 2026-10-20