# Contacts API

Com o link encurtado haverá um redirecionamento para o link-alvo e o registro do evento `redirect_request` ou `pixel_request`.&#x20;

O `pixel_request` é utilizado para identificar seu usuário quando acessa um email de engajamento, no qual pode-se identificar a abertura desta uma mensagem por meio da pixel requisitado.&#x20;

### Introdução

Contacts API é o micro serviço para encurtar URLs, redirecionamento e criação de links para pixel de e-mails. O Contacts API absorveu as antigas api's, API Redirect Links e API Pixel, criando apenas em um único *endpoint* para gerar esses recursos.&#x20;

Agora, você tem um único local para enviar os dados de contato, criar um link encurtado e o pixel, automaticamente. Com esses recursos é possível colocar estes links em suas mensagens de SMS, E-mail ou campanhas melhorando a experiências dos usuários, além de oferecer um link de pixel de identificação que pode ser utilizado em campanhas por e-mail, para gerenciar os envios e identificar as etapas em que o cliente se encontram.

### O que você precisa saber sobre Contacts API antes de começar?

1. Todos os campos enviados no payload serão salvos para cada contato e podem ser utilizados para interpolação.
2. Os nomes dos campos serão mantidos como CASE SENSITIVE onde NOME, Nome, nome são campos diferentes.
3. Você precisará fornecer o modelo desta base de contatos enviando no `payload.model_name`.
4. Você precisará enviar uma descrição do modelo enviando no `payload.model_description`.
5. Você precisará enviar os campos enviados em um forma de uma lista separada por vírgulas em `payload.model_fields`. Os campos informados aqui serão utilizados para analytics, ou seja, serão enviados para o `destination` definido pelo cliente, por exemplo, Elastic.&#x20;
   1. Esses campos não são públicos para o destino do link por exemplos os clientes que clicaram no link enviado.
   2. Esses campos serão automaticamente adicionados ao evento `redirect_request` como [extra\_data](#introducao) (42). Desta forma, times de operações como Marketing e Customer Success podem acompanhar de forma granular e analítica a interação do contato com cada link. O evento redirect\_request é disparado quando um link AgnosticData é clicado.&#x20;
   3. Os campos enviados no payload e não informados em `model_fields` somente poderão ser acessados via consulta de banco de dados. Isso é útil quando o time de dados tem interesse em determinadas informações, mas elas não podem ficar disponíveis para os times operacionais.&#x20;
6. No máximo 2.000 contatos são processos por requisição.
7. Para a criação de urls encurtadas automaticamente requer informar o campo `hash` de cada contato com o texto `"auto"`
   1. Caso seja necessário (não recomendado) poderá enviar seu próprio hash, mas precisará garantir que seja único em toda a base enviada, pois LEMBRE-SE: se um documento existente der erro salvar por conflito de hash, por exemplo dos 2.000 enviados, irá cancelar toda a requisição de todos os itens da lista (lote) não sendo possível identificar individualmente qual deles estava duplicado.
8. É requerida uma URL para compor a rota. Disponibilizamos por padrão `https://agno.cc/HASH`. Mas, você pode criar um domínio para ser implementado como seu domínio encurtado.&#x20;

```javascript
// EXEMPLO:
 
 url_encurtada = "https://agno.cc/HASH_CODE" 
 // hash_code sempre será a chave primária do link
```

### Aspectos técnicos

#### O que é e como utilizar a interpolação via qs\_target

**qs\_target** é um string que contém toda a querystring para interpolação de variáveis para a URL de destino ou redirecionamento esperado.&#x20;

````python
```python
{
  "qs_target": "?&acid={{CODE}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}"
}
```
````

Você deverá enviar *obrigatoriamente* o campo **`qs_target`** para realizar a interpolação dos valores dos campos enviados (lembre-se que são CASE SENSITIVE) .&#x20;

**Exemplo:**&#x20;

Quando você envia um campo chamado `CODE` e desejar que ele seja exposto na *querystring* da URL de destino preencha o `qs_target` com algo como `"?campanha={{CODE}}".` Ao receber o campo CODE e o qs\_target com {{CODE}} algoritmo irá entender que deverá interpolar a *querystring,* substituindo a expressão {{CODE}} pelo valor do campo enviado do item de contato.&#x20;

#### Interpolação de pixel\_url

De forma similar, você pode criar uma url com uma imagem de 1px para ser inserida no e-mail e acompanhar como o padrão de mercado, a interação básica de leitura sobre aquela mensagem.

**Note**: *as soluções de e-mail já informam ao remetente quando um determinado usuário (destinatário) ler uma mensagem, porém essa configuração pode ser alterada pelos usuários, por isso o mercado utiliza atualmente um pixel que permite interpretar esse cenário*.

{% hint style="warning" %}
**IMPORTANTE**: você não precisa criar pixel\_url a partir da v2 desta API (31 agosto de 2024). A API irá retornar o campo shorten\_url\_v2 que contém o shorten\_url + "?agp=true". Ao adicionar agp=true a uma shorten url o comportamento do redirecionamento será de devolver um pixel e não um redirecionamento de URL. Obviamente deve ser inserido dentro de uma tag \<img com src="shorten+agp=true" />
{% endhint %}

É **requerido** para interpolar enviar para cada "linha" do contato o campo `pixel_url` com a PIXEL\_URL\_BASE do Agnostic Data + doc (identificador do pixel ou apid) + variáveis. Abaixo temos um exemplo.

* PIXEL\_URL\_BASE = `https://utils.agnosticdata.ai/v2/?api_key=API_KEY&project_id=PROJECT_ID&f=pixel&doc=UNIQUE_PIXEL_ID`
  * `onde:`&#x20;
    * URL\_PIXEL = `https://utils.agnosticdata.ai/v2/`
    * `api_key = chave do projeto`
    * `project_id = identificador do projeto no Agnostic Data`
    * `f = função de leitura de pixel`
    * `doc = identificador único do pixel, geralmente sha256 do identificador do cliente.`&#x20;
* **Interpolação**: E você poderá concatenar mais dados, além da variável doc, tornando-os mais lúcido para estratégias de (re)marketing como utm\_source, utm\_content, etc, conforme o exemplo: `https://utils.agnosticdata.ai/v2/?api_key=API_KEY&project_id=PROJECT_ID&f=pixel&doc={{hash}}&acid={{acid}}&apid={{CODE}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}`

Por fim, para utilizar uma `pixel_url` do Agnostic Data, se essa eventualmente existir, basta acessar a url do serviço:

```
https://utils.agnosticdata.ai/v2/?api_key=CHAVE_DO_PROJETO&project_id=ID_DO_PROJETO&f=pixel&doc={{hash}}
```

{% hint style="info" %}
**Fique por dentro**

O `hash_code` da URL encurtada sempre será a chave primária (id) dos links e/ou pixel. Contudo você poder localizar um pixel por um campo específico, no caso, o identificador do usuário ou um identificador único. Coloque `` &fdoc=NOME_DO_CAMPO` ``como querystring do atributo "`pixel_url`", onde `NOME_DO_CAMPO` é um campo enviado no payload `{data:{...}},` com isso você identificar o usuário que abriu o e-mail`.`&#x20;
{% endhint %}

#### Exemplos de interpolação

Suponha que você tenha as variáveis `campanha`,`utm_source`, `utm_medium`, `utm_campaign` e `utm_content` com valores, `ABC`, `cenprot`, `email`, `campanha01` e `pf`, respectivamente. Para interpolar para a querystring final, teremos uma `qs_target` parecida com:

```
?campanha={{CODE}}utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}
```

que resultará em (exemplo):

```
?campanha=ABC&utm_source=cenprot&utm_medium=email&utm_campaign=campanha01&utm_content=pf
```

Para isso você enviou junto ao payload, os dados abaixo:

```javascript
{ data: {
    //... dados do payload
    "model_name": "meu_modelo_01", 
    "model_description": "dados de cnpj", 
    "model_fields": "CODE, utm_source, utm_medium, utm_campaign, utm_content",
    contacts:[
        {
            "CODE": "ABC", 
            "utm_source": "cenprot", 
            "utm_medium": "email", 
            "utm_campaign": "campanha01", 
            "utm_content": "pf"
        }
    ]
}
```

#### **Exemplo de aplicação do PIXEL em e-mails HTML**

Crie uma imagem no seu template, coloque no atributo src a url `pixel_url` gerada nesta API.&#x20;

```html
<!-- seu código ou template de email -->
<img width="1px" height="1px" src="https://utils.agnosticdata.ai/v2/?api_key=CHAVE_DO_PROJETO&project_id=ID_DO_PROJETO&f=pixel&doc={{UNIQUE_PIXEL_ID}}" />
```

**✅ doc é requerido:** `doc` refere-se ao hash do pixel de um determinado usuário. É o identificador único. Veja mais sobre fdoc para alterar o atributo que será utilizado como "chave primária".&#x20;

### Atribuições

#### Atributos complementares que podem ser mapeados da querystring do pixel URL

Os campos a seguir são previamente conhecidos e podem ser utilizados no Agnostic Data para ajudar no seu compromisso da melhor prestação de serviço e suporte. Os campos que também podem ser enviados como querystring são:

* `acid`: identificação direta (chave primária) de um usuário do seu sistema (aplicativo, ambiente). NÃO USE DOCUMENTOS PESSOAIS.
* `apsid`: identificação de um usuário anônimo
* `vv`: o valor desta interação
* `cc`: moeda sobre o custo (custo de marketing, aquisição, click, envio de email, etc)

além das UTMs

* `utm_source`: Identifica a fonte do tráfego, como o nome do mecanismo de busca, boletim informativo ou outro referenciador Exemplo: utm\_source=google
* `utm_medium`: Define o meio de marketing utilizado, como e-mail, CPC (custo por clique), banner, entre outros. Exemplo: utm\_medium=cpc
* `utm_campaign`: Usado para identificar uma campanha de marketing específica. É útil para segmentar dados de diferentes campanhas. Exemplo: utm\_campaign=primavera\_sale
* `utm_term`: Principalmente usado para rastreamento de palavras-chave em campanhas de publicidade paga. Identifica os termos de pesquisa pagos. Exemplo: utm\_term=sapatos+de+corrida
* `utm_content`: Usado para diferenciar anúncios ou links semelhantes que apontam para a mesma URL. Pode ser útil em testes A/B. Exemplo: utm\_content=logotipo\_link ou utm\_content=texto\_link
* `utm_id`: Um parâmetro menos comum que pode ser usado para identificar especificamente uma campanha com um ID único.

#### 🪪 \[avançado] Atribuições com dados pessoais: Complete Data para Contacts

Ao criar seus contatos você passou campos padronizados de dados complementares de usuários (complete\_data), além dos seus campos personalizados e do seu interesse, eles serão utilizados para permitir conhecer seu cliente (KYC), que é bastante útil para times de Customer Success e Atendimento (pode responder questões como *qual cliente está navegando neste funcionalidade agora?*).&#x20;

Na etapa de criação dos contatos é possível enviar os campos complementares que chamamos de \`complete\_data\`. São eles:

* `complete_data_save` // se true informará ao serviço contacts para salvar os dados pessoais junto a mesma tupla (ou documento) dos links.&#x20;
* `complete_data_has_hash` || "base64" // pode ser base64 ou sha256 ou plain; se não informado será base64. Use "plain" se desejar que os dados sejam humanamente legíveis pera time de suporte, operações e customer success.
* `complete_data_email` || null
* `complete_data_phone` || null
* `complete_data_firstname` || null
* `complete_data_lastname` || null
* `complete_data_date_born` || null
* `complete_data_gender` || null
* `complete_data_city` || null
* `complete_data_neighborhood` || null
* `complete_data_state` || null
* `complete_data_zipcode` || null
* `complete_data_country` || null
* `complete_data_order_id` || null
* `complete_data_ps_id_ga` || null // pseudo id dos caras google measurement id
* `complete_data_ps_id_fb` || null // pseudo id facebook pixel id
* `complete_data_ps_id_uc` || null // pseudo id uxcam
* `complete_data_ps_id_sg` || null // pseudo id segment
* `complete_data_ps_id_hj` || null // pseudo id hotjar
* `complete_data_ps_id_ap` || null // pseudo id amplitude
* `complete_data_install_id` || null // application install hash id apple ou android

#### IMPORTANTE: hash e fdoc

**hash**

Por padrão o hash gerado é a chave primária do redirect e pixel (Ex.: https//curta.url/hash) e também o campo ***doc***. Assim o hash e doc serão os mesmos e significa que o pixel será localizado pelo hash. Contudo, em alguns casos isso pode ser um impeditivo ou porque um HASH de 6 dígitos seja insuficiente e/ou não representativo para o pixel que geralmente contém a identificação de um usuário específico com SHA256 de um documento pessoal.

**fdoc**

Para modificar o \`doc\` você pode informar qual campo terá o identificador único utilizando `fdoc` ou (acrônimo de field document) para identificar o campo que irá representar o `doc` para a pixel\_url.

No exemplo abaixo, a chave primária será o atributo do payload chamado CODE. Consulte o exemplo do payload em "Exemplos de interpolação".&#x20;

```javascript
//...
let pixel_url = `${PIXEL_URL_BASE}&fdoc=CODE&doc={{hash}}...`
```

### Enviando via javascript

```javascript
// PROJECT SETUP
const api_key = process.env.AGNOSTIC_API_KEY
const project_id = process.env.AGNOSTIC_PROJECT_ID

// DEFAULT URL-TARGETs
const URL_CONTACT_API = 'https://contacts.agnosticdata.ai/v2/?api_key=' + api_key + '&project_id=' + project_id + '&f=contacts'
const PIXEL_URL_BASE = 'https://utils.agnosticdata.ai/v2/?api_key=' + api_key + '&project_id=' + project_id + '&f=pixel'

// SAMPLE qs_target
let qs_target = "?campanha={{CODE}}&apid={{CODE}}&acid={{acid}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}";
// SAMPLE pixel_url
let pixel_url = `${PIXEL_URL_BASE}&fdoc=CODE&doc={{CODE}}&acid={{acid}}&apid={{CODE}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}`;

// SAMPLE data 
const payload = {data: { // contactsData
  model_name: "contacts",
  model_description: "contacts",
  model_fields: "name,email,phone",
  contacts: [{ // array of contacts
      CODE: "test-91817-4151-8f24-3910c7cadb13", hash: "auto", 
      qs_target: "?campanha={{CODE}}&apid={{CODE}}&acid={{acid}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}", 
      pixel_url: `${PIXEL_URL_BASE}&fdoc=CODE&doc={{CODE}}&acid={{acid}}&apid={{CODE}}&utm_source={{utm_source}}&utm_medium={{utm_medium}}&utm_campaign={{utm_campaign}}&utm_term={{utm_term}}&utm_content={{utm_content}}`,
      shorten_url: "https://rslv.cc/", target_url: "https://resolve.cenprot.org.br/app/", 
      utm_source: "fonte", utm_medium: "email", utm_campaign: "campanhaX", utm_content: "pf", utm_term: "livros%2Bcadernos%2Bcanetas", 
      acid: "meu-uuid-uniq-user",
      _controle: "seu_controle_de_envios_ou_lista_nome"}]
    }
  }

// POST 
const response = await request.post(URL_CONTACT_API)
  .set('Content-Type', 'application/json')
  .set('Accept', 'application/json')
  .send(payload);

// console.log(response) 
// { 
//    status: 200, 
//    data: JSON.stringify(outputData), 
//    message: `#[adai][utils][set_contacts] ${contacts.length} contacts saved successfully` 
}    
```

**Analogamente a uma planilha os dados de envio teriam as colunas**

Onde `shorten_url` e `target_url` precisam terminar com barra (/).&#x20;

A `shorten_url` é a url base para automaticamente compor algo similar a `https://shorten_url/hash/` . **Obs.: Barra no final**&#x20;

A `target_url` a url da página é a página para onde o usuário será redirecionado ao clicar na shorten\_url que foi gerada automaticamente. E, a target\_url é automaticamente composta com os *Dados de Marketing* para localização das campanhas que irá gerar a `redirect_to`.  Geralmente, o time de marketing não precisa da redirect\_to, pois é utilizada pelo algoritmo redirecionador.&#x20;

<figure><img src="/files/20DiVzDTZM9Qh9KYIgOt" alt=""><figcaption><p>Dados de interpolação</p></figcaption></figure>

<figure><img src="/files/DDF1M8XW5ERy5P8Ldyho" alt="" width="375"><figcaption><p>Dados de Marketing</p></figcaption></figure>

<figure><img src="/files/htf9wot1mXm4gvfkc6pm" alt="" width="201"><figcaption><p>Dados de controle</p></figcaption></figure>

**Retorno**

```json
{
	"status": 200,
	"message": "#[adai][utils][set_contacts] 1 contacts saved successfully",
	"data": [
		{
			"NR_CHAVE": "NR_CHAVE",
			"firstname": "firstname",
			"LAST_NM_SACADO": "LAST_NM_SACADO",
			"lastname": "lastname",
			"DT_NASCIMENTO_SACADO": "DT_NASCIMENTO_SACADO",,
			"CODE": "CODE", // Exemplo: id do user em sha256
			"hash": "BY288K", // vc envou "auto" e a API gerou esse
			"ACID": "ACID", // user ID não obrigatório
			"utm_souce": "utm_souce", // campos de marketing
			"utm_medium": "utm_medium", // campos de marketing
			"utm_campaign": "utm_campaign", // campos de marketing
			"utm_content": "utm_content", // campos de marketing
			"utm_term": "utm_term", // campos de marketing
			"pixel_url": "", //DEPRECATED: não necessário (url interpolada para utilizar marketing)
			"shorten_url": "shorten_urlBY288K", // url encurtada recebida
			"target_url": "target_url", // *obrigatório: url de destino
			"qs_target": "", // querystring para completar a target_url (opcional)
			"redirect_to": "target_url", // url gerada como destino da shorten_url
			"scope": "api_key:project_id",
			"model_fields": "nome,lugar,objeto",
			"model_name": "newco_padrao_01",
			"model_description": "contém dados de usuários de protestos",
			"is_active": true,
			"user_id": "Rei Naldo Benny", // quem enviou 
			"created": {
				"_seconds": 1709891619,
				"_nanoseconds": 351000000
			},
			"updated": {
				"_seconds": 1709891619,
				"_nanoseconds": 351000000
			}
		}
	]
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.agnosticdata.ai/agnosticdata.ai-or-documentation/fundamentals/contacts-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
