# Zapini API — Kanban

**Version:** 1.0.0
**Base URL:** `https://zapini.app/api/v1`

---

## Authentication

All endpoints require a Bearer Token:

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

Generate API tokens in your admin panel under **API Docs → Manage Tokens**.

---

## Kanban API

**Base path:** `/api/v1/kanban`
**Requirement:** `kanban_enabled` must be true on your tenant account.

The Kanban API provides full CRUD access to boards, columns, and leads. Use it to build CRM integrations, automate pipeline management, or sync with external tools.

---

## Boards

### List Boards
`GET /api/v1/kanban/boards`

Returns all Kanban boards for the authenticated instance.

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

**Response:**
```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"
    }
  ]
}
```

---

### Create Board
`POST /api/v1/kanban/boards`

Creates a new board with default columns (New Lead, Qualified, Proposal, Negotiation, Won, Lost).

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | Yes | Board name |
| description | string | No | Board description |
| is_default | boolean | No | Set as default board |

```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"
```

---

### Get Board
`GET /api/v1/kanban/boards/{uuid}`

Returns board details with statistics and columns.

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

**Response includes `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
  }
}
```

---

### Update Board
`PUT /api/v1/kanban/boards/{uuid}`

| Field | Type | Description |
|-------|------|-------------|
| name | string | Board name |
| description | string | Board description |
| is_default | boolean | Set as default (unsets others) |
| auto_detect_leads_enabled | boolean | Enable auto lead detection |
| auto_detect_score_threshold | integer | Min score (0–100) for auto detection |

---

### Delete Board
`DELETE /api/v1/kanban/boards/{uuid}`

Deletes the board and all its columns and leads.

---

## Columns

### List Columns
`GET /api/v1/kanban/boards/{board_uuid}/columns`

Returns columns ordered by position.

---

### Create Column
`POST /api/v1/kanban/boards/{board_uuid}/columns`

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| name | string | Yes | Column name |
| color | string | No | Hex color (e.g. `#3B82F6`) |
| position | integer | No | Column position (appended if omitted) |
| wip_limit | integer | No | Max leads in this column |
| is_final | boolean | No | Whether this is a final stage column |

---

### Reorder Columns
`POST /api/v1/kanban/boards/{board_uuid}/columns/reorder`

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

---

### Update Column
`PUT /api/v1/kanban/columns/{uuid}`

| Field | Type | Description |
|-------|------|-------------|
| name | string | Column name |
| color | string | Hex color |
| wip_limit | integer | WIP limit |
| is_final | boolean | Final stage flag |
| min_ai_score | integer | Min AI score for auto-routing |
| max_ai_score | integer | Max AI score for auto-routing |

---

### Delete Column
`DELETE /api/v1/kanban/columns/{uuid}`

| Query | Type | Description |
|-------|------|-------------|
| move_leads_to_uuid | string | UUID of column to move leads to (optional) |

---

## Leads

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

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| status | string | open | `open` \| `won` \| `lost` \| `all` |
| priority | string | — | `low` \| `medium` \| `high` \| `urgent` |
| column_uuid | string | — | Filter by column |
| search | string | — | Search by title, phone, email, notes |

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

---

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

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| board_uuid | string | Yes | Target board UUID |
| column_uuid | string | No | Target column (first column if omitted) |
| title | string | Yes | Lead title |
| phone_number | string | Yes | Contact phone number |
| email | string | No | Contact email |
| value | decimal | No | Deal value |
| priority | string | No | `low` \| `medium` \| `high` \| `urgent` |
| notes | string | No | Initial notes |
| due_date | date | No | Due date (YYYY-MM-DD) |
| custom_fields | object | No | Custom key-value fields |

```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"
```

**Response:**
```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"
  }
}
```

---

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

Returns full lead details including notes, custom_fields, ai_analysis, and lost_reason.

---

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

| Field | Type | Description |
|-------|------|-------------|
| title | string | Lead title |
| phone_number | string | Phone number |
| email | string | Email |
| value | decimal | Deal value |
| priority | string | Priority level |
| notes | string | Notes |
| due_date | date | Due date |
| custom_fields | object | Custom fields |

---

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

Soft-deletes the lead (can be recovered from database).

---

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

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

If `position` is omitted, the lead is appended at the end. Moving to a "Won" or "Lost" final column automatically sets the lead status.

---

### Mark as Won
`POST /api/v1/kanban/leads/{uuid}/won`

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

---

### Mark as Lost
`POST /api/v1/kanban/leads/{uuid}/lost`

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

---

### Add Note
`POST /api/v1/kanban/leads/{uuid}/note`

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

Notes are appended with timestamp and user name.

---

### Get Activities
`GET /api/v1/kanban/leads/{uuid}/activities`

Returns the full activity timeline for a lead.

**Response:**
```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"
    }
  ]
}
```

---

### AI Qualify Lead
`POST /api/v1/kanban/leads/{uuid}/ai-qualify`

Runs AI analysis on the lead (requires AI integration configured).

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

---

## Error Codes

| Code | HTTP | Description |
|------|------|-------------|
| `NOT_FOUND` | 404 | Resource not found |
| `FORBIDDEN` | 403 | Kanban not enabled for this account |
| `VALIDATION_ERROR` | 422 | Validation failed — check `error.details` |
| `MOVE_FAILED` | 422 | Cannot move lead (e.g. WIP limit reached) |
| `NO_AI_PROVIDER` | 422 | No AI integration configured |
| `INSTANCE_REQUIRED` | 400 | `instance_uuid` required for Sanctum auth |
| `NO_BOARD` | 422 | No Kanban board found for tenant |
| `UNAUTHORIZED` | 401 | Invalid or missing token |
| `SERVER_ERROR` | 500 | Internal server error |

---

*Generated by Zapini — https://zapini.app*
