
# Criar uma integração de ponta a ponta

Este guia percorre tudo o que precisa para executar o <span data-t="appName">Your AI Connector</span> a partir do seu próprio código, sem nunca abrir o painel de controlo. No final, terá criado uma integração mínima que:

1. Autentica-se com uma chave de API
2. Cria um Agente de IA e configura o seu comportamento de assistente
3. Liga um canal de mensagens (usamos o WhatsApp Web como exemplo prático) e aponta-o para o Agente
4. Importa contactos
5. Envia e lê mensagens
6. Lê análises
7. Subscreve webhooks para eventos em tempo real

Cada passo contém uma ligação para o guia de recursos completo, para que possa aprofundar os detalhes quando precisar. Esta página é o mapa; os guias de recursos são o território.

> **Antes de começar.** O acesso à API é uma funcionalidade paga. Se o seu plano não a incluir, cada pedido devolverá `403`. Consulte [Acesso à API](../integrations/api-access.md) para confirmar se está ativado e [Autenticação](authentication.md) para conhecer todas as formas de transmitir a sua chave.

Todos os caminhos abaixo são relativos ao URL base:

```
https://api.youraiconnector.com/v1
```

---

## Passo 1 — Obter uma chave de API e fazer o seu primeiro pedido

A sua chave de API encontra-se na aplicação em **Definições → Integrações → Chave de API** — uma secção própria em Integrações, separada dos Webhooks, que só aparece quando o acesso à API está incluído no plano. Gere uma, copie-a e guarde-a num local seguro (um armazenamento de segredos no lado do servidor ou variável de ambiente — nunca no código do browser). As instruções completas estão em [Acesso à API](../integrations/api-access.md).

Assim que tiver uma chave, confirme que funciona chamando o endpoint de estado de funcionamento (health). Existem várias formas de enviar a chave; a mais simples é o parâmetro de consulta `?apiKey=`, mas para código real prefira o cabeçalho `X-API-Key` para que a chave nunca termine nos registos do servidor ou no histórico do navegador.

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/health?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const BASE = "https://api.youraiconnector.com/v1";
const headers = { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" };

const res = await fetch(`${BASE}/health`, { headers });
const data = await res.json();
console.log(data); // { "success": true, ... }
```

**Python**

```python
import requests

BASE = "https://api.youraiconnector.com/v1"
HEADERS = {"X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json"}

res = requests.get(f"{BASE}/health", headers=HEADERS)
print(res.json())  # { "success": true, ... }
```

Todas as respostas bem-sucedidas são envolvidas no mesmo envelope — um campo `success: true` mais os dados do resultado. Os erros devolvem `success: false` com uma mensagem `error` e um `error_code`. Consulte [Erros e Paginação](errors-and-pagination.md) para obter a lista completa e saber como os endpoints de lista paginam com `?limit` e `?cursor`.

> **Limite de taxa.** Os pedidos autenticados estão limitados a **300 por minuto** (com um teto mais alargado de 1.200/minuto por conta). Ultrapassar este limite devolve `429`; aguarde e tente novamente.

---

## Passo 2 — Criar um Agente de IA

Um **Agente de IA** é a unidade que contém o comportamento do seu assistente: as suas instruções, o seu objetivo, o seu horário de funcionamento e a forma como fala com os contactos. É o que responde a uma conversação, por isso é a primeira coisa natural a criar.

Crie um com `POST /agents`. `name` é o único campo que vale a pena enviar inicialmente; tudo o resto pode ser definido com a chamada bot-config abaixo.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/agents" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Inbound WhatsApp Leads",
    "language": "en"
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/agents`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    name: "Inbound WhatsApp Leads",
    language: "en",
  }),
});
const { agent_id } = await res.json();
```

**Python**

```python
res = requests.post(
    f"{BASE}/agents",
    headers=HEADERS,
    json={"name": "Inbound WhatsApp Leads", "language": "en"},
)
agent_id = res.json()["agent_id"]
```

Uma criação bem-sucedida devolve `201` com o novo ID:

```json
{
  "success": true,
  "agent_id": "abc123agent"
}
```

**Guarde o `agent_id`** — irá referenciá-lo ao encaminhar canais.

### Configurar o assistente

`PUT /agents/{agentId}/bot-config` define o comportamento do assistente. *Combina* os campos que envia com a configuração existente, pelo que tudo o que não incluir é preservado:

```bash
curl -X PUT "https://api.youraiconnector.com/v1/agents/abc123agent/bot-config" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "instructions": "Greet warmly, answer questions about our services, and offer to book a call.",
    "goal": "Book a discovery call.",
    "ai_speed": "balanced"
  }'
```

Defina o horário de funcionamento com `PUT /agents/{agentId}/active-hours` para que o assistente responda apenas durante o horário de expediente; fora desses períodos, não responde automaticamente.

> **Base de conhecimento.** Para que o assistente responda com base no seu próprio conteúdo, anexe FAQs. Consulte o [guia de FAQs](faqs.md).

> **Legado: campanhas clássicas.** As contas que ainda possuem uma página de **Campanhas** criam o mesmo comportamento de assistente numa campanha (`POST /campaigns` com um objeto `type` e um `bot`, depois `PUT /campaigns/{campaignId}/bot-config`). A lista completa de campos de campanha e controlos de ciclo de vida encontra-se no [guia de Campanhas](campaigns.md). Se está a criar algo novo, crie um Agente.

---

## Passo 3 — Ligar um canal

Um Agente precisa de uma forma de enviar e receber mensagens. Sete fluxos de ligação podem ser geridos a partir da API: WhatsApp Business, WhatsApp Web, Instagram e Messenger em conjunto (um fluxo Meta partilhado), contas pessoais do Instagram, Telegram, LINE e Viber. Os restantes canais — SMS, e-mail, o widget de chat e canais personalizados, entre outros — são configurados no painel de controlo e não via REST, e uma vez ligados, os endpoints de mensagens, contactos e encaminhamento funcionam exatamente da mesma forma. `GET /channels` é a fonte de verdade em tempo real sobre o que uma determinada conta tem efetivamente ligado:

```bash
curl "https://api.youraiconnector.com/v1/channels?apiKey=YOUR_API_KEY"
```

O conjunto completo de fluxos de ligação/desligação para cada canal está documentado no [Guia de Canais](channels.md). Abaixo, percorremos o **WhatsApp Web** de ponta a ponta, porque mostra o padrão mais interessante: um fluxo de emparelhamento por código QR que o seu wrapper tem de renderizar e consultar.

### Exemplo prático: emparelhar WhatsApp Web por código QR

O emparelhamento do WhatsApp Web é uma dança de três chamadas — **iniciar**, **obter o QR**, **consultar até ligar**.

**1. Iniciar a sessão de emparelhamento.** Indique o número que pretende ligar no formato E.164.

```bash
curl -X POST "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "phone_number": "+15551230000" }'
```

```javascript
await fetch(`${BASE}/channels/whatsapp-web/connections`, {
  method: "POST",
  headers,
  body: JSON.stringify({ phone_number: "+15551230000" }),
});
```

```python
requests.post(
    f"{BASE}/channels/whatsapp-web/connections",
    headers=HEADERS,
    json={"phone_number": "+15551230000"},
)
```

**2. Obter o código QR e mostrá-lo ao utilizador.** Consulte este endpoint a cada 10–15 segundos. A resposta inclui o payload `qr_code` bruto (renderize-o como uma imagem QR) e um `qr_data_url` pronto a exibir.

```bash
curl "https://api.youraiconnector.com/v1/channels/whatsapp-web/connections/+15551230000/qr?apiKey=YOUR_API_KEY"
```

```json
{
  "success": true,
  "phone_number": "+15551230000",
  "status": "qr_pending",
  "qr_code": "2@abc...",
  "qr_data_url": "data:image/png;base64,iVBORw0KGgo..."
}
```

Na interface do seu wrapper, coloque o `qr_data_url` diretamente num `<img src="...">` e peça ao utilizador para o digitalizar a partir de **WhatsApp → Dispositivos Ligados** no seu telemóvel. Se o QR expirar (uma resposta `410`), reinicie a partir do passo 1 para obter um novo.

**3. Consultar o estado até ligar.** Após o utilizador digitalizar, continue a consultar o endpoint de estado até que este reporte `connected` (o serviço também pode reportar `open`). Trate `disconnected` e `not_initialized` como falhas terminais.

```python
import time

PHONE = "+15551230000"
while True:
    res = requests.get(
        f"{BASE}/channels/whatsapp-web/connections/{PHONE}/status",
        headers=HEADERS,
    )
    status = res.json()["status"]
    if status in ("connected", "open"):
        print("Connected!")
        break
    if status in ("disconnected", "not_initialized"):
        raise RuntimeError(f"Pairing failed: {status}")
    time.sleep(5)
```

```javascript
async function waitForConnection(phone) {
  while (true) {
    const res = await fetch(
      `${BASE}/channels/whatsapp-web/connections/${encodeURIComponent(phone)}/status`,
      { headers }
    );
    const { status } = await res.json();
    if (status === "connected" || status === "open") return;
    if (status === "disconnected" || status === "not_initialized") {
      throw new Error(`Pairing failed: ${status}`);
    }
    await new Promise((r) => setTimeout(r, 5000));
  }
}
```

> **Atenção.** Cada número de WhatsApp Web ligado acarreta uma taxa de manutenção mensal recorrente até que o desligue (`DELETE /channels/whatsapp-web/connections/{phoneNumber}`).

### Encaminhar o canal para o seu Agente

Ligar um canal faz com que funcione; encaminhá-lo diz à plataforma *qual o Agente de IA* que deve responder a novas conversações recebidas. Defina o Ponto de Entrada predefinido do canal, indicando o Agente que criou no Passo 2:

```bash
curl -X PUT "https://api.youraiconnector.com/v1/entry-points/channel-defaults" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "channel": "whatsapp_web", "agent_id": "abc123agent" }'
```

Repita a chamada uma vez por canal — um ponto de entrada predefinido por canal. Para deixar um canal sem um Agente a responder, chame `DELETE /entry-points/channel-defaults?channel=whatsapp_web`; para verificar se a hierarquia de Pontos de Entrada está ativa para a conta, chame `GET /entry-points/routing-status`. O mapa `POST /channels/campaign` mais antigo é mantido apenas para reversão e já não é consultado para encaminhamento de entrada. Consulte o [guia de Canais](channels.md) para os outros tipos de canais e para o fluxo OAuth do WhatsApp Business.

---

## Passo 4 — Importe os seus contactos

Com um canal ativo, carregue as pessoas que pretende contactar. O endpoint de importação aceita até **500 registos por chamada**. Cada registo necessita de um `phone_number` em formato internacional; tudo o resto é opcional. Os registos com números inválidos, canais não suportados ou números que já existam são ignorados — e cada omissão é reportada com o respetivo índice e motivo, para que possa tentar novamente apenas as falhas.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/import" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "contacts": [
      { "phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee" },
      { "phone_number": "+12025551235", "first_name": "Bob" }
    ],
    "defaultChannel": "whatsapp_web"
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/contacts/import`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    contacts: [
      { phone_number: "+12025551234", first_name: "Ann", last_name: "Lee" },
      { phone_number: "+12025551235", first_name: "Bob" },
    ],
    defaultChannel: "whatsapp_web",
  }),
});
const result = await res.json();
console.log(`${result.imported} imported, ${result.skipped.length} skipped`);
```

**Python**

```python
res = requests.post(
    f"{BASE}/contacts/import",
    headers=HEADERS,
    json={
        "contacts": [
            {"phone_number": "+12025551234", "first_name": "Ann", "last_name": "Lee"},
            {"phone_number": "+12025551235", "first_name": "Bob"},
        ],
        "defaultChannel": "whatsapp_web",
    },
)
result = res.json()
print(f"{result['imported']} imported, {len(result['skipped'])} skipped")
```

A resposta indica-lhe exatamente o que aconteceu:

```json
{
  "success": true,
  "imported": 2,
  "contact_ids": ["contactId1", "contactId2"],
  "skipped": []
}
```

Para a criação individual, consulta de listas, listas, etiquetas e campos personalizados, consulte o [Guia de contactos](contacts.md).

---

## Passo 5 — Envie e leia mensagens

### Enviar uma mensagem

O envio mais simples é **agnóstico em relação ao canal**: forneça a identidade do contacto e o corpo da mensagem, e a plataforma entrega-a no canal em que o contacto se encontra. Pode direcionar por `contact_id`, ou por `channel` mais o campo de identidade correspondente (`phone_number` para WhatsApp/WhatsApp Web/SMS, `instagram_id` para Instagram, e assim sucessivamente).

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/contacts/send" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel": "whatsapp_web",
    "phone_number": "+12025551234",
    "body": "Hi Ann! Thanks for reaching out."
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/contacts/send`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    channel: "whatsapp_web",
    phone_number: "+12025551234",
    body: "Hi Ann! Thanks for reaching out.",
  }),
});
const { message_id } = await res.json();
```

**Python**

```python
res = requests.post(
    f"{BASE}/contacts/send",
    headers=HEADERS,
    json={
        "channel": "whatsapp_web",
        "phone_number": "+12025551234",
        "body": "Hi Ann! Thanks for reaching out.",
    },
)
message_id = res.json()["message_id"]
```

A entrega é **assíncrona** — um `201` significa que a mensagem foi *aceite e colocada na fila*, ainda não entregue. (Os contactos com o modo 'não incomodar' ou modo privado ativado são rejeitados com um `422`.)

```json
{
  "success": true,
  "message_id": "aB3dE5fG7hI9jK1lM2nO",
  "contact_id": "contact123",
  "channel": "whatsapp_web"
}
```

### Ler uma conversa

Para ler as mensagens recebidas, liste-as por contacto, da mais recente para a mais antiga, com paginação por cursor. Passe o `next_cursor` de uma resposta como o `cursor` da seguinte para percorrer o histórico.

```bash
curl "https://api.youraiconnector.com/v1/contacts/contact123/messages?limit=50&apiKey=YOUR_API_KEY"
```

```python
res = requests.get(
    f"{BASE}/contacts/contact123/messages",
    headers=HEADERS,
    params={"limit": 50},
)
page = res.json()
for msg in page["messages"]:
    print(msg)
next_cursor = page["next_cursor"]  # pass back as ?cursor= for the next page
```

Também pode filtrar por tipo de conteúdo (`?filter=text|media|tool_use`) ou direção (`?direction=inbound|outbound`). O [Guia de mensagens](messages.md) abrange anexos multimédia, marcação de mensagens como lidas e as vistas de mensagens por sessão.

> **Não faça polling para obter respostas.** Listar mensagens com um temporizador funciona, mas desperdiça pedidos e aumenta a latência. Para mensagens recebidas, utilize webhooks — esse é o Passo 7.

---

## Passo 6 — Ler análises

Assim que as mensagens começam a fluir, o resumo de análise fornece contagens agregadas num intervalo de datas: enviadas, entregues, lidas, respondidas, agendadas, contactos criados e créditos gastos/recarregados. Obtém tanto os totais do intervalo como uma série diária preenchida com zeros — ideal para um gráfico de painel. Opcionalmente, limite a uma única campanha com `campaign_id` (os exemplos abaixo utilizam um ID de campanha de marcador de posição, `abc123campaign`); omita o parâmetro para obter totais de toda a conta.

```bash
curl "https://api.youraiconnector.com/v1/analytics/summary?from=2026-05-01&to=2026-05-31&campaign_id=abc123campaign&apiKey=YOUR_API_KEY"
```

```javascript
const params = new URLSearchParams({
  from: "2026-05-01",
  to: "2026-05-31",
  campaign_id: "abc123campaign",
});
const res = await fetch(`${BASE}/analytics/summary?${params}`, { headers });
const { totals, by_date } = await res.json();
```

```python
res = requests.get(
    f"{BASE}/analytics/summary",
    headers=HEADERS,
    params={"from": "2026-05-01", "to": "2026-05-31", "campaign_id": "abc123campaign"},
)
data = res.json()
totals = data["totals"]
by_date = data["by_date"]
```

O intervalo predefinido é de 30 dias e está limitado a 366. Para registos de utilização crédito a crédito e detalhe de custos de IA, consulte o [Guia de análises](analytics.md).

---

## Passo 7 — Subscrever webhooks para eventos em tempo real

A consulta (polling) é aceitável para um script rápido, mas uma integração real deve ser **baseada em push**. Os webhooks permitem que a plataforma chame o *seu* servidor no momento em que algo acontece — um novo contacto, uma resposta, uma marcação agendada, uma conversa concluída.

Primeiro, descubra os nomes exatos dos eventos aos quais pode subscrever:

```bash
curl "https://api.youraiconnector.com/v1/webhooks/events?apiKey=YOUR_API_KEY"
```

```json
{
  "success": true,
  "events": [
    "Contact Created",
    "Human Alerted",
    "Appointment Booked",
    "Replies",
    "New Message",
    "Chat Concluded",
    "Task Created",
    "Daily Summary Created"
  ]
}
```

Depois, crie uma subscrição que aponte para um URL HTTPS no seu servidor. Utilize as strings de evento exatas da chamada acima.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "name": "Lead updates hook"
  }'
```

**JavaScript**

```javascript
const res = await fetch(`${BASE}/webhooks`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    url: "https://hooks.example.com/incoming",
    subscribed_to: ["Contact Created", "Replies"],
    name: "Lead updates hook",
  }),
});
const { webhook_id } = await res.json();
```

**Python**

```python
res = requests.post(
    f"{BASE}/webhooks",
    headers=HEADERS,
    json={
        "url": "https://hooks.example.com/incoming",
        "subscribed_to": ["Contact Created", "Replies"],
        "name": "Lead updates hook",
    },
)
webhook_id = res.json()["webhook_id"]
```

```json
{
  "success": true,
  "webhook_id": "1",
  "webhook": {
    "id": "1",
    "name": "Lead updates hook",
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "subscribed_to_tags": [],
    "created_at": "2026-06-09T12:00:00.000Z"
  }
}
```

O URL deve utilizar HTTPS e ser publicamente acessível. A partir daqui, o seu servidor recebe um POST para cada evento subscrito. Pode enviar um teste de entrega, verificar o estado de uma subscrição e reativar uma subscrição que tenha sido desativada automaticamente após falhas repetidas — consulte o [Guia de webhooks](webhooks.md) e a página de [Webhooks](../integrations/webhooks.md) ao nível das integrações para formatos de payload e verificação.

---

## Juntar tudo

Aqui tem todo o fluxo num relance:

| Passo | Objetivo | Chamada principal |
|---|---|---|
| 1 | Autenticar | `GET /health` |
| 2 | Criar + ajustar o assistente | `POST /agents`, `PUT /agents/{id}/bot-config`, `PUT /agents/{id}/active-hours` |
| 3 | Ligar um canal e encaminhá-lo | `POST /channels/whatsapp-web/connections` → ler QR + estado → `PUT /entry-points/channel-defaults` |
| 4 | Carregar contactos | `POST /contacts/import` |
| 5 | Enviar & ler | `POST /contacts/send`, `GET /contacts/{id}/messages` |
| 6 | Medir | `GET /analytics/summary` |
| 7 | Reagir em tempo real | `POST /webhooks` |

Um wrapper mínimo consiste apenas nestas sete chamadas integradas na sua própria interface. A partir daí, adicione os guias por recurso conforme precisar de mais:

- [Campanhas](campaigns.md) · [Contactos](contacts.md) · [FAQs](faqs.md) · [Mensagens](messages.md) · [Marcações](appointments.md)
- [Canais](channels.md) · [Modelos](templates.md) · [Análises](analytics.md) · [Webhooks](webhooks.md) · [Chaves de API](api-keys.md)
- Novo por aqui? [Introdução](getting-started.md) · [Autenticação](authentication.md) · [Erros & Paginação](errors-and-pagination.md)

Stuck on something this guide does not cover? Email [<span data-t="supportEmail">hi@youraiconnector.com</span>](mailto:hi@youraiconnector.com).
