Quando uma tarefa de desafio, marco ou desafio é concluído e tem um valor de recompensa configurado, a plataforma emite uma recompensa ao chamar o ponto de extremidade HTTP do seu provedor de recompensa com uma carga JSON. Uma Definição de Recompensa descreve qual recompensa deve ser emitida e fornece uma expressão JSONata — rewardJsonata — que molda a carga exata que seu provedor espera.
Este guia aborda como configurar um provedor de premiação, criar definições de premiação, escrever a expressão rewardJsonata e entender qual contexto está disponível para ele no momento da avaliação.
Modelo de dois níveis
As recompensas são organizadas em dois níveis:
Reward Provider (endpoint, auth, headers)
└── Reward Definition (denomination, rewardJsonata)
└── Reward Definition
└── ...
Um Provedor de Recompensa representa um único sistema de recompensas externo — ele contém a URL do ponto de extremidade de entrega, a autenticação e qualquer cabeçalho HTTP personalizado. Um provedor pode conter várias Definições de Recompensa, cada uma descrevendo um tipo ou denominação de recompensa distinta oferecida por esse provedor (por exemplo, “50 Estrelas”, “Estrelas Duplas”, “Item Gratuito”).
Um desafio faz referência ao provedor e à definição por GUID. Quando uma premiação é emitida, a plataforma avalia a expressão rewardJsonata da definição e faz o POST do resultado para o ponto de extremidade do provedor.
Prestador de recompensas e campos de definição
| table 0-row-4 1-row-4 2-row-4 3-row-4 4-row-4 5-row-4 6-row-4 7-row-4 8-row-4 html-authored | |||
|---|---|---|---|
| Campo | Tipo | Obrigatório | Descrição |
guid |
String |
Não (atribuído pelo sistema) | Identificador exclusivo. Somente leitura. |
name |
String |
Sim | Nome de exibição, exclusivo dentro da organização. |
desc |
String |
Não | Descrição legível do provedor. |
enabled |
Boolean |
Não | Quando false, a entrega de premiação ésuspensa para todas as definições neste provedor. |
url |
String |
Sim | Endpoint HTTP que recebe a carga do prêmio. A plataforma publica a saída rewardJsonata avaliada para esta URL. |
additionalHeaders |
Object |
Não | Cabeçalhos HTTP personalizados para incluir em cada solicitação de entrega (por exemplo, chaves de API, substituições de tipo de conteúdo). |
maxRatePerSecond |
Integer |
Não | Limite de taxa por provedor opcional (1-5000). Nulo significa ilimitado. |
enableMTLS |
Boolean |
Não | Se o ponto de extremidade requer TLS mútuo. |
| table 0-row-4 1-row-4 2-row-4 3-row-4 4-row-4 5-row-4 6-row-4 7-row-4 html-authored | |||
|---|---|---|---|
| Campo | Tipo | Obrigatório | Descrição |
guid |
String |
Não (atribuído pelo sistema) | Identificador exclusivo. Somente leitura. |
name |
String |
Sim | Nome de exibição, exclusivo no provedor. |
denomination |
String |
Não | A unidade da premiação, usada na exibição e disponível em expressões como reward.denomination(por exemplo, "Stars", "Points", "Miles"). |
desc |
String |
Não | Descrição da premiação, disponível em expressões como reward.desc. |
enabled |
Boolean |
Não | Quando false, esta definição fica inativae não emitirá recompensas. |
isDefault |
Boolean |
Não | Marca isso como a definição padrão de recompensa em toda a sandbox. Somente uma definição em todos os provedores pode ser padrão de cada vez; a definição de um novo padrão limpa a anterior. Usado para popular automaticamente os detalhes da premiação em desafios personalizados no momento da publicação. |
rewardJsonata |
String |
Sim | Expressão JSONata avaliada em tempo de emissão de recompensa. Recebe o contexto de premiação completo e deve retornar a carga JSON para POST para o provedor. |
O contexto da recompensa
Quando rewardJsonata é avaliado, ele recebe um único objeto raiz contendo tudo o que se sabe sobre o evento de premiação. Todos os caminhos na expressão são relativos a essa raiz.
{
"rewardContext": {
"rewardValue": "50",
"source": "challenge"
},
"reward": {
"name": "500 Stars",
"desc": "Issue 500 Stars to the member",
"denomination": "Stars",
"enabled": true
},
"task": { ... },
"milestone": { ... },
"challenge": { ... },
"timestamp": "2026-02-10T00:29:22.538+00:00"
}
| table 0-row-2 1-row-2 2-row-2 3-row-2 4-row-2 5-row-2 6-row-2 7-row-2 8-row-2 9-row-2 10-row-2 11-row-2 12-row-2 13-row-2 14-row-2 15-row-2 16-row-2 | |
|---|---|
| Campo | Descrição |
rewardContext.rewardValue |
A sequência de caracteres do valor de premiação configurada no desafio, tarefa ou marco que provocou essa ocorrência. |
rewardContext.source |
O que acionou a premiação: "task", "challenge" ou "milestone". |
reward |
A própria RewardDefinition — name, desc, denomination. |
task |
A tarefa de conclusão, incluindo accumulators, schedule e reward. |
task.accumulators.spend |
Total de gastos de qualificação acumulados pela tarefa. |
task.accumulators.qty |
Contagem total de itens qualificados acumulada pela tarefa. |
task.accumulators.item_list |
Todos os itens qualificados aplicados à tarefa. Cada entrada tem item, transactionId, timestamp, utcOffset, locationId. |
task.accumulators.item_list[-1] |
O item mais recente aplicado (índice negativo JSONata). Útil para fornecer a ID da última transação ou carimbo de data e hora. |
task.schedule.currentStreak |
Contagem de sequências de visitas consecutivas atuais (para desafios de sequências). |
task.schedule.currentVisits |
Contagem total de visitas (para desafios de visitas). |
milestone |
O marco que disparou esta recompensa, ou null se não for uma recompensa por marcos. Inclui count e reward.rewardValue. |
challenge.profileId |
A ID de fidelidade do membro. |
challenge.kvpCustom |
Pares de valores-chave personalizados configurados no desafio. Um padrão comum para transmitir IDs de campanha, nomes de produtos ou metadados específicos do provedor. |
challenge.name |
Nome do desafio. |
challenge._id |
ID do desafio. |
timestamp |
Carimbo de data e hora ISO 8601 da emissão de recompensa. |
Escrever a expressão awardJsonata
A expressão recebe o contexto de premiação como sua entrada e deve retornar um objeto JSON — a carga POST para o endpoint do provedor. A forma desse objeto depende totalmente da API do provedor; mapeie os campos de contexto em qualquer estrutura que o provedor espere.
O caso mais simples: o provedor precisa de uma contagem de pontos e uma ID de membro, ambos conhecidos do contexto.
| code language-jsonata |
|---|
|
Saída:
| code language-json |
|---|
|
rewardContext.rewardValueé sempre uma cadeia de caracteres. Use$number()para convertê-lo se o provedor esperar um valor numérico.
kvpCustom para metadados específicos do provedorOs provedores geralmente exigem campos como IDs de campanha ou códigos do sistema de origem específicos para cada execução de desafio. Armazene-os em challenge.kvpCustom ao criar o desafio e, em seguida, faça referência a eles na expressão — mantendo a expressão reutilizável em campanhas.
| code language-jsonata |
|---|
|
Você também pode usar reward.kvpCustom para constantes que são fixas para um determinado tipo de recompensa em vez de por desafio.
Os acumuladores de tarefas mantêm um registro de cada evento qualificado. Usar item_list[-1] para acessar o item aplicado mais recentemente — seus transactionId e timestamp são úteis para trilhas de auditoria e desduplicação no lado do provedor.
| code language-jsonata |
|---|
|
Para provedores baseados em notificação (Slack, SMS, email), você pode criar uma cadeia de caracteres de mensagem diretamente usando o operador de concatenação & do JSONata:
| code language-jsonata |
|---|
|
Saída:
| code language-json |
|---|
|
Exemplos
Cenário: uma API básica de pontos de fidelidade espera uma ID de membro e um valor de ponto.
Definição de recompensa:
| code language-json |
|---|
|
Expressão formatada:
| code language-jsonata |
|---|
|
Carga postada para o provedor:
| code language-json |
|---|
|
Cenário: o provedor requer um registro de prêmio estruturado que inclua campos de auditoria, referências de campanha e descrição do membro. Os valores específicos de campanha são armazenados em challenge.kvpCustom para que a mesma definição de premiação funcione em campanhas sem editar a expressão.
DesafiokvpCustom (definido ao criar o desafio):
| code language-json |
|---|
|
Definição de recompensa:
| code language-json |
|---|
|
Expressão formatada:
| code language-jsonata |
|---|
|
Carga postada para o provedor:
| code language-json |
|---|
|
Cenário: um desafio de sequência emite uma recompensa por marcos a cada N visitas. A expressão inclui a contagem de etapas e a listra atual para o contexto do provedor.
Expressão formatada:
| code language-jsonata |
|---|
|
Carga postada para o provedor (na segunda etapa de visita):
| code language-json |
|---|
|
Quando
rewardContext.sourceé"milestone", o objetomilestoneé preenchido comcountereward.rewardValue. Quando a origem é"task"ou"challenge",milestoneénull.
Referência da API
| code language-http |
|---|
|
Todas as solicitações exigem x-gw-ims-org-id e x-sandbox-name cabeçalhos.
Criar um provedor:
| code language-http |
|---|
|
| code language-http |
|---|
|
Criar uma definição de premiação:
| code language-http |
|---|
|
Validação de expressão
rewardJsonata expressões são validadas para sintaxe no momento da publicação. Se a expressão for inválida, a API retornará um erro 422 com uma descrição da falha de análise.
Para desenvolver e testar uma expressão antes de publicar, use o JSONata Exerciser. Cole o JSON de contexto de premiação como o documento de entrada e sua expressão para verificar se a saída corresponde ao que o provedor espera. Um contexto de premiação representativo para cada tipo de gatilho (task, milestone, challenge) é mostrado nos exemplos acima.
Erros comuns
rewardContext.rewardValue usado como um número sem conversão$number(rewardContext.rewardValue)challenge.kvpCustom.someKey retorna nulokvpCustom em cada desafio que usa essa definiçãotask.accumulators.item_list[-1] é nulotimestamp do contextomilestone acessado quando a origem é "task" ou "challenge"milestone é nulo; a expressão lança ou produz campos nulosrewardContext.source antes de acessar milestone, ou use apenas milestone em definições anexadas a recompensas por etapas{ "items": [...] }