Ativos
| Método | Caminho | Finalidade |
|---|---|---|
| POST | /assets | Importar uma URL remota como asset. |
| POST | /assets/uploads | Iniciar um upload direto. |
| POST | /assets/uploads/{uploadId}/complete | Finalizar um upload direto. |
| GET | /assets | Listar assets. |
| GET/PATCH/DELETE | /assets/{id} | Ler, atualizar ou excluir um asset. |
Categorias, mapeamentos, pacotes, links e tags
| Método | Caminho | Finalidade |
|---|---|---|
| GET/POST | /categories | Listar ou criar categorias planas. |
| GET/PATCH/DELETE | /categories/{id} | Ler, renomear ou excluir uma categoria. |
| GET/POST | /mappings | Listar ou inserir/atualizar mapeamentos de produtos da Shopify. |
| GET/PUT/DELETE | /mappings/{id} | Ler, substituir ou excluir um mapeamento. |
| GET/POST | /packs | Listar ou criar packs. |
| GET/DELETE | /packs/{id} | Ler ou excluir um pack. |
| GET/POST | /links | Listar ou criar links. A criação exige um plano pago; limites de visitas e expiração continuam exclusivos do admin. |
| GET/POST | /license-key-tags | Listar ou criar tags de chaves de licença. |
POST /mappings e PUT /mappings/{id} aceitam um objeto opcional notify_customers ({} ou { "message": "…", "variant_ids": [ … ] }). Depois que a escrita é confirmada, o Alva coloca na fila uma notificação de atualização de produto para os compradores do mapeamento que você escreveu — a mesma campanha de POST /products/{shopify_product_id}/notifications abaixo, com as mesmas regras de observação e o mesmo limite de 7 dias por produto. Só as verificações do próprio texto da observação são executadas antes da escrita: uma observação em branco, longa demais, que usa uma variável desconhecida ou malformada, cita mais de cinco metacampos ou tem um link no texto é 422 invalid_message e nada é escrito. Toda outra recusa é informada dentro da resposta como data.notification com created: false e um código error — nunca como um 4xx, então a escrita do mapeamento em si continua bem-sucedida. Isso inclui um problema de metacampo (invalid_message com errors[]: um metacampo ausente, de um tipo não compatível, longo demais ou que contém um link, ou uma observação longa demais depois que suas variáveis são preenchidas), notification_cooldown com next_available_at, too_many_active_notifications com limit e active_notification_ids, no_eligible_recipients, email_disabled e archive_not_queued quando a nova geração do arquivo não pôde ser colocada na fila. Um mapeamento recém-criado ainda não tem compradores e informa no_eligible_recipients. data.notification só está presente quando você enviou o sinalizador. O sinalizador não acrescenta custo de limite de taxa: a gravação do mapeamento custa os 2 tokens de sempre. Repetir a mesma Idempotency-Key retorna a resposta armazenada sem uma segunda campanha; para tentar de novo só a notificação, chame POST /products/{shopify_product_id}/notifications com uma chave nova e variant_ids com as variantes do mapeamento gravado, ou com os mesmos variant_ids que o sinalizador levava. Sem variant_ids, esse endpoint notifica os compradores de todos os mapeamentos do produto, não só os do que você gravou.
Um sinalizador por produto, não um por variante. O sinalizador envia e-mail só para os compradores do mapeamento que você escreveu, mas usa o limite de 7 dias do produto inteiro. Se você escrever os mapeamentos de variantes de um produto um de cada vez, com o sinalizador em cada um, a primeira campanha ocupa os 7 dias do produto, e as outras informam notification_cooldown. Em vez disso, coloque o sinalizador em uma única escrita, a última, para que a campanha também espere pelas novas gerações de arquivo que as escritas anteriores colocaram na fila. Liste em variant_ids todas as variantes cujos compradores devem ser avisados, inclusive as do próprio mapeamento escrito: variant_ids substitui o escopo padrão em vez de se somar a ele.
Pedidos e acesso
| Método | Caminho | Finalidade |
|---|---|---|
| GET | /orders/{shopify_order_id} | Ler o status de download de um pedido. |
| GET/POST | /orders/{shopify_order_id}/assignments | Listar ou criar atribuições no nível do produto. |
| GET | /orders/{shopify_order_id}/assignments/{purchaseId}/download-urls | Gerar URLs de download. |
| POST | /orders/{shopify_order_id}/revoke | Desativar o acesso. |
| POST | /orders/{shopify_order_id}/restore | Restaurar o acesso. |
| POST | /orders/{shopify_order_id}/grant-downloads | Conceder downloads extras. |
| POST | /orders/{shopify_order_id}/resend | Reenviar o e-mail de entrega. |
O endpoint de download-urls retorna 422 withdrawal_consent_required quando a loja tem o consentimento do direito de arrependimento da UE ativado e o pedido ainda não tem um registro de consentimento; as URLs de download são emitidas assim que o cliente consente.
Os endpoints download-urls e resend retornam 409 delivery_not_yet_released quando o produto tem um atraso na entrega do download configurado e os arquivos do comprador ainda não foram liberados. O valor error.details.release_at é o instante ISO 8601 da liberação, e o endpoint grant-downloads libera o pedido antecipadamente.
Notificações de atualização de produto
Envie por e-mail aos compradores de um produto o aviso de que ele foi atualizado — a mesma campanha que um lojista inicia com Notificar clientes na página de um produto no aplicativo — a partir do seu próprio sistema. Disponível em todos os planos pagos; 403 forbidden significa que a API está desativada para o aplicativo (o interruptor global de emergência) ou que o Alva desativou o recurso — entre em contato conosco se receber essa resposta. No caminho, {shopify_product_id} é o id numérico simples do produto (recomendado) ou um GID codificado em porcentagem como um único segmento de caminho (gid%3A%2F%2Fshopify%2FProduct%2F123); um gid://shopify/Product/123 literal ocupa vários segmentos de caminho e não chega à rota.
| Método | Caminho | Finalidade |
|---|---|---|
| POST | /products/{shopify_product_id}/notifications | Colocar na fila uma campanha para todos os compradores elegíveis do produto (202). Envie { "dry_run": true } para executar as mesmas verificações e obter o número de destinatários, o assunto e a observação renderizada sem enviar nada (200). Custa 10 tokens de limite de taxa em ambos os casos. |
| GET | /notifications/{notificationId} | Ler uma campanha: status, números, waiting_for_archive, error. Campanhas iniciadas pelo aplicativo também aparecem. |
| POST | /notifications/{notificationId}/cancel | Cancelar uma campanha que ainda está na fila (200, status cancelled). O limite de 7 dias do produto é mantido. |
Corpo da requisição (todos os campos opcionais; {} notifica o produto inteiro sem observação). message: uma observação em texto simples de até 2.000 caracteres, exibida como "Um recado de {sua loja}:" acima do botão de download. A observação serve para descrever o que mudou no produto — correções, arquivos novos, o que baixar de novo — e não deve ser usada para promoções ou descontos. Ela pode usar {customer.first_name}, {shop.name}, {product.title} e {product.metafields.<namespace>.<key>} (até cinco metacampos do tipo texto, número, data ou lista de texto; outros tipos são recusados). Links não são permitidos em nenhuma parte da observação — endereços web, www., domínios sem prefixo e endereços de e-mail são recusados, inclusive dentro do valor de um metacampo — e uma variável desconhecida é recusada em vez de ficar como texto. Um message presente mas em branco é recusado; omita o campo para não ter observação. variant_ids: limita a campanha aos mapeamentos que atendem a essas variantes (ids simples ou GIDs, no máximo 100); omita-o para o produto inteiro. Um array vazio é 400 invalid_request, nunca "tudo". dry_run: veja a tabela.
Quem recebe o e-mail. Por padrão, todo mapeamento do produto que tem arquivos, packs ou links; mapeamentos só com chaves e personalizados são pulados. Um comprador conta uma vez, não importa quantas variantes alvo tenha comprado, e o botão abre sua compra mais recente. Compradores que optaram por não receber e-mails de atualização de produto são pulados e contados em opted_out_count.
Uma campanha por produto a cada 7 dias, em todas as suas variantes e em todas as origens — este endpoint, o sinalizador notify_customers em uma escrita de mapeamento e o próprio botão do lojista. Dentro dessa semana, e enquanto uma campanha para o produto ainda está na fila ou enviando, a resposta é 429 notification_cooldown com Retry-After (segundos, até sete dias) e error.details.next_available_at. Isto não é o token bucket por chave: não tente de novo automaticamente — um loop de novas tentativas baseado em 429 vai girar por uma semana. Agende a próxima chamada para next_available_at. Cancelar uma campanha não devolve ao produto os seus 7 dias; use dry_run para conferir uma observação antes de enviar. Uma campanha que falha com zero envios libera o limite, então basta tentar de novo.
No máximo 5 campanhas por loja ao mesmo tempo. Uma loja pode ter no máximo 5 campanhas na fila ou enviando ao mesmo tempo, somando todos os seus produtos e todas as origens. A sexta campanha é 429 too_many_active_notifications: error.details.limit é o limite e error.details.active_notification_ids lista as campanhas desta loja na fila ou enviando, da mais antiga para a mais recente. Não há Retry-After; consulte periodicamente GET /notifications/{id} de uma delas e tente de novo quando ela terminar. Um dry run é recusado da mesma forma. Em uma escrita de mapeamento, isso é informado em data.notification, nunca como um 4xx.
Um e-mail de atualização de produto por comprador por dia. Um comprador recebe no máximo um e-mail de atualização de produto de uma loja em qualquer período de 24 horas, contado por endereço de e-mail, somando todas as campanhas, produtos e origens. Isso é aplicado quando a campanha envia: um comprador que já recebeu um é pulado, e ser pulado não é uma falha. Compradores pulados não são contados em sent_count, failed_count nem suppressed_count, então recipient_count pode ser maior que a soma deles. Uma campanha em que todos os compradores foram pulados termina failed com error: recipients_recently_notified e não consome os 7 dias do produto. Uma em que só alguns foram pulados é concluída normalmente e consome os 7 dias.
A espera pelo arquivo. Se o arquivo ZIP de um mapeamento alvo está sendo gerado de novo — você acabou de substituir seus arquivos — a campanha espera até a geração terminar, para que nenhum comprador baixe o arquivo antigo: waiting_for_archive: true no 202 e no GET. Apenas um mapeamento que entrega um arquivo ZIP faz uma campanha esperar. Uma geração que falha, ou que fica 60 minutos sem progresso enquanto está em execução (6 horas enquanto ainda aguarda para começar ou por uma nova tentativa), contados a partir da última mudança de estado da geração, não de quando a campanha foi criada, faz a campanha falhar com zero envios (error é archive_build_failed ou archive_not_ready) e libera o limite; corrija os arquivos e tente de novo.
Idempotência. Um 202 é repetido por 24 horas sob a mesma chave (mesmo id, sem segunda campanha). Recusas nunca são armazenadas, então uma nova tentativa com a mesma chave depois de next_available_at é avaliada de novo. Use uma Idempotency-Key nova para cada dry run: uma chave repetida retorna a visualização armazenada, e a mesma chave com e sem dry_run é 409 idempotency_conflict.
Status no GET. queued → processing → completed, failed ou cancelled. completed com partial: true significa que alguns envios falharam ou foram suprimidos (veja sent_count, failed_count, suppressed_count) ou que o envio parou no meio do caminho (veja abaixo). Em failed, error é um de 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 é admin, api ou api_mapping.
Verificações durante o envio. Antes de cada lote de até 500 e-mails, a campanha verifica a loja de novo. Ela é interrompida se a assinatura ficou inativa ou a loja passou para o plano Free (plan_required), se os e-mails para clientes foram desativados (email_disabled), se o envio foi suspenso após reclamações (notifications_suspended) ou se o Alva desativou as notificações (notifications_switched_off). Interrompida antes de alguém receber e-mail, a campanha fica failed com esse error e os 7 dias do produto são liberados. Interrompida depois que alguns compradores receberam o e-mail, ela fica completed com partial: true. nothing_sent significa que todos os envios falharam, então ninguém recebeu e-mail; isso também libera os 7 dias. no_eligible_recipients significa que não restava ninguém para receber o e-mail no momento em que a campanha enviou (todos os compradores tinham optado por não receber e-mails ou perdido o acesso ao download), então nada foi enviado e os 7 dias são liberados.
Recusas. 402 plan_required (a loja está no plano Free ou sua assinatura não está ativa), 403 forbidden (a API está desativada para o aplicativo ou o Alva desativou o recurso — entre em contato conosco), 403 notifications_suspended (o envio está suspenso após reclamações — entre em contato com o suporte), 404 mapping_not_found (nenhum mapeamento para o produto, ou uma variante que nenhum mapeamento atende ou que o Shopify não lista entre as variantes do produto — error.details.unresolved_variant_ids), 409 multiple_mappings_match (error.details.ambiguous_variant_ids), 409 personalized_product, 422 invalid_message (error.details.errors[] nomeia cada regra quebrada, error.details.max_length é o limite), 422 email_disabled (o e-mail para clientes está desativado no aplicativo), 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 (a observação menciona um metacampo ou você enviou variant_ids, e o Alva não tem uma sessão ativa do Shopify para a loja, geralmente porque o aplicativo foi desinstalado), 500 internal_error (por exemplo, o Shopify não conseguiu retornar os metacampos do produto para a observação nem confirmar as variantes solicitadas, ou a criação esperou mais de 8 segundos atrás das outras criações da loja: todo 500 deste endpoint libera a Idempotency-Key, então tente de novo a mesma requisição com a mesma chave; se a tentativa que falhou chegou a colocar a campanha na fila, a nova tentativa é recusada com 429 notification_cooldown em vez de iniciar uma segunda). GET e cancel respondem 404 notification_not_found para um id inexistente ou de outra loja, e cancel responde 409 notification_not_cancellable com error.details.status depois que uma campanha saiu da fila. Veja a página de erros para saber o que fazer em cada caso.
Saúde e status
| Método | Caminho | Finalidade |
|---|---|---|
| GET | /health | Verificar a disponibilidade da API. |
| GET | /ping | Verificar a autenticação. |
| GET | /jobs/{jobId} | Ler o status de um job assíncrono. |
Documentação da API
Isto foi útil?
Última atualização 2026-10-20