Skip to Content

KlientBox REST API v1

Programmatic access for Provoz-tier customers. All endpoints require an X-API-Key header.

Authentication

Include your API key in every request:

curl -H "X-API-Key: YOUR_KEY" \
     https://your-odoo.com/klientbox/api/v1/clients

Generate your API key in Settings > Companies > KlientBox tab.

Rate Limiting

100 requests per minute per API key. Exceeding this returns 429 Too Many Requests.

Pagination

List endpoints accept ?page=1&per_page=50 (max 200).

Response includes total, page, and per_page fields.

Error Codes

CodeMeaning
400Bad Request -- missing or invalid fields
401Unauthorized -- missing API key
403Forbidden -- invalid key or wrong tier
404Not Found
429Too Many Requests
500Internal Server Error

Clients

GET /klientbox/api/v1/clients

List clients (paginated). Optional query params:

  • search -- filter by name or phone
  • status -- filter by status (new, active, warning, inactive, lost)
  • page, per_page
Response
{
  "data": [
    {
      "id": 42,
      "name": "Jan Novak",
      "phone": "+420601234567",
      "email": "[email protected]",
      "status": "active",
      "last_visit_date": "2026-03-20",
      "total_visits": 5,
      "days_since_visit": 25,
      "sms_opt_out": false,
      "email_opt_out": false,
      "created": "2025-11-01T10:00:00"
    }
  ],
  "total": 128,
  "page": 1,
  "per_page": 50
}
POST /klientbox/api/v1/clients
Request body (JSON)
{
  "name": "Jan Novak",          // required
  "phone": "+420601234567",     // required, unique per company
  "email": "[email protected]",   // optional
  "notes": "VIP customer",      // optional
  "sms_opt_out": false,         // optional, default false
  "email_opt_out": false        // optional, default false
}

Returns 201 with the created client object.

GET /klientbox/api/v1/clients/

Get a single client by ID. Returns 404 if not found in your company.

PUT /klientbox/api/v1/clients/

Update client fields. Only include fields you want to change.

{
  "name": "Jan Novak Jr.",
  "email": "[email protected]"
}
DELETE /klientbox/api/v1/clients/

Soft-delete (deactivate) a client. Returns {"deleted": true, "id": 42}.


Visits

GET /klientbox/api/v1/visits

List visits (paginated). Optional query params:

  • date_from, date_to -- ISO date (YYYY-MM-DD)
  • client_id -- filter by client
  • state -- scheduled, arrived, done, no_show, cancelled
  • page, per_page
POST /klientbox/api/v1/visits
Request body (JSON)
{
  "client_id": 42,                        // required
  "date": "2026-04-15T14:00:00",          // optional, defaults to now
  "service_id": 7,                        // optional
  "state": "done",                        // optional, default "done"
  "note": "Regular checkup",              // optional
  "staff_name": "Dr. Svoboda"             // optional
}

Returns 201 with the created visit object.


Services

GET /klientbox/api/v1/services

List all active services for your company.

{
  "data": [
    {"id": 7, "name": "Haircut", "duration_minutes": 30, "price": 450.0, "active": true}
  ]
}

Reports

GET /klientbox/api/v1/reports/summary

Dashboard summary: client counts by status, visits today, messages this month.

{
  "total_clients": 128,
  "status_breakdown": {"new": 5, "active": 80, "warning": 20, "inactive": 15, "lost": 8},
  "visits_today": 12,
  "messages_this_month": 34
}
GET /klientbox/api/v1/reports/reactivation

Reactivation campaign results. Optional: date_from, date_to (defaults to current month).

{
  "date_from": "2026-04-01",
  "date_to": "2026-04-14",
  "total_sent": 34,
  "delivered": 30,
  "replied": 8,
  "failed": 2,
  "by_trigger": {
    "warning": {"sent": 15, "delivered": 14, "replied": 5, "failed": 0},
    "inactive": {"sent": 12, "delivered": 10, "replied": 2, "failed": 1},
    "lost": {"sent": 7, "delivered": 6, "replied": 1, "failed": 1}
  }
}