# Zapini API — Kanban

**Versão:** 1.0.0
**Base URL:** `https://zapini.app/api/v1`

---

## Autenticação

Todos os endpoints requerem um Bearer Token:

```
Authorization: Bearer sk_your_api_token
Accept: application/json
Content-Type: application/json
```

Gere tokens de API no painel admin em **API Docs → Gerenciar Tokens**.

---

## Kanban API

**Base path:** `/api/v1/kanban`
**Requisito:** `kanban_enabled` deve ser true na sua conta de tenant.

A API Kanban fornece acesso CRUD completo a quadros, colunas e leads. Use-a para criar integrações de CRM, automatizar o gerenciamento de pipeline ou sincronizar com ferramentas externas.

---

## Quadros

### Listar Quadros
`GET /api/v1/kanban/boards`

Retorna todos os quadros Kanban para a instância autenticada.

```bash
curl -s -H "Authorization: Bearer sk_your_token" \
  "https://zapini.app/api/v1/kanban/boards"
```

**Resposta:**
```json
{
  "success": true,
  "data": [
    {
      "uuid": "board-uuid",
      "name": "Sales Pipeline",
      "description": null,
      "is_default": true,
      "whatsapp_instance_uuid": "instance-uuid",
      "auto_detect_leads_enabled": false,
      "auto_detect_score_threshold": 50,
      "columns_count": 6,
      "created_at": "2026-01-01T00:00:00+00:00"
    }
  ]
}
```

---

### Criar Quadro
`POST /api/v1/kanban/boards`

Cria um novo quadro com colunas padrão (Novo Lead, Qualificado, Proposta, Negociação, Ganho, Perdido).

| Campo | Tipo | Obrigatório | Descrição |
|-------|------|-------------|-----------|
| name | string | Sim | Nome do quadro |
| description | string | Não | Descrição do quadro |
| is_default | boolean | Não | Definir como quadro padrão |

```bash
curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{"name":"Q2 Pipeline","is_default":false}' \
  "https://zapini.app/api/v1/kanban/boards"
```

---

### Obter Quadro
`GET /api/v1/kanban/boards/{uuid}`

Retorna detalhes do quadro com estatísticas e colunas.

```bash
curl -s -H "Authorization: Bearer sk_your_token" \
  "https://zapini.app/api/v1/kanban/boards/board-uuid"
```

**Resposta inclui `stats`:**
```json
{
  "stats": {
    "total_leads": 12,
    "open_leads": 9,
    "won_leads": 2,
    "lost_leads": 1,
    "total_value": 15000.00,
    "won_value": 5000.00,
    "conversion_rate": 66.7,
    "avg_time_to_close": 14.5
  }
}
```

---

### Atualizar Quadro
`PUT /api/v1/kanban/boards/{uuid}`

| Campo | Tipo | Descrição |
|-------|------|-----------|
| name | string | Nome do quadro |
| description | string | Descrição do quadro |
| is_default | boolean | Definir como padrão (desmarca os outros) |
| auto_detect_leads_enabled | boolean | Habilitar detecção automática de leads |
| auto_detect_score_threshold | integer | Pontuação mínima (0–100) para detecção automática |

---

### Excluir Quadro
`DELETE /api/v1/kanban/boards/{uuid}`

Exclui o quadro e todas as suas colunas e leads.

---

## Colunas

### Listar Colunas
`GET /api/v1/kanban/boards/{board_uuid}/columns`

Retorna colunas ordenadas por posição.

---

### Criar Coluna
`POST /api/v1/kanban/boards/{board_uuid}/columns`

| Campo | Tipo | Obrigatório | Descrição |
|-------|------|-------------|-----------|
| name | string | Sim | Nome da coluna |
| color | string | Não | Cor hexadecimal (ex: `#3B82F6`) |
| position | integer | Não | Posição da coluna (adicionada no final se omitida) |
| wip_limit | integer | Não | Máximo de leads nesta coluna |
| is_final | boolean | Não | Se esta é uma coluna de estágio final |

---

### Reordenar Colunas
`POST /api/v1/kanban/boards/{board_uuid}/columns/reorder`

```json
{
  "order": ["col-uuid-1", "col-uuid-2", "col-uuid-3"]
}
```

---

### Atualizar Coluna
`PUT /api/v1/kanban/columns/{uuid}`

| Campo | Tipo | Descrição |
|-------|------|-----------|
| name | string | Nome da coluna |
| color | string | Cor hexadecimal |
| wip_limit | integer | Limite WIP |
| is_final | boolean | Flag de estágio final |
| min_ai_score | integer | Pontuação mínima de IA para roteamento automático |
| max_ai_score | integer | Pontuação máxima de IA para roteamento automático |

---

### Excluir Coluna
`DELETE /api/v1/kanban/columns/{uuid}`

| Consulta | Tipo | Descrição |
|---------|------|-----------|
| move_leads_to_uuid | string | UUID da coluna para mover os leads (opcional) |

---

## Leads

### Listar Leads
`GET /api/v1/kanban/boards/{board_uuid}/leads`

| Parâmetro | Tipo | Padrão | Descrição |
|-----------|------|--------|-----------|
| status | string | open | `open` \| `won` \| `lost` \| `all` |
| priority | string | — | `low` \| `medium` \| `high` \| `urgent` |
| column_uuid | string | — | Filtrar por coluna |
| search | string | — | Pesquisar por título, telefone, e-mail, observações |

```bash
curl -s -H "Authorization: Bearer sk_your_token" \
  "https://zapini.app/api/v1/kanban/boards/board-uuid/leads?status=open&priority=high"
```

---

### Criar Lead
`POST /api/v1/kanban/leads`

| Campo | Tipo | Obrigatório | Descrição |
|-------|------|-------------|-----------|
| board_uuid | string | Sim | UUID do quadro alvo |
| column_uuid | string | Não | Coluna alvo (primeira coluna se omitido) |
| title | string | Sim | Título do lead |
| phone_number | string | Sim | Número de telefone do contato |
| email | string | Não | E-mail do contato |
| value | decimal | Não | Valor do negócio |
| priority | string | Não | `low` \| `medium` \| `high` \| `urgent` |
| notes | string | Não | Observações iniciais |
| due_date | date | Não | Data de vencimento (YYYY-MM-DD) |
| custom_fields | object | Não | Campos personalizados chave-valor |

```bash
curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "board_uuid": "board-uuid",
    "title": "John Doe - Pro Plan",
    "phone_number": "5511999999999",
    "value": 299.00,
    "priority": "high"
  }' \
  "https://zapini.app/api/v1/kanban/leads"
```

**Resposta:**
```json
{
  "success": true,
  "data": {
    "uuid": "lead-uuid",
    "title": "John Doe - Pro Plan",
    "phone_number": "5511999999999",
    "value": "299.00",
    "value_formatted": "R$ 299,00",
    "priority": "high",
    "priority_label": "High",
    "source": "api",
    "ai_score": null,
    "is_open": true,
    "is_won": false,
    "is_lost": false,
    "is_overdue": false,
    "column": {
      "uuid": "col-uuid",
      "name": "New Lead",
      "color": "#3B82F6"
    },
    "created_at": "2026-01-01T00:00:00+00:00"
  }
}
```

---

### Obter Lead
`GET /api/v1/kanban/leads/{uuid}`

Retorna detalhes completos do lead incluindo notes, custom_fields, ai_analysis e lost_reason.

---

### Atualizar Lead
`PUT /api/v1/kanban/leads/{uuid}`

| Campo | Tipo | Descrição |
|-------|------|-----------|
| title | string | Título do lead |
| phone_number | string | Número de telefone |
| email | string | E-mail |
| value | decimal | Valor do negócio |
| priority | string | Nível de prioridade |
| notes | string | Observações |
| due_date | date | Data de vencimento |
| custom_fields | object | Campos personalizados |

---

### Excluir Lead
`DELETE /api/v1/kanban/leads/{uuid}`

Exclusão suave do lead (pode ser recuperado do banco de dados).

---

### Mover Lead
`POST /api/v1/kanban/leads/{uuid}/move`

```json
{
  "column_uuid": "target-column-uuid",
  "position": 0
}
```

Se `position` for omitido, o lead é adicionado no final. Mover para uma coluna final "Ganho" ou "Perdido" define automaticamente o status do lead.

---

### Marcar como Ganho
`POST /api/v1/kanban/leads/{uuid}/won`

```json
{
  "value": 299.00
}
```

---

### Marcar como Perdido
`POST /api/v1/kanban/leads/{uuid}/lost`

```json
{
  "reason": "Budget constraints"
}
```

---

### Adicionar Observação
`POST /api/v1/kanban/leads/{uuid}/note`

```json
{
  "note": "Interested in annual subscription. Follow up next week."
}
```

Observações são adicionadas com timestamp e nome do usuário.

---

### Obter Atividades
`GET /api/v1/kanban/leads/{uuid}/activities`

Retorna o histórico completo de atividades de um lead.

**Resposta:**
```json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "type": "created",
      "description": null,
      "metadata": { "column_name": "New Lead" },
      "user": { "id": 1, "name": "John" },
      "created_at": "2026-01-01T00:00:00+00:00",
      "created_at_human": "2 days ago"
    }
  ]
}
```

---

### Qualificar Lead com IA
`POST /api/v1/kanban/leads/{uuid}/ai-qualify`

Executa análise de IA no lead (requer integração de IA configurada).

**Resposta:**
```json
{
  "success": true,
  "data": {
    "lead": { "uuid": "...", "ai_score": 82 },
    "ai_result": {
      "score": 82,
      "analysis": { "summary": "High-intent lead...", "strengths": [] }
    }
  }
}
```

---

## Códigos de Erro

| Código | HTTP | Descrição |
|--------|------|-----------|
| `NOT_FOUND` | 404 | Recurso não encontrado |
| `FORBIDDEN` | 403 | Kanban não habilitado para esta conta |
| `VALIDATION_ERROR` | 422 | Falha de validação — verifique `error.details` |
| `MOVE_FAILED` | 422 | Não é possível mover o lead (ex: limite WIP atingido) |
| `NO_AI_PROVIDER` | 422 | Nenhuma integração de IA configurada |
| `INSTANCE_REQUIRED` | 400 | `instance_uuid` necessário para autenticação Sanctum |
| `NO_BOARD` | 422 | Nenhum quadro Kanban encontrado para o tenant |
| `UNAUTHORIZED` | 401 | Token inválido ou ausente |
| `SERVER_ERROR` | 500 | Erro interno do servidor |

---

*Gerado por Zapini — https://zapini.app*
