# Zapini API — Calendar

**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**.

---

## Calendar API

**Base path:** `/api/v1/calendar`
**Requirement:** No special permission required — all tenants can manage appointments.

---

## Appointment Statuses

| Status | Description |
|--------|-------------|
| `scheduled` | Initial status — appointment is booked |
| `confirmed` | Client confirmed attendance |
| `completed` | Appointment was completed |
| `cancelled` | Appointment was cancelled |
| `no_show` | Client did not show up |

---

## Appointments

### List Appointments
`GET /api/v1/calendar/appointments`

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| start | date | Start of month | Range start (ISO 8601) |
| end | date | End of month | Range end (ISO 8601) |
| status | string | — | Filter by status |
| per_page | integer | 50 | Items per page |

```bash
curl -s -H "Authorization: Bearer sk_your_token" \
  "https://zapini.app/api/v1/calendar/appointments?start=2026-05-01&end=2026-05-31"
```

---

### Create Appointment
`POST /api/v1/calendar/appointments`

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| title | string | Yes | Appointment title |
| description | string | No | Details |
| client_name | string | No | Client name |
| client_phone | string | No | Client phone |
| client_email | string | No | Client email |
| starts_at | datetime | Yes | Start time (ISO 8601) |
| ends_at | datetime | Yes | End time (must be after starts_at) |
| all_day | boolean | No | All-day event |
| location | string | No | Location or meeting URL |
| color | string | No | Hex color code |
| reminder_minutes | integer | No | Minutes before to send reminder (0–10080) |

```bash
curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Consultation with John Doe",
    "client_name": "John Doe",
    "client_phone": "5511999999999",
    "starts_at": "2026-05-01T10:00:00",
    "ends_at": "2026-05-01T11:00:00",
    "location": "Online - Google Meet",
    "reminder_minutes": 30
  }' \
  "https://zapini.app/api/v1/calendar/appointments"
```

**Response:**
```json
{
  "success": true,
  "data": {
    "uuid": "appt-uuid",
    "title": "Consultation with John Doe",
    "client_name": "John Doe",
    "client_phone": "5511999999999",
    "starts_at": "2026-05-01T10:00:00+00:00",
    "ends_at": "2026-05-01T11:00:00+00:00",
    "all_day": false,
    "duration_minutes": 60,
    "location": "Online - Google Meet",
    "status": "scheduled",
    "color": "#3b82f6",
    "reminder_minutes": 30,
    "created_at": "2026-01-01T00:00:00+00:00"
  }
}
```

---

### Get Appointment
`GET /api/v1/calendar/appointments/{uuid}`

Returns appointment details including `created_by` user.

---

### Update Appointment
`PUT /api/v1/calendar/appointments/{uuid}`

Same fields as Create. Additionally supports `status` field.

---

### Delete Appointment
`DELETE /api/v1/calendar/appointments/{uuid}`

---

### Confirm Appointment
`POST /api/v1/calendar/appointments/{uuid}/confirm`

Transitions status from `scheduled` to `confirmed`.

```bash
curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  "https://zapini.app/api/v1/calendar/appointments/appt-uuid/confirm"
```

---

### Complete Appointment
`POST /api/v1/calendar/appointments/{uuid}/complete`

Transitions status to `completed` and sets `completed_at`.

---

### Cancel Appointment
`POST /api/v1/calendar/appointments/{uuid}/cancel`

Returns `422 CANNOT_CANCEL` if appointment is already completed or cancelled.

---

### Convert to Kanban Lead
`POST /api/v1/calendar/appointments/{uuid}/to-kanban`

Creates a Kanban lead from this appointment. Requires `kanban_enabled` on your tenant.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| board_uuid | string | No | Target board UUID (uses default board if omitted) |

```bash
curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{"board_uuid": "optional-board-uuid"}' \
  "https://zapini.app/api/v1/calendar/appointments/appt-uuid/to-kanban"
```

**Response:**
```json
{
  "success": true,
  "data": {
    "lead_uuid": "new-lead-uuid",
    "board_uuid": "board-uuid",
    "board_name": "Sales Pipeline"
  }
}
```

---

## Error Codes

| Code | HTTP | Description |
|------|------|-------------|
| `NOT_FOUND` | 404 | Resource not found |
| `VALIDATION_ERROR` | 422 | Validation failed — check `error.details` |
| `CANNOT_CANCEL` | 422 | Appointment cannot be cancelled |
| `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*
