# Fiwano — Documentação da API

API REST unificada para WhatsApp, Instagram e Facebook Messenger.

> Esta página está em português do Brasil para facilitar a leitura. Os endpoints, nomes de campos, headers, event names, valores de enumeração e exemplos JSON continuam em inglês porque a API funciona com esses identificadores.

| | |
|---|---|
| **Base URL** | `/api/v1` |
| **Formato** | JSON |
| **Autenticação** | header `X-API-Key` |
| **n8n nodes** | [`n8n-nodes-fiwano`](https://www.npmjs.com/package/n8n-nodes-fiwano) no npm |

---

## Capacidades dos Canais

Os três canais são conectados pelo mesmo fluxo OAuth. A tabela mostra o que cada canal suporta.

| Recurso | WhatsApp | Instagram | Facebook Messenger |
|---|---|---|---|
| Texto outbound | Sim | Sim | Sim |
| Limite de texto outbound | 4096 chars | 1000 chars | 2000 chars |
| Mídia outbound (Pro) | image, audio, video, document | image, video, audio | image, audio, video, file |
| Template messages (Pro) | Sim, obrigatório fora da janela de 24h | Não suportado | Não suportado |
| Webhooks inbound — texto | `type: "text"` | `type: "text"` | `type: "text"` |
| Webhooks inbound — mídia (Pro) | image, audio, video, document, sticker | image, audio, video, file | image, audio, video, file |
| Webhooks inbound — mídia (Starter) | `type: "unsupported"` + `upgrade_required: "pro"` | Mesmo comportamento | Mesmo comportamento |
| Status de entrega | `sent` `delivered` `read` `failed` | `delivered` `read` | `delivered` `read` |
| Formato do destinatário | Número sem `+` (ex.: `1234567890`) | IGSID — de `data.from` nos webhooks | PSID — de `data.from` nos webhooks |
| Fora da janela de 24h | Usar approved templates | Aguardar mensagem do usuário | Aguardar mensagem do usuário |
| Identificador do canal | `phone_number_id` | `ig_account_id` | `page_id` |
| Perfil do remetente | `data.from_name` (Meta contacts) | Via [profile endpoint](#perfil-do-remetente) | Via [profile endpoint](#perfil-do-remetente) |

> Cada conta Meta (número de telefone, conta Instagram ou Facebook Page) só pode estar conectada a um usuário Fiwano por vez.

---

## Licenças

Cada canal conectado precisa de uma licença ativa.

| Plano | Mensal | Recursos |
|---|---|---|
| **Starter** | $12 | Mensagens de texto inbound/outbound ilimitadas e status de entrega |
| **Pro** | $19 | Tudo do Starter + mídia inbound com arquivos, mídia outbound por HTTPS URL, gerenciamento e envio de WhatsApp templates |

Novas contas começam com teste gratuito de 7 dias (tier Pro). Upgrade e gestão de assinatura ficam na página Billing do portal.

---

## Autenticação

Todas as chamadas exigem uma API key no header `X-API-Key`.

Crie a chave em **API Keys** no portal. A chave completa aparece **uma única vez**. Guarde com segurança. Chaves perdidas não podem ser recuperadas; revogue e crie uma nova.

```bash
curl https://fiwano.com/api/v1/channels \
  -H "X-API-Key: YOUR_API_KEY"
```

Todas as chaves começam com `mip_live_`. No servidor, armazenamos apenas hashes.

---

## Conectando Canais

### Opção A: Pelo Portal (self-service)

1. Abra **Channels → Connect Channel** no portal.
2. Escolha o tipo de canal: WhatsApp, Instagram ou Facebook Messenger.
3. Complete o fluxo Meta OAuth no popup.
4. Configure a **Webhook URL** e selecione **Webhook Events** nas configurações do canal.
5. Por padrão, nenhum evento vem ativado. Selecione explicitamente quais eventos enviar ao seu endpoint.

Um `webhook_secret` é gerado automaticamente quando você define a primeira webhook URL. Use esse segredo para verificar assinaturas dos webhooks recebidos.

### Opção B: Pela API (programático)

Use este fluxo quando sua aplicação conecta canais em nome dos seus próprios clientes.

**Passo 1.** Registrar redirect URIs:

```bash
curl -X POST https://fiwano.com/api/v1/redirects \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"uri_pattern": "https://yourapp.com/callback"}'
```

**Passo 2.** Solicitar uma setup URL válida por 10 minutos:

```bash
curl -X POST https://fiwano.com/api/v1/channels/setup-url \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"channel_type": "whatsapp", "redirect_uri": "https://yourapp.com/callback"}'
```

A resposta contém `setup_url`. Abra essa URL no navegador ou em um popup para o usuário.

**Passo 3.** O usuário completa o Meta OAuth. Depois da aprovação, ele volta para seu `redirect_uri` com um `code` de uso único:

```text
https://yourapp.com/callback?code=abc123...
```

Se o usuário cancelar: `?error=access_denied`.

**Passo 4.** Trocar o code e, opcionalmente, configurar webhook em até 5 minutos:

```bash
curl -X POST https://fiwano.com/api/v1/channels/exchange-code \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "code": "abc123...",
    "webhook_url": "https://yourapp.com/webhooks/meta",
    "webhook_secret": "your-optional-secret",
    "webhook_events": ["message.received", "message.delivered", "message.failed"]
  }'
```

A resposta retorna `channel_id`, detalhes do canal e `webhook_secret` (gerado automaticamente se não enviado). Todos os campos exceto `code` são opcionais e podem ser configurados depois via `PATCH /api/v1/channels/{id}`.

> Importante: por padrão, nenhum evento é entregue. Configure `webhook_events` explicitamente para receber webhooks.

---

## Channels

### GET /api/v1/channels

Lista todos os canais da sua conta, ativos e inativos.

```bash
curl https://fiwano.com/api/v1/channels \
  -H "X-API-Key: YOUR_API_KEY"
```

Campos principais da resposta:

| Campo | Descrição |
|---|---|
| `id` | Channel ID usado nas outras chamadas |
| `channel_type` | `whatsapp`, `instagram` ou `facebook` |
| `name` | Nome exibido do canal |
| `is_active` | `true` se o canal pode enviar/receber mensagens |
| `phone_number_id` | Apenas WhatsApp — ID Meta do número |
| `phone_number` | Apenas WhatsApp — número legível |
| `waba_id` | Apenas WhatsApp — WhatsApp Business Account ID |
| `ig_account_id` | Apenas Instagram — Instagram account ID |
| `ig_username` | Apenas Instagram — username |
| `page_id` | Instagram/Facebook — linked Facebook Page ID |
| `webhook_url` | Endpoint onde mensagens inbound são entregues |
| `has_webhook_secret` | Indica se há webhook secret configurado |
| `webhook_events` | Eventos habilitados, ex.: `["message.received", "message.delivered"]` |
| `token_expires_at` | Expiração do access token; refresh automático 7 dias antes |
| `subscription` | Estado da licença/assinatura |

#### `subscription` object

| Campo | Tipo | Descrição |
|---|---|---|
| `status` | string | `active`, `expired`, `canceled` ou `none` |
| `source` | string \| null | `trial`, `paddle`, `enterprise` ou `null` |
| `tier` | string \| null | `starter` ou `pro`; `pro` é necessário para mídia e templates |
| `expires_at` | string \| null | Timestamp UTC ISO-8601 do fim do período atual |
| `auto_renew` | boolean | `true` para assinatura Paddle ativa com renovação automática |

### GET /api/v1/channels/{channel_id}

Retorna detalhes de um canal específico no mesmo formato da lista.

```bash
curl https://fiwano.com/api/v1/channels/a1b2c3d4e5f67890 \
  -H "X-API-Key: YOUR_API_KEY"
```

### POST /api/v1/channels/setup-url

Gera uma URL OAuth para conectar um novo canal.

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `channel_type` | string | Sim | `whatsapp`, `instagram` ou `facebook` |
| `redirect_uri` | string | Sim | Precisa bater com uma redirect URI cadastrada |

### POST /api/v1/channels/exchange-code

Troca um completion code de uso único pelos dados do canal e pode configurar webhook.

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `code` | string | Sim | Code do OAuth redirect; expira em 5 minutos; uso único |
| `webhook_url` | string | Não | HTTPS URL para webhooks inbound |
| `webhook_secret` | string | Não | Segredo HMAC customizado |
| `webhook_events` | string[] | Não | Eventos a entregar; se omitido, nenhum evento é entregue |

### PATCH /api/v1/channels/{channel_id}

Atualiza nome, webhook, events ou status ativo do canal.

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `name` | string | Não | Nome interno do canal |
| `webhook_url` | string | Não | HTTPS URL para receber webhooks |
| `webhook_secret` | string | Não | Segredo HMAC para assinatura |
| `webhook_events` | string[] | Não | Lista de eventos habilitados |
| `is_active` | boolean | Não | Ativa/desativa envio e recebimento |

### DELETE /api/v1/channels/{channel_id}

Desconecta e remove o canal da Fiwano. Tokens armazenados são apagados.

---

## Enviando Mensagens

### POST /api/v1/messages/send

Envia uma mensagem de texto por qualquer canal conectado.

```bash
curl -X POST https://fiwano.com/api/v1/messages/send \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "channel_id": "a1b2c3d4e5f67890",
    "to": "1234567890",
    "text": "Hello from Fiwano"
  }'
```

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `channel_id` | string | Sim | Channel ID |
| `to` | string | Sim | Destinatário: telefone sem `+`, IGSID ou PSID |
| `text` | string | Sim | Texto da mensagem |

Limites: WhatsApp 4096 chars, Instagram 1000 chars, Facebook Messenger 2000 chars. Respostas de erro incluem `message_too_long` quando o limite é excedido.

Erros transitórios da Meta entram em retry quando seguro. Erros permanentes, como destinatário inválido, retornam erro imediatamente.

### POST /api/v1/messages/send-template

Envia um WhatsApp template aprovado. Requer canal WhatsApp e tier Pro.

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `channel_id` | string | Sim | Channel ID WhatsApp |
| `to` | string | Sim | Telefone sem `+` |
| `template_name` | string | Sim | Nome do template aprovado |
| `language_code` | string | Sim | Ex.: `en_US`, `pt_BR` |
| `components` | array | Não | Variáveis/header/buttons conforme Meta |

### POST /api/v1/messages/send-media

Envia mídia por HTTPS URL. Requer tier Pro.

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `channel_id` | string | Sim | Channel ID |
| `to` | string | Sim | Destinatário |
| `media_url` | string | Sim | HTTPS URL acessível pela Meta |
| `media_type` | string | Sim | `image`, `audio`, `video`, `document` ou `file` conforme canal |
| `caption` | string | Não | Legenda quando suportada |
| `filename` | string | Não | Nome de arquivo para documentos/files |

---

## Arquivos de Mídia

### GET /api/v1/media/{media_id}

Baixa mídia recebida. Links são temporários e devem ser buscados com sua `X-API-Key`.

```bash
curl https://fiwano.com/api/v1/media/m123 \
  -H "X-API-Key: YOUR_API_KEY" \
  -o file.bin
```

---

## WhatsApp Templates

Operações de template exigem canal WhatsApp e tier Pro. O status final depende da aprovação da Meta.

### GET /api/v1/channels/{channel_id}/templates

Lista templates do canal.

### GET /api/v1/channels/{channel_id}/templates/{template_id}

Retorna detalhes de um template específico.

### POST /api/v1/channels/{channel_id}/templates

Cria um template no WhatsApp.

| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| `name` | string | Sim | Nome do template |
| `category` | string | Sim | Categoria Meta, ex.: `MARKETING`, `UTILITY`, `AUTHENTICATION` |
| `language` | string | Sim | Ex.: `en_US`, `pt_BR` |
| `components` | array | Sim | Componentes conforme formato da Meta |

### PUT /api/v1/channels/{channel_id}/templates/{template_id}

Atualiza um template quando a Meta permite edição.

### DELETE /api/v1/channels/{channel_id}/templates/{template_id}

Remove um template.

---

## Webhooks Recebidos

A Fiwano entrega eventos para sua `webhook_url` em HTTPS. Cada request é assinado com HMAC-SHA256.

### Verificação de Assinatura

Cada webhook contém headers:

| Header | Descrição |
|---|---|
| `X-Fiwano-Signature` | Assinatura HMAC-SHA256 do payload |
| `X-Fiwano-Timestamp` | Timestamp usado na assinatura |
| `X-Fiwano-Event` | Event type, ex.: `message.received` |
| `X-Trace-ID` | ID para debug e suporte |

Verifique a assinatura usando o `webhook_secret` configurado no canal.

### Event Types

| Event | Quando ocorre |
|---|---|
| `message.received` | Nova mensagem inbound |
| `message.delivered` | Mensagem entregue |
| `message.read` | Mensagem lida |
| `message.failed` | Falha de envio/entrega |

### Delivery Status Tracking

A Fiwano normaliza status da Meta em `sent`, `delivered`, `read` e `failed` quando o canal suporta esses eventos.

### Formato de Payload

O payload usa a mesma estrutura de alto nível para todos os canais:

```json
{
  "event": "message.received",
  "channel_id": "a1b2c3d4e5f67890",
  "channel_type": "whatsapp",
  "data": {
    "message_id": "wamid...",
    "from": "1234567890",
    "from_name": "Customer Name",
    "type": "text",
    "text": "Hello",
    "timestamp": "2026-05-20T10:30:00Z"
  }
}
```

#### message.received (WhatsApp)

`data.from` é o telefone do usuário sem `+`. Para mídia Pro, `data.type` pode ser `image`, `audio`, `video`, `document` ou `sticker` e o payload inclui `media` com `media_id`, `mime_type`, `filename` quando disponível e URL temporária para download.

#### message.received (Instagram)

`data.from` é o IGSID. Use o profile endpoint para buscar nome/foto quando necessário.

#### message.received (Facebook Messenger)

`data.from` é o PSID. Use o profile endpoint para buscar dados de perfil quando permitido.

#### message.received — mídia (Pro)

Mídia inbound inclui uma referência de download temporária. Você deve baixar rapidamente, autenticar com `X-API-Key` e armazenar no seu lado se precisar reter o arquivo.

#### message.received — unsupported type (Starter)

No Starter, mídia inbound é entregue como:

```json
{
  "event": "message.received",
  "data": {
    "type": "unsupported",
    "upgrade_required": "pro"
  }
}
```

#### message.delivered / message.read

Eventos de status usam `data.message_id`, `data.status` e timestamps normalizados.

#### message.failed

Falhas incluem `data.error_code`, `data.error_message` e dados técnicos retornados pela Meta quando disponíveis.

### Política de Retry

Se seu endpoint estiver temporariamente indisponível, a Fiwano faz até 7 tentativas durante aproximadamente 11 minutos. Payloads em retry são criptografados em repouso e têm TTL rígido de 20 minutos. Após sucesso ou expiração, o payload é apagado. Falhas persistentes geram alerta por e-mail.

### Perfil do Remetente

Alguns canais expõem perfil do remetente de forma limitada. Quando a Meta permite, use o endpoint abaixo.

---

## Perfil do Remetente

### GET /api/v1/channels/{channel_id}/profile/{user_id}

Busca perfil do usuário em Instagram ou Facebook Messenger quando permitido pela Meta.

```bash
curl https://fiwano.com/api/v1/channels/a1b2c3d4e5f67890/profile/USER_ID \
  -H "X-API-Key: YOUR_API_KEY"
```

---

## Redirect URIs

Redirect URIs são usadas no fluxo programático de conexão de canais.

### GET /api/v1/redirects

Lista padrões cadastrados.

### POST /api/v1/redirects

Cadastra um novo padrão.

```bash
curl -X POST https://fiwano.com/api/v1/redirects \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"uri_pattern": "https://yourapp.com/callback"}'
```

### DELETE /api/v1/redirects/{redirect_id}

Remove um padrão cadastrado.

---

## Erros e Rate Limits

### HTTP Status Codes

| Status | Significado |
|---|---|
| `200` / `201` | Sucesso |
| `400` | Request inválido |
| `401` | API key ausente ou inválida |
| `403` | Sem permissão, licença insuficiente ou canal inativo |
| `404` | Recurso não encontrado |
| `409` | Conflito de estado |
| `422` | Validação falhou |
| `429` | Rate limit excedido |
| `500` | Erro interno |

### Error Format

```json
{
  "error": "invalid_request",
  "message": "Human-readable error message",
  "details": {}
}
```

### Rate Limits

O limite padrão é 100 requests por minuto por API key, salvo acordo específico.

---

## Integração n8n

A Fiwano tem community nodes para n8n.

### Instalação

#### Pelo editor do n8n (recomendado)

1. Abra o painel de nodes.
2. Procure por `Fiwano`.
3. Clique em Install.
4. Configure sua API key.

#### Fallback manual (npm)

```bash
npm install n8n-nodes-fiwano
```

### Nodes

| Node | Uso |
|---|---|
| Fiwano Trigger | Inicia workflows com mensagens inbound e status de entrega |
| Fiwano Action | Envia mensagens, gerencia canais, templates e setup URLs |

### Action node — operations

Operações comuns: send text, send media, send template, list channels, create setup URL, manage templates.

### Trigger node — events

Eventos suportados: `message.received`, `message.delivered`, `message.read`, `message.failed`.

### Exemplo de workflow

`Fiwano Trigger` → `AI Agent` → `Fiwano Send`.

---

## Notas Importantes

- A API pública, os payloads, nomes de campos e event names permanecem em inglês.
- WhatsApp exige templates aprovados para iniciar conversas fora da janela de 24 horas.
- O cliente é responsável por consentimento, opt-in, conteúdo das mensagens e políticas da Meta.
- Mensagens entregues com sucesso não são armazenadas permanentemente pela Fiwano.
- Payloads em retry são criptografados e apagados no sucesso ou após TTL rígido de 20 minutos.
- Paddle atua como Merchant of Record para cobrança, impostos, faturas e reembolsos.
- Para dúvidas, escreva para `contact@fiwano.com`.
