Introdução
Esta API permite que você envie eventos que ocorrem dentro ou fora do aplicativo móvel, mas que não são enviados através do SDK da AppsFlyer. Por exemplo, se você tiver uma interface móvel e na web, você pode gravar todos os eventos de ambos os meios na AppsFlyer.
Observação
O tipo de conteúdo deve ser definido como aplicativo/json.
URL:https://api2.appsflyer.com/inappevent/{app_id}
Exemplo Android:https://api2.appsflyer.com/inappevent/com.appsflyer.myapp
Exemplo iOS: https://api2.appsflyer.com/inappevent/id123456789
É importante prestar atenção extra para que a ID do aplicativo no iOS contenha a "id" principal antes da ID, caso contrário, a solicitação termina com HTTPS 200 OK, mas o evento não é registrado.
Importante!
O tamanho máximo da carga do JSON não deve exceder 1K.
O payload do JSON deve ser passado como uma string e o valor do evento deve estar em formato de string.
Certifique-se de que o payload do JSON inclui o parâmetro "af_events_api" :"true"
Este parâmetro garante que o evento seja estruturado como um evento avançado para habilitar o mapeamento automático dos valores dos eventos para vários parceiros.
Confira exemplos abaixo.
Método: POST
Cabeçalho – "autenticação"= {dev-key}
A chave do desenvolvedor é encontrada no Painel >> Configurações do aplicativo >> Chave do desenvolvedor
{
"appsflyer_id": {AppsFlyer Device ID }, // e.g. 1415211453000-6513894
"idfa":{idfa},
"customer_user_id": {customer_user_id}, // Customer User ID optional parameter
"eventName": {The event name}, // e.g. "af_purchase"
"eventValue": {A JSON containing a rich in-app event value - must be stringfied},
"{
\"af_revenue\":\"6\",
\"af_content_type\":\"wallets\",
\"af_content_id\":\"15854\"
}",
"eventCurrency": {Event currency}, // e.g "USD"
"ip": {device IP},
"eventTime": {Event timestamp in UTC +0}, // e.g "2014-05-15 12:17:00.000"
"af_events_api" :"true"
}
{
"appsflyer_id": {AppsFlyer Device id}, // e.g. 1415211453000-6513894
"advertising_id": {advertising_id},
"customer_user_id": {customer_user_id}, // Customer User ID optional parameter ---
"eventName": {The event name}, // e.g "af_purchase
"eventValue": {A JSON containing a rich in-app event value - must be stringified}
"{
\"af_revenue\":\"6\",
\"af_content_type\":\"wallets\",
\"af_content_id\":\"15854\"
}"
"eventCurrency": {Event currency}, // e.g "USD"
"ip": {device IP},
"eventTime": {Event timestamp in UTC +0}, // e.g "2014-05-15 12:17:00.000"
"af_events_api" :"true"
}
Observação
Todos os caracteres reservados (https://tools.ietf.org/html/rfc3986#section-2.1) devem ser codificados por porcentagem antes que a URI seja formada.
Parâmetros
-
Parâmetros obrigatórios:
appsflyer_id
(AppsFlyer Device id),eventName
,eventValue
eaf_events_api
-
Parâmetros altamente recomendados:
idfa
para iOS eadvertising_id
para Android.
Se você quiser mapear seus eventos in-app de usuários orgânicos com parceiros externos, esses parâmetros são OBRIGATÓRIOS. Além disso, alguns recursos, como Públicos, contam com a ID do dispositivo para segmentar seus usuários e atualizar as redes. -
Opcional –
eventValue
pode ser com um valor vazio, ou seja, "eventValue":"", (nenhum espaço é necessário) -
Opcional – O endereço IP (
ip
) deve ser o IP do dispositivo móvel (durante a ocorrência do evento) -
Opcional – O campo ID de usuário do cliente (
customer_user_id
) é um parâmetro identificador de usuário, mapeado para o campo ID de usuário do cliente nos relatórios brutos. A API do SDK do ID de usuário do cliente anexa esse valor automaticamente a todos os eventos in-app com origem no SDK. Certifique-se de incluir esse campo em TODOS os seus eventos S2S para desfrutar da mesma funcionalidade.
Preparação de dados para parâmetros
A lógica do back-end é necessária para obter certos valores para os parâmetros mencionados acima. Confira abaixo o fluxo recomendado para obter esses valores:
Mapeamento da ID da AppsFlyer com a ID de usuário cliente
A ID da AppsFlyer é um parâmetro obrigatório ao enviar eventos in-app de servidor para servidor. Para facilitar que você saiba qual usuário executou qual evento, implemente o fluxo abaixo:
- Defina a ID de usuário cliente quando o usuário instalar o aplicativo.
- Baixe o relatório de dados brutos de instalações por meio dos dados de exportação ou da API de pull
- Obtenha o ID da AppsFlyer combinando o ID de usuário cliente em seus sistemas internos com o ID de usuário cliente no relatório de dados brutos.
Observação: você pode obter o ID da AppsFlyer de seus usuários do SDK da AppsFlyer integrado em seus aplicativos (Android/iOS) - Mapeie a ID da AppsFlyer para a ID de usuário cliente em seu sistema interno (importante para uso futuro)
Após mapear a ID da AppsFlyer com sua ID de usuário cliente interna, você pode facilmente saber qual usuário executou qual evento. Você pode então obter a ID da AppsFlyer e outros valores (valor do evento, moeda do evento, hora do evento etc.) e enviar o evento in-app de servidor para servidor.
Cronometrar os eventos
Eventos de servidor para servidor podem ser enviados em tempo real ou com um carimbo de data hora do evento.
Você pode usar o parâmetro opcional eventTime
para especificar a hora da ocorrência do evento (no fuso horário UTC +0). Se o parâmetro não for incluído na mensagem, o AppsFlyer usa o carimbo de data e hora da mensagem HTTPS recebida.
O formato de eventTime
é: "aaaa-MM-dd HH:mm:ss.SSS" (por exemplo, "2014-05-15 12:17:00.000")
Ao enviar eventos com carimbos de data e hora, e para que esses eventos sejam registrados com seus carimbos em tempo real (quando realmente ocorreram), todos eles devem ser enviados para a AppsFlyer até as 2 h (UTC+0) do dia seguinte.
Eventos com carimbos de data e hora anteriores, os quais não são enviados até as 2 horas são registrados com a hora em que são enviados.
Evento com carimbo de data e hora enviado antes das 2 h UTC+0
Evento acionado: 2 de maio às 22h00
Evento enviado aos servidores do AppsFlyer: 3 de maio à 1h00
O evento é registrado na plataforma do AppsFlyer sob o tempo real em que o evento ocorreu (2 de maio às 22h00).
Evento com carimbo de data e hora enviado após as 2 h UTC+0
Evento enviado aos servidores do AppsFlyer: 4 de maio às 9h00
O evento é registrado na plataforma do AppsFlyer no momento em que ele é enviado ao servidor do AppsFlyer e não na hora em que o evento ocorreu (4 de maio às 09:00).
Evento com carimbos de data e hora futuros
Eventos enviados com carimbos de data e hora futuros são sempre registrados na AppsFlyer com a hora em que são enviados para a AppsFlyer, e não com o carimbo de data e hora do evento na carga.
Eventos de tempo: linha do tempo visual

Observação
O número máximo de solicitações S2S é de 60K por minuto ou 1K por segundo. Entre em contato com seu Gestor de sucesso do cliente se seus requisitos forem diferentes.
Códigos de retorno de serviço
- 200
- OK quando a solicitação foi processada pelo sistema da Appsflyer.
- 401
- não autorizado quando a chave fornecida no cabeçalho de autenticação não é a chave de desenvolvedor para esse aplicativo.
- 400
- Solicitação incorreta quando a solicitação falhou em pelo menos um dos critérios de validação
- 500
- Erro interno do servidor indica um erro no servidor
Se seus servidores forem protegidos por um firewall, você precisará fazer uma lista de respostas seguras recebidas dos intervalos de endereço IP da AWS para receber as mensagens de retorno.
Exemplo de corpo de solicitação
{
"appsflyer_id": "1415211453000-6513894",
"advertising_id": "38412345-8cf0-aa78-b23e-10b96e40000d",
"eventName": "af_purchase",
"eventValue":
"{
\"af_revenue\": \"6\",
\"af_content_type\": \"wallets\",
\"af_content_id\": \"15854\",
\"af_quantity\" :\"1\"
}",
"eventCurrency": "USD",
"ip": "1.2.3.4",
"eventTime": "2014-05-15 12:17:00.000",
"af_events_api" :"true"
}
Neste caso, o AppsFlyer recebe um evento no aplicativo S2S que representa um evento de compra com receita, bem como propriedades adicionais, tais como tipo de conteúdo, etc.
Casos especiais
Envio de receitas negativas
Se você quiser enviar um evento com receita negativa (como compra cancelada ou reembolso), é possível especificar o valor negativo no parâmetro da receita. Por exemplo:
{
"appsflyer_id": "1415211453000-6513894",
"advertising_id": "38412345-8cf0-aa78-b23e-10b96e40000d",
"eventName": "cancel_purchase",
"eventValue":
"{
\"af_revenue\": \"-6\",
\"af_content_type\": \"wallets\",
\"af_content_id\": \"15854\",
\"af_quantity\" :\"1\"
}",
"eventCurrency": "USD",
"ip": "1.2.3.4",
"eventTime": "2014-05-15 12:17:00.000",
"af_events_api" :"true"
}
Envio de eventos sem o valor do evento
Se você quiser enviar eventos sem o valor do evento, é só passar uma string vazia ao valor do evento: "event_value":""
Em seguida, o AppsFlyer é capaz, de acordo com a configuração do anunciante, de enviar esses eventos avançados no aplicativo para fontes de mídia para fins de direcionamento avançado, otimização e criação de público.
Buscar a ID do dispositivo AppsFlyer
appsflyer_id
é um parâmetro obrigatório em mensagens de evento de servidor para servidor. O AppsFlyer usa esse parâmetro para atribuir o evento ao dispositivo original e à fonte de mídia atribuída.
Existem várias maneiras de obter essa ID.
- A partir do dispositivo móvel usando a API do SDK da AppsFlyer (Android / iOS)
- Por meio das APIs Pull ou Push (clique no link para obter mais informações sobre a API Push ou a API Pull)
- Exportar o relatório deinstalação de dados brutos
Dica
Ao testar mensagens S2S, se você estiver usando dados brutos ou APIs push ou pull, procure o registro com fonte de mídia "s2s_test". Esse é o seu dispositivo de teste e essa ID de dispositivo AppsFlyer é a ID que você precisa.
Diferença entre orgânico e não orgânico
Ao enviar eventos in-app S2S, a AppsFlyer automaticamente associa dados adicionais aos eventos. Os dados adicionais vêm do evento de instalação que precede os eventos in-app.
O que isso significa é que alguns dados que a AppsFlyer associa a eventos in-app S2S não orgânicos não estão associados a eventos in-app S2S orgânicos.
Exemplo
Por exemplo, se você comparar relatórios de dados brutos de eventos in-app S2S não orgânicos e orgânicos, os eventos não orgânicos contêm dados que os eventos in-app não orgânicos não contêm.
Eventos in-app não orgânicos contém dados sobre a fonte de mídia, campanha, tipo de toque atribuído e hora do toque atribuído.
Eventos in-app orgânicos, por outro lado, seguem uma instalação orgânica. A instalação orgânica não possui dados relacionados a campanhas, fontes de mídia ou hora e tipo do toque atribuído.
Teste de eventos de servidor para servidor
- Desinstale o aplicativo do seu dispositivo de testes
- Prepare um link de atribuição personalizado para teste de mensagens S2S. O link deve incluir o nome da fonte de mídia "s2s_test" (&pid=s2s_test)
- Envie o link para o seu dispositivo de testes e clique nele
-
Instale e inicie o aplicativo
Agora você deve ter uma nova instalação com a versão mais recente do aplicativo. - Busque a nova ID de dispositivo AppsFlyer para usar em suas mensagens de teste
- Envie mensagens S2S com o novo ID de dispositivo da AppsFlyer. Confira exemplos de códigos abaixo:
/* using the okhttp package
install from maven https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp */
import okhttp3.*;
import java.io.IOException;
public class SendRequest {
public static void main(String[] args) {
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "" +
"{\r\n\t\"appsflyer_id\": \"<APPS_FLYER_ID>\"," +
"\r\n\t\"customer_user_id\": \"123456\",\r\n\t\"eventName\": \"af_purchase\",\r\n\t\"" +
"eventValue\": \"{\\\"af_revenue\\\":\\\"6\\\" ,\\\"af_content_id\\\":\\\"15854\\\"}\",\r\n\t\"" +
"eventCurrency\": \"USD\",\r\n\t\"" +
"eventTime\": \"2018-08-10 4:17:00.000\",\r\n\t\"" +
"af_events_api\" :\"true\"\r\n}");
Request request = new Request.Builder()
.url("https://api2.appsflyer.com/inappevent/<APP_ID>")
.post(body)
.addHeader("Content-Type", "application/json")
.addHeader("authentication", "<YOUR_DEV_KEY>")
.build();
try {
Response response = client.newCall(request).execute();
System.out.println(response.code());
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
''' using the requests python package, install using pip install requests '''
import requests
import json
url = "https://api2.appsflyer.com/inappevent/<APP_ID>" # i.e. com.appsflyer.sampleapp
payload = {
"appsflyer_id": "<APPS_FLYER_ID>",
"eventName": "af_purchase",
"eventValue": "{\"af_revenue\":\"7\" ,\"af_content_type\":\"wallets\"}",
"eventCurrency": "USD",
"ip": "1.0.0.0",
"eventTime": "2018-09-02 15:17:00.000",
"af_events_api" :"true"
}
headers = {
"authentication": "<YOUR_DEV_KEY>",
'Content-Type': 'application/json'
}
res = requests.request("POST", url, headers=headers, json=payload)
print(res)
print(res.text)
/* using the request npm package, install using npm install request */
var request = require("request");
var options = { method: 'POST',
url: 'https://api2.appsflyer.com/inappevent/<APP_ID>',
headers:
{
"authentication": '<YOUR_DEV_KEY>',
'Content-Type': 'application/json'
},
body:
{ appsflyer_id: '<APPS_FLYER_ID>',
customer_user_id: '123456',
eventName: 'node_js',
eventValue: '{"node_js":"6" ,"af_content_id":"15854"}',
eventCurrency: 'USD',
ip: '1.0.0.0',
eventTime: '2018-07-09 4:17:00.000',
af_events_api: 'true' },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
/* using the RestSharp package, install using NuGet */
using System;
using RestSharp;
namespace CS
{
class Event
{
static void Main(string[] args)
{
var client = new RestClient("https://api2.appsflyer.com/inappevent/<APP_ID>");
var request = new RestRequest(Method.POST);
request.AddHeader("authentication", "<YOUR_DEV_KEY>");
request.AddHeader("Content-Type", "application/json");
var body = "{\"appsflyer_id\": \"<APPS_FLYER_ID>\"," +
"\"customer_user_id\": \"123456\"," +
"\"eventName\": \"af_purchase\"," +
"\"eventValue\": \"{\\\"af_revenue\\\":\\\"6\\\" ,\\\"af_content_id\\\":\\\"15854\\\"}\"," +
"\"eventCurrency\": \"USD\"," +
"\"eventTime\": \"2018-07-08 4:17:00.000\"," +
"\"af_events_api\" :\"true\"}";
request.AddParameter("undefined", body, ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
// handle response by reading response.StatusCode
Console.WriteLine(response.Content);
}
}
}
$purchase_event = array(
'appsflyer_id' => <APPS_FLYER_DEVICE_ID>,
'idfa' => <IDFA>,
'eventCurrency' => <PURCHASE_CURRENCY>,
'ip' => <DEVICE_ID_ADDRESS>,
'eventTime' => date("Y-m-d H:i:s.000", time()),
'af_events_api' => true
);
$purchase_event['eventName'] = 'af_purchase';
$purchase_event['eventValue'] = json_encode(array('af_revenue' => <PURCHASE_REVENUE>,
'af_price' => <PURCHASE_PRICE>,
'af_order_id' => <PURCHASE_ORDER_ID>,
'af_currency' => <PURCHASE_CURRENCY>,
'af_content_type' => <PURCHASE_TYPE>,
'af_quantity' => <PURCHASE_QUANTITY>,
'af_content' => <PRODUCT_NAME>,
'af_content_id' => <PRODUCT_ID>)
);
$data_string = json_encode($purchase_event);
$ch = curl_init('https://api2.appsflyer.com/inappevent/<YOUR_APP_ID>');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'authentication: <YOUR_APPS_FLYER_DEV_TOKEN>',
'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($ch);
$curl = curl_init();
7. Baixe o relatório de dados brutos de eventos no aplicativo .
Verifique os valores enviados na coluna "event_value". Aguarde até 15 minutos após o envio do evento para que ele apareça no relatório de dados brutos.
Observação
Os dados brutos de eventos de servidor para servidor não incluem quaisquer valores originados no SDK, como nome do aplicativo, versão do SO, versão do aplicativo, etc.
Solução de problemas
Eventos S2S não estão aparecendo no painel
- Verifique se o endpoint usado para enviar o evento está correto e se a sintaxe da carga também está correta. Veja aqui.
- Verifique se a ID do AppsFlyer que você está usando para acionar o evento é uma appsflyer_id verdadeira que realmente está instalada no seu aplicativo específico (não uma ID de teste fornecida na documentação). Veja aqui.
- Eventos S2S não suportam o envio de eventos em massa. Não é possível enviar vários eventos em massa (única solicitação com uma única carga que contém os dados de vários eventos). Cada evento deve ser enviado separadamente.
- Para ver o evento no painel de controle – certifique-se de que a data selecionada no painel de controle corresponde à data de instalação daquele dispositivo (appsflyer_id) e não à data do evento.
Para ver o evento no relatório de dados brutos – você deve selecionar a data do evento e NÃO a data da instalação.
Eventos S2S não mostram receitas
Se você enviar eventos S2S, mas sua receita não for registrada, certifique-se de que o JSON enviado esteja em formato de string. A parte mais importante é o parâmetro do valor do evento no JSON. Ele deve estar em formato de stringfield i.e.
"{\"af_revenue\":\"6\" ,\"af_content_type\":\"wallets\"}"
Se não estiver em formato de string, o valor do evento não será processado corretamente e a receita não poderá ser registrada.
Importante!
NÃO formate o valor de receita de forma alguma. Ele não deve conter separadores de vírgula, símbolo de moeda ou texto. Um evento de receita deve ser semelhante a 1234.56, por exemplo.
Erros e respostas do servidor
Mensagem de erro | Código de resposta | O que fazer |
---|---|---|
Falha ao autenticar | 400 | Certifique-se de passar a chave do desenvolvedor correta nos cabeçalhos: "authentication": "<MY_DEV_KEY>". |
appsflyer_id é um campo obrigatório | 400 | Certifique-se de passar o ID da AppsFlyer correto no JSON. Certifique-se também de que o JSON esteja em formato de string e formatado corretamente. |
Payload faltando ou que falhou no processamento | 400 |
Certifique-se de que o JSON esteja em formato de string e formatado corretamente. Este erro também retorna se mais de um evento for incluído na carga do JSON. Certifique-se de enviar um evento por solicitação. |
Erro interno do servidor | 500 | Verifique o JSON enviado como o payload. Certifique-se de que esteja em formato de string |