Início rápido
No painel Web, crie um aplicativo de terceiros vinculado à empresa desejada. Copie o App ID e o App Secret e, se precisar do resultado final, configure um Callback URL opcional.
O Engine cria entradas para os usuários escolhidos pelo audience opcional (toda a empresa elegível por padrão) e só tenta o Push do sistema em dispositivos registrados elegíveis.
Endpoint e autenticação
Ambientes da API:
- Teste: https://aim-api-test.proton-system.com
- Produção: https://aim-api.proton-system.com
Cada solicitação JSON entre servidores deve incluir Authorization: Basic Base64(KEY:SECRET) por meio de HTTP Basic Authentication, em que KEY é o App ID e SECRET é o App Secret:
Endpoint: POST /openapi/v1/notifications.
curl --request POST 'https://<your-engine-host>/openapi/v1/notifications' \
--header 'Authorization: Basic <Base64(AppID:AppSecret)>' \
--header 'Content-Type: application/json' \
--data '{"requestId":"order-20260819-001","title":"Pedido concluído","body":"Seu pedido foi concluído.","imageUrls":["https://cdn.example.com/order/001-1.webp","https://cdn.example.com/order/001-2.webp"],"displayFields":[{"label":"Nome da loja","value":"Macarrão Xiao Han (Wangjing)"},{"value":"ORD-10086"}],"tags":["Concluído","Loja principal"]}'Contrato da solicitação
Resumo dos campos
| Campo | Obrigatório | Tipo | Significado |
|---|---|---|---|
requestId | Sim | string | Identificador único criado pelo emissor e chave de idempotência. É aparado e não pode ficar vazio. |
title | Sim | string | Título da notificação. É aparado e não pode ficar vazio. |
body | Sim | string | Corpo da notificação. É aparado e não pode ficar vazio. |
imageUrls | Não | string[] | Imagens do detalhe, na ordem de exibição. |
displayFields | Não | object[] | Campos de texto adicionais do detalhe, em ordem. |
tags | Não | string[] | Tags de plain text exibidas somente no detalhe, em ordem. |
audience | Não | object | Restringe a usuários ou funções; omitido significa toda a empresa elegível. |
Imagens: imageUrls
- Omita, envie
nullou[]quando não houver imagens; caso contrário, envie 1-9 URLs em ordem. - Cada URL é aparada, deve ser única e deve ser uma URL
HTTPSabsoluta sem usuário ou senha. - Cada URL aceita até 2048 caracteres Unicode. Uma URL inválida rejeita toda a solicitação.
- O Engine guarda as URLs, mas não busca, verifica, faz proxy ou cache.
Campos de detalhe: displayFields
| Subcampo | Obrigatório | Limite | Exibição |
|---|---|---|---|
label | Não | Aparado, não vazio, até 32 Unicode caracteres | Nome do campo. |
value | Sim | Aparado, não vazio, até 256 Unicode caracteres | Valor do campo. |
{
"displayFields": [
{ "label": "Loja", "value": "Little Han Noodles (Wangjing)" },
{ "value": "ORD-10086" }
]
}- Omiti-lo, enviar
nullou[]significa nenhuma linha extra; são permitidos até 10 objetos. - Sem
labelou comlabel: null, ovalueocupa uma linha inteira. - O conteúdo é sempre plain text; HTML, Markdown, links, dados aninhados, tipos e estilos não são aceitos.
Tags do detalhe: tags
- Omita, envie
nullou[]quando não houver tags. Caso contrário, envie no máximo 8 strings na ordem de exibição. - Cada tag é aparada e deve conter 1-20 caracteres Unicode. Valor vazio, não string, longo demais ou duplicado após aparar rejeita toda a solicitação com
INVALID_REQUEST. - As tags são plain text não interativo, aparecem somente no detalhe e preservam a ordem.
Destinatários: audience
type | Seletor | Significado do ID |
|---|---|---|
USERS | userIds | ID do membro da empresa |
ROLES | roles | CompanyRole ID; membros válidos de qualquer função recebem. |
Copie o ID do membro da empresa na lista de membros da empresa do Web Admin. O membro deve pertencer à empresa vinculada ao aplicativo de terceiros.
{
"audience": { "type": "USERS", "userIds": ["companyMemberId"] }
}{
"audience": { "type": "ROLES", "roles": ["roleId"] }
}- Omita
audienceou envienullpara todos os usuários ativos elegíveis da empresa vinculada. - A lista aceita 1-100 strings originais; IDs são aparados, vazios ignorados e o conjunto é deduplicado e ordenado.
- IDs inexistentes, inativos, excluídos ou de outra empresa são ignorados; os alvos válidos restantes recebem.
- Um seletor válido sem alvos é aceito e termina com
recipientCount=0; nunca há fallback para toda a empresa. - O seletor não correspondente pode ser omitido ou
null. Misturas não nulas, types ou campos desconhecidos, listas ausentes ou vazias, itens não string e mais de 100 entradas retornamINVALID_REQUEST.
Limites e idempotência
- O corpo completo aceita 256 KiB.
requestId,titleebodyaceitam 128, 100 e 1000 caracteres Unicode. - Cada App ID aceita 10 solicitações por minuto e 100 por hora.
- Repetir
requestIdcom conteúdo normalizado equivalente retorna o resultado salvo. A ordem importa para imagens, campos e tags, não para o conjunto audience. - Conteúdo diferente com o mesmo
requestIdretornaIDEMPOTENCY_CONFLICT. O resultado final pode serSUCCESS,PARTIAL_SUCCESSouFAILED.
Resposta de aceitação
Uma solicitação válida retorna HTTP 202:
{
"requestId": "order-20260819-001",
"notificationId": "00000000-0000-0000-0000-000000000001",
"status": "ACCEPTED"
}ACCEPTED significa apenas que o Engine guardou a solicitação para envio, não que APNs/FCM ou o dispositivo exibiram a notificação.
Resultado do Callback
Com Callback URL configurado, o Engine envia o resultado final:
{
"requestId": "order-20260819-001",
"status": "PARTIAL_SUCCESS",
"recipientCount": 8,
"pushAcceptedCount": 1,
"pushFailedCount": 1
}recipientCount é o número de usuários destinatários da central de notificações. pushAcceptedCount e pushFailedCount são contagens de lotes do Push Outbox, não contagens de usuários ou dispositivos nem prova de entrega do banner do sistema.
Teste de Callback
Cada teste de Callback do painel administrativo envia uma sonda distinta:
{
"requestId": "callback-test-<unique-id>",
"status": "SUCCESS",
"recipientCount": 1,
"pushAcceptedCount": 1,
"pushFailedCount": 0,
"test": true
}Quando test for true, valide a estrutura e responda com 2xx, mas não associe a sonda a uma solicitação de notificação nem atualize o estado de entrega do negócio. As contagens são valores fixos de teste, não destinatários nem lotes reais do Push Outbox.
O status final é SUCCESS, PARTIAL_SUCCESS ou FAILED. Responda com qualquer 2xx para confirmar.
Caso contrário, haverá novas tentativas após 1 minuto, 5 minutos, 30 minutos, 2 horas, 6 horas e 24 horas. Atualmente não existe assinatura HMAC: exija HTTPS, confira o requestId dos resultados que não sejam de teste, restrinja a exposição e processe o Callback de forma idempotente.
Referência de erros
| HTTP | Code | Significado |
|---|---|---|
| 400 | INVALID_REQUEST | Content-Type, JSON, tamanho ou validação inválidos. |
| 401 | INVALID_APP_CREDENTIALS | App ID ou App Secret inválidos. |
| 403 | APPLICATION_INACTIVE | Aplicativo ou empresa inativos. |
| 409 | IDEMPOTENCY_CONFLICT | requestId reutilizado com conteúdo diferente. |
| 429 | RATE_LIMITED | Limite do aplicativo excedido. |
| 503 | NOTIFICATION_UNAVAILABLE | Serviço temporariamente indisponível. |
Segurança e escopo de envio
- App ID e App Secret são credenciais entre servidores. Nunca use navegador, aplicativo móvel, repositório público, URL ou armazenamento do cliente. Redefina o App Secret se houver exposição.
- Os IDs de destino privados nunca são gravados nos logs do aplicativo. O seletor privado e seus IDs também não aparecem em GraphQL, Push, Callback, realtime nem navigation.
- Sem
audience, todos os usuários ativos elegíveis da empresa são incluídos; com audience, somente os alvos válidos resolvidos. Cada destinatário válido recebe uma entrada e é contado emrecipientCount. - O Push do sistema só é tentado em dispositivos com um
PushInstallationativo que permita a categoriaBUSINESS, sem garantir um banner em todos os dispositivos. - A lista completa de
imageUrlsfica só no detalhe autorizado. O Engine pode enviar a primeira URL deimageUrlsao APNs/FCM para um banner nativo.displayFieldsetagsnão entram em Push nem Callback e são plain text não interativo; não inclua segredos, tokens de acesso, dados de pagamento nem valores sensíveis. titleebodydevem permanecer completos e compreensíveis sem as imagens. Falhas ao baixar ou renderizar imagens não alteram o status de accepted, Callback ou Push.- O cliente móvel aceita no máximo 5 MiB por imagem e limita a operação completa de download a 10 segundos. Ele não segue redirecionamentos 3xx, portanto cada URL deve retornar a imagem diretamente.
- O cliente móvel baixa cada imagem diretamente do CDN público. Use URLs sem autenticação nem cookies, mantenha-as disponíveis por pelo menos 90 dias e considere que o CDN recebe o IP, o horário da solicitação e o User-Agent do usuário.
- Prefira URLs de objetos imutáveis quando a exibição histórica precisar permanecer estável.