Docfav Public API

Welcome to the Docfav Public API. This API allows you to integrate your system with Docfav to manage appointments, clients, availability, and more.

Base URLhttps://www.docfav.com/api-connector/v1

Response Format

All responses follow this structure:

{"data": { ... },
  "errors": [],
  "meta": {"timestamp": "2026-02-05T12:00:00+00:00",
    "api_version": "v1"
  }
}

Timestamps

All datetime values in the API are in UTC (ISO 8601 format). Use the timezone field from staff calendars to convert to local time when displaying to users.

Authentication

The API uses API Key authentication. Include your API key in the X-Api-Key header of each request.

Request Example
curl -H "X-Api-Key: df_pk_your_api_key" \
  https://www.docfav.com/api-connector/v1/me

Getting your API Key

  1. Log in to your Docfav account
  2. Go to Settings → API
  3. Create a new API Key
  4. Copy and save the key securely (it's only shown once)
Important: Never share your API key or include it in client-side code. Treat your API key like a password.

Scopes

API keys have specific permissions (scopes) that determine which endpoints they can access:

ScopeDescription
user:readAccess to user information
profiles:readAccess to professional profiles
backofficeclinics:readAccess to back office clinic information
staff:readAccess to staff and staff calendars information
services:readAccess to services catalog
clients:readAccess to client information and search
clients:writeCreate and update clients
appointments:readAccess to appointments and availability
appointments:writeCreate and update appointments
sales:readAccess to sales information
products:readAccess to sold products (sale line items)
payments:readAccess to payments and refunds (cash-flow movements)
invoices:readAccess to invoices, rectified invoices, PDFs, TicketBai XML and invoice issuers

Rate Limiting

API requests are rate limited to ensure service stability. Limits depend on your plan.

Response Headers

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per hour
X-RateLimit-RemainingRemaining requests in current window
X-RateLimit-ResetUnix timestamp when the limit resets
If you exceed the limit, you'll receive a 429 Too Many Requests error. Wait for the time indicated in the Retry-After header.

Error Codes

The API uses standard HTTP codes to indicate request results.

CodeErrorDescription
400VALIDATION_ERRORInvalid request parameters
401INVALID_API_KEYInvalid or missing API key
401API_KEY_REVOKEDThe API key has been revoked
401API_KEY_EXPIREDThe API key has expired
403INSUFFICIENT_SCOPESThe API key lacks required permissions
403CLINIC_MANAGER_ACCESS_DENIEDThe user is not a manager of the requested clinic
403IP_NOT_ALLOWEDAccess denied from this IP address
404NOT_FOUNDResource not found
404SALE_NOT_FOUNDThe requested sale does not exist in this clinic
404INVOICE_NOT_FOUNDThe requested invoice or rectified invoice does not exist in this clinic
404INVOICE_PDF_NOT_AVAILABLEThe invoice exists but its PDF has not been generated yet
404TBAI_NOT_AVAILABLEThe invoice is not registered with TicketBai (Basque Country) so no XML exists
400INVALID_LIMITlimit is not an integer between 1 and 100
400INVALID_OFFSEToffset is negative; or — on the sales/payments/invoices/products list endpoints — not a multiple of limit
400OFFSET_TOO_LARGEoffset + limit exceeds 10000 (Elasticsearch result window; applies to /clients and /clients/autocomplete)
400INVALID_DATE_FORMATstart_date or end_date is not ISO 8601 UTC (e.g. 2026-01-01T00:00:00Z)
400INVALID_DATE_RANGEstart_date is after end_date or required dates are missing
400DATE_RANGE_TOO_LARGEThe window between start_date and end_date exceeds 366 days
400INVALID_SALE_NUMBERsaleNumber is not a positive integer
400INVALID_SALE_STATUSsale_status contains a value outside completed, paid_partially, unpaid
400INVALID_TYPEtype is not one of invoice, rectified_invoice
400INVALID_CLIENT_IDclient_id is not a valid UUID
409CLIENT_EMAIL_EXISTSA client with this email already exists
429RATE_LIMIT_EXCEEDEDRequest rate limit exceeded
500INTERNAL_ERRORInternal server error
503API_DISABLEDThe API is temporarily disabled

Error Format

{"data": null,
  "errors": [
    {"code": "INVALID_API_KEY",
      "message": "Invalid API key"
    }
  ],
  "meta": {"timestamp": "2026-02-05T12:00:00+00:00",
    "api_version": "v1"
  }
}

User & Profiles

Endpoints to access user and profile information.

GET /api-connector/v1/me

Get the authenticated user information.

Scope: user:read

Response Example

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "[email protected]",
    "fullname": "John Doe",
    "firstname": "John",
    "lastname": "Doe",
    "timezone": "Europe/Madrid",
    "locale": "es_ES",
    "country_code": "ES",
    "status": "active"
  },
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/profiles

List all professional profiles for the authenticated user.

Scope: profiles:read

Response Example

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "type": "professional",
      "back_office_clinic_id": "550e8400-e29b-41d4-a716-446655440002",
      "last_selected": true
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}

Clinics

Endpoints to access back office clinic information.

GET /api-connector/v1/backofficeclinics

List all back office clinics associated with the authenticated user.

Scope: backofficeclinics:read

Response Example

{
  "data": [
    {
      "id": "6edafcff-732d-4cce-8f16-f0d50d2b22b2",
      "name": "Central Clinic",
      "business_name": "Central Clinic S.L.",
      "vat_number": "B12345678",
      "address": "Main Street 1",
      "city": "Madrid",
      "zip_code": "28001",
      "has_logo": true,
      "subscription_status": "active"
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}

Get details of a specific back office clinic.

Scope: backofficeclinics:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic

Response Example

{
  "data": {
    "id": "6edafcff-732d-4cce-8f16-f0d50d2b22b2",
    "name": "Central Clinic",
    "business_name": "Central Clinic S.L.",
    "vat_number": "B12345678",
    "issuer_type": "company",
    "address": "Main Street 1",
    "city": "Madrid",
    "zip_code": "28001",
    "has_logo": true,
    "custom_email": "[email protected]",
    "default_appointments_behaviour": "confirmed",
    "subscription_status": "active"
  },
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}

Calendars

Endpoints to access calendars (physical locations where appointments occur).

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/calendars

List all calendars for a clinic. A calendar represents a physical location.

Scope: backofficeclinics:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic

Response Example

{
  "data": [
    {
      "id": "6e8e058e-f01b-454b-8d49-77589dadc7bd",
      "name": "Centro Getxo",
      "address": "Getxo, España",
      "city": "Getxo",
      "zip_code": "48993",
      "type": "onsite",
      "is_active": true
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}

Staff

Endpoints to access staff members and their calendars.

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/staff

List all staff members for a clinic.

Scope: staff:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic

Response Example

{
  "data": [
    {
      "id": "e727a18f-edf0-45f5-a866-d2c629113758",
      "name": "Pedro",
      "surname": "García",
      "fullname": "Pedro García",
      "email": "[email protected]",
      "is_active": true
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/staffcalendars

List staff calendars for a clinic. A staff calendar links a staff member to a calendar with specific settings. Supports optional filtering by calendar or staff.

Scope: staff:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
calendar_idstring (UUID)queryNoFilter by calendar UUID
staff_idstring (UUID)queryNoFilter by back office staff UUID
service_idstring (UUID)queryNoReturn only staff calendars configured to provide this service (empty list if the service is unknown)
limitintegerqueryNoMax results to return (1-100, default: 100)
offsetintegerqueryNoNumber of results to skip (default: 0)
order_bystringqueryNoSort field and direction (default: "email.asc")

Response Example

{
  "data": [
    {
      "id": "9cf404c3-951e-4895-8a14-18c68bd91ef4",
      "back_office_staff_id": "e727a18f-edf0-45f5-a866-d2c629113758",
      "calendar_id": "6e8e058e-f01b-454b-8d49-77589dadc7bd",
      "email": "[email protected]",
      "telephone": "+34600000000",
      "slot_duration": 15,
      "is_active": true,
      "timezone": "Europe/Madrid"
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}

Services

Endpoints to access the services catalog.

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/services

List the clinic service catalogue (treatments). Optionally filter by staff member (staff_id) or calendar/gabinete (calendar_id), and expand the staff/calendar tuples each service is configured for via expand=staff_calendars. Amounts are returned in cents.

Scope: services:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
staff_idstring (UUID)queryNoReturn only services offered by this staff member
calendar_idstring (UUID)queryNoReturn only services offered in this calendar (gabinete)
expandstring (CSV)queryNoComma-separated fields to expand per item. Supported: "staff_calendars" (adds a staff_calendars array of {id, staff_id, calendar_id})
service_categorystring (UUID)queryNoFilter by service category UUID
order_bystringqueryNoSort field and direction (default: "name.asc")
limitintegerqueryNoMax results to return (1-100, default: 100)
offsetintegerqueryNoNumber of results to skip (default: 0)

Response Example

{
  "data": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Fisioterapia",
      "service_category": "c1d2e3f4-a5b6-7890-abcd-ef1234567890",
      "amount": 5000,
      "duration": 30,
      "price_type": 1,
      "color": "#4CAF50",
      "is_active": true,
      "vat_rate": "21",
      "note": null,
      "location_type": "onsite",
      "scope": "individual",
      "max_participants": null,
      "position": 1,
      "staff_calendars": [
        { "id": "9cf404c3-951e-4895-8a14-18c68bd91ef4", "staff_id": "e727a18f-edf0-45f5-a866-d2c629113758", "calendar_id": "6e8e058e-f01b-454b-8d49-77589dadc7bd" }
      ]
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}

Clients

Endpoints to list, search, create and retrieve clients.

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/clients

List all clients for a clinic with pagination, filtering and sorting.

Scope: clients:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
limitintegerqueryNoMax results to return (default: 10, max: 100)
offsetintegerqueryNoNumber of results to skip (default: 0)
order_bystringqueryNoSort field and direction, e.g. "name.asc", "created_at.desc" (default: "name.asc")
genderstringqueryNoFilter by gender: "male", "female"
min_agestringqueryNoMinimum age filter (e.g., "18")
max_agestringqueryNoMaximum age filter (e.g., "65")
activity_fromstring (YYYY-MM-DD)queryNoFilter clients active from this date
activity_tostring (YYYY-MM-DD)queryNoFilter clients active until this date

Response Example

{
  "data": {
    "clients": [
      {
        "id": "68b70480-e924-4841-8038-e2e695971ff6",
        "client_number": 1234,
        "firstname": "Carlos",
        "lastname": "Garcia",
        "fullname": "Carlos Garcia",
        "email": "[email protected]",
        "phone": "+34600000000",
        "gender": "male",
        "date_of_birth": { "dayOfBirth": "15", "monthOfBirth": "03", "yearOfBirth": "1990" },
        "address": "Calle Mayor 1",
        "city": "Madrid",
        "province": "Madrid",
        "post_code": "28001",
        "country_code": "ES",
        "id_card": "12345678A",
        "note": "Paciente habitual",
        "tags": ["vip"],
        "is_active": true,
        "is_company": false,
        "walk_in": false,
        "receive_reminders": true,
        "receive_campaigns": true,
        "has_photo": false,
        "created_at": "2026-01-15T10:00:00+00:00"
      }
    ],
    "meta": {
      "limit": 10,
      "offset": 0,
      "total": 156
    }
  },
  "errors": [],
  "meta": { "timestamp": "2026-03-04T12:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/clients/{clientId}

Get details of a specific client by ID.

Scope: clients:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
clientIdstring (UUID)pathYesUUID of the client

Response Example

{
  "data": {
    "id": "68b70480-e924-4841-8038-e2e695971ff6",
    "client_number": 1234,
    "firstname": "Carlos",
    "lastname": "García",
    "fullname": "Carlos García",
    "email": "[email protected]",
    "phone": "+34600000000",
    "gender": "male",
    "date_of_birth": { "dayOfBirth": "15", "monthOfBirth": "03", "yearOfBirth": "1990" },
    "address": "Calle Mayor 1",
    "city": "Madrid",
    "province": "Madrid",
    "post_code": "28001",
    "country_code": "ES",
    "id_card": "12345678A",
    "note": "Paciente habitual",
    "tags": ["vip"],
    "is_active": true,
    "is_company": false,
    "walk_in": false,
    "receive_reminders": true,
    "receive_campaigns": true,
    "has_photo": false,
    "created_at": "2026-01-15T10:00:00+00:00"
  },
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/clients/autocomplete

Search clients by name, surname, email, phone or ID card. Supports partial and accent-insensitive matching.

Scope: clients:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
keywordstringqueryYesSearch query (name, surname, email, phone, or ID card)
limitintegerqueryNoMax results to return (default: 20)
offsetintegerqueryNoNumber of results to skip (default: 0)
order_bystringqueryNoSort field and direction (e.g. name.asc)

Response Example

{
  "data": [
    {
      "id": "68b70480-e924-4841-8038-e2e695971ff6",
      "fullname": "Carlos García",
      "email": "[email protected]",
      "telephone": "+34600000000",
      "client_number": 1234
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
POST /api-connector/v1/backofficeclinics/{backOfficeClinicId}/clients

Create a new client. firstname/lastname/phone are the canonical field names (they match what the GET endpoints return); name/surname/telephone are accepted as legacy aliases. If both forms are sent in the same request, the canonical value wins. The response includes both the canonical fields and the legacy aliases for backwards compatibility.

Scope: clients:write

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
firstnamestringbodyNoClient first name (canonical). Legacy alias: "name"
lastnamestringbodyNoClient last name (canonical). Legacy alias: "surname"
phonestringbodyNoPhone in international format (canonical). Legacy alias: "telephone"
emailstringbodyNoClient email address
walk_inbooleanbodyNoIs walk-in client (default: false)

Request Body

{
  "firstname": "Carlos",
  "lastname": "García",
  "phone": "+34600000000",
  "email": "[email protected]"
}

Response Example

{
  "data": {
    "id": "68b70480-e924-4841-8038-e2e695971ff6",
    "client_number": 1234,
    "firstname": "Carlos",
    "lastname": "García",
    "fullname": "Carlos García",
    "email": "[email protected]",
    "phone": "+34600000000",
    "name": "Carlos",
    "surname": "García",
    "telephone": "+34600000000"
  },
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}

Availability

Endpoints to check availability and occupied time slots.

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/calendars/{calendarId}/schedules

Get staff working hours (schedules) for a date range. Returns day offs and time offs as well.

Scope: staff:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
calendarIdstring (UUID)pathYesUUID of the calendar
start_datestring (YYYY-MM-DD)queryYesStart date
end_datestring (YYYY-MM-DD)queryNoEnd date (defaults to start_date)

Response Example

{
  "data": [
    {
      "staff_id": "e727a18f-edf0-45f5-a866-d2c629113758",
      "staff_calendar_id": "9cf404c3-951e-4895-8a14-18c68bd91ef4",
      "name": "Pedro García",
      "schedules": [
        {
          "day": "THURSDAY",
          "date": "2026-02-05",
          "type": "REGULAR_DAY",
          "hours": [
            { "start": "08:00", "end": "14:00", "type": "WORKING_DAY" },
            { "start": "16:00", "end": "20:00", "type": "WORKING_DAY" }
          ]
        }
      ]
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/calendars/{calendarId}/occupied

Get all occupied time slots: appointments, time reservations, group reservations, day offs, and working hours.

Scope: appointments:read + staff:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
calendarIdstring (UUID)pathYesUUID of the calendar
start_datestring (YYYY-MM-DD)queryYesStart date
end_datestring (YYYY-MM-DD)queryYesEnd date
staff_calendar_idstring (UUID)queryNoFilter by staff calendar

Response Example

{
  "data": [
    {
      "staff_id": "e727a18f-edf0-45f5-a866-d2c629113758",
      "staff_calendar_id": "9cf404c3-951e-4895-8a14-18c68bd91ef4",
      "name": "Pedro García",
      "working_hours": [
        { "date": "2026-02-05", "from": "08:00", "to": "20:00", "type": "WORKING_DAY" }
      ],
      "day_offs": [],
      "time_offs": [],
      "appointments": [
        {
          "id": "31bd18a6-52be-4ad3-9b9f-78b684fc6f2a",
          "from": "2026-02-05T17:00:00Z",
          "to": "2026-02-05T17:30:00Z",
          "behaviour": "confirmed",
          "client_id": "68b70480-e924-4841-8038-e2e695971ff6",
          "service_name": "Fisioterapia"
        }
      ],
      "time_reservations": [
        {
          "id": "ac14f29b-89f0-4d16-873c-772dae27650f",
          "from": "2026-02-05T13:00:00Z",
          "to": "2026-02-05T14:00:00Z",
          "reason": "Lunch break"
        }
      ],
      "group_reservations": []
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/calendars/{calendarId}/check-availability

Check if a specific time slot is available. Returns conflicts if not available.

Scope: appointments:read + staff:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
calendarIdstring (UUID)pathYesUUID of the calendar
fromstring (ISO 8601)queryYesStart datetime in UTC (e.g., 2026-02-05T10:00:00Z)
tostring (ISO 8601)queryYesEnd datetime in UTC
staff_calendar_idstring (UUID)queryYesUUID of the staff calendar

Response Example

{
  "data": {
    "available": false,
    "requested": {
      "from": "2026-02-05T13:00:00Z",
      "to": "2026-02-05T14:00:00Z",
      "staff_calendar_id": "9cf404c3-951e-4895-8a14-18c68bd91ef4"
    },
    "conflicts": [
      {
        "type": "time_reservation",
        "id": "ac14f29b-89f0-4d16-873c-772dae27650f",
        "from": "2026-02-05T13:00:00Z",
        "to": "2026-02-05T14:00:00Z",
        "reason": "Lunch break"
      }
    ]
  },
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/calendars/{calendarId}/available-slots

Get all time slots with availability status. Useful for rendering a booking calendar.

Scope: appointments:read + staff:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
calendarIdstring (UUID)pathYesUUID of the calendar
start_datestring (YYYY-MM-DD)queryYesStart date
end_datestring (YYYY-MM-DD)queryYesEnd date
staff_calendar_idstring (UUID)queryNoFilter by staff calendar
service_idstring (UUID)queryNoFilter slots that fit the given service duration
slot_durationintegerqueryNoSlot duration in minutes (default: 15)
service_durationintegerqueryNoService duration to check fit (default: 0)
periodstring (morning|afternoon)queryNoKeep only morning (before 14:00) or afternoon (14:00 onwards) slots, in the staff member timezone
weekdaysstring (CSV 1-7)queryNoComma-separated ISO weekdays to keep (1=Monday ... 7=Sunday)
datestring (YYYY-MM-DD)queryNoReturn only this single day. Must fall within start_date/end_date

Response Example

{
  "data": [
    {
      "staff_id": "e727a18f-edf0-45f5-a866-d2c629113758",
      "staff_calendar_id": "9cf404c3-951e-4895-8a14-18c68bd91ef4",
      "name": "Pedro García",
      "timezone": "Europe/Madrid",
      "slot_duration": 15,
      "available_slots": [
        {
          "date": "2026-02-05",
          "day": "THURSDAY",
          "type": "REGULAR_DAY",
          "slots": [
            { "from": "2026-02-05T08:00:00Z", "to": "2026-02-05T08:15:00Z", "available": true, "hour_type": "WORKING_DAY" },
            { "from": "2026-02-05T13:00:00Z", "to": "2026-02-05T13:15:00Z", "available": false, "hour_type": "WORKING_DAY" }
          ]
        }
      ]
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/available-slots

Convenience endpoint for conversational agents: resolves the calendar (gabinete) from calendar_name and returns the same availability payload as the by-id endpoint, including the optional period/weekdays/date filters. Name matching is Unicode-aware and case-insensitive (Á ↔ á, Í ↔ í). By default accents matter; pass accent_insensitive=true to also ignore diacritics (Podologia ↔ Podología). Returns 404 (CALENDAR_NOT_FOUND) when no calendar matches and 409 (CALENDAR_NAME_AMBIGUOUS) when more than one calendar shares the name — candidates are listed in meta.candidates.

Scope: appointments:read + staff:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
calendar_namestringqueryYesCalendar (gabinete) name. Unicode-aware case-insensitive exact match; accents matter unless accent_insensitive=true
accent_insensitivebooleanqueryNoWhen true, diacritics are ignored when matching calendar_name (Podologia ↔ Podología). Default: false
start_datestring (YYYY-MM-DD)queryYesStart date (strict YYYY-MM-DD format)
end_datestring (YYYY-MM-DD)queryYesEnd date (strict YYYY-MM-DD format). Range cannot exceed 15 days
periodstring (morning|afternoon)queryNoKeep only morning (before 14:00) or afternoon (14:00 onwards) slots, in the staff member timezone
weekdaysstring (CSV 1-7)queryNoComma-separated ISO weekdays to keep (1=Monday ... 7=Sunday)
datestring (YYYY-MM-DD)queryNoReturn only this single day. Must fall within start_date/end_date
staff_calendar_idstring (UUID)queryNoFilter by a single staff calendar UUID
service_idstring (UUID)queryNoFilter slots that fit the given service duration

Response Example

{
  "data": [
    {
      "staff_id": "e727a18f-edf0-45f5-a866-d2c629113758",
      "staff_calendar_id": "9cf404c3-951e-4895-8a14-18c68bd91ef4",
      "name": "Pedro García",
      "timezone": "Europe/Madrid",
      "slot_duration": 15,
      "available_slots": [
        {
          "date": "2026-02-05",
          "day": "THURSDAY",
          "type": "REGULAR_DAY",
          "slots": [
            { "from": "2026-02-05T08:00:00Z", "to": "2026-02-05T08:15:00Z", "available": true, "hour_type": "WORKING_DAY" }
          ]
        }
      ]
    }
  ],
  "errors": [],
  "meta": {
    "timestamp": "2026-02-05T12:00:00+00:00",
    "api_version": "v1",
    "calendar": { "id": "5c3f...", "name": "Gabinete 1" }
  }
}

Appointments

Endpoints to create and manage appointments.

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/availability

Get appointments, time reservations, group reservations, and recurring events for a date range. Maximum range: 7 days.

Scope: appointments:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
start_datestring (ISO 8601)queryYesStart datetime in UTC (e.g., 2026-03-05T23:00:00Z)
end_datestring (ISO 8601)queryYesEnd datetime in UTC (e.g., 2026-03-06T22:59:59Z)
local_start_datestring (YYYY-MM-DD)queryNoLocal start date for recurring events (e.g., 2026-03-06). Required to get recurring_events — see note below.
local_end_datestring (YYYY-MM-DD)queryNoLocal end date for recurring events (e.g., 2026-03-06). Required to get recurring_events — see note below.
result_typestringqueryNoFilter by type: "appointments", "time_reservations", "group_reservations", "recurring_events". Returns all if omitted.
client_idstring (UUID)queryNoFilter appointments by client
staff_idstring (UUID)queryNoFilter by staff
calendar_idstring (UUID)queryNoFilter by calendar
sale_statusstringqueryNoFilter by sale status
limitintegerqueryNoMax results to return (default: all)
offsetintegerqueryNoNumber of results to skip (default: 0)

Response Example

{
  "data": {
    "appointments": [
      {
        "id": "31bd18a6-52be-4ad3-9b9f-78b684fc6f2a",
        "client_id": "68b70480-e924-4841-8038-e2e695971ff6",
        "client_name": "Carlos Garcia",
        "service_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "service_name": "Consulta general",
        "calendar_id": "9cf404c3-951e-4895-8a14-18c68bd91ef4",
        "staff_id": "e727a18f-edf0-45f5-a866-d2c629113758",
        "booked_from": "2026-03-06T09:00:00Z",
        "booked_to": "2026-03-06T09:30:00Z",
        "status": "confirmed",
        "sale_status": "pending",
        "note": "Primera visita",
        "price": 5000,
        "source": "backoffice"
      }
    ],
    "time_reservations": [
      {
        "id": "ac14f29b-89f0-4d16-873c-772dae27650f",
        "back_office_staff_calendar_id": "9cf404c3-951e-4895-8a14-18c68bd91ef4",
        "name": "Lunch break",
        "booked_from": "2026-03-06T12:00:00Z",
        "booked_to": "2026-03-06T13:00:00Z",
        "note": null
      }
    ],
    "group_reservations": [],
    "recurring_events": [
      {
        "id": "b5c6d7e8-f9a0-1234-5678-9abcdef01234",
        "back_office_staff_calendar_id": "9cf404c3-951e-4895-8a14-18c68bd91ef4",
        "name": "Weekly team meeting",
        "booked_from": "2026-03-06T08:00:00",
        "booked_to": "2026-03-06T08:30:00",
        "is_recurring_event": true,
        "original_id": "a1b2c3d4-0000-0000-0000-000000000001",
        "timezone": "Europe/Madrid"
      }
    ]
  },
  "errors": [],
  "meta": { "timestamp": "2026-03-06T12:00:00+00:00", "api_version": "v1" }
}

IMPORTANT — Recurring Events (recurring_events):
Recurring events are generated from EventSchedules and calculated based on the clinic's local timezone, not UTC. To receive them, you MUST provide both local_start_date and local_end_date in YYYY-MM-DD format (e.g., 2026-03-06). If these parameters are omitted, the recurring_events array will be empty. The start_date/end_date parameters (UTC, ISO 8601) are used for appointments, time_reservations, and group_reservations only.
POST /api-connector/v1/backofficeclinics/{backOfficeClinicId}/appointments

Create one or more appointments.

Scope: appointments:write

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
clientstring (UUID)bodyNoClient UUID (omit for walk-in)
timezonestringbodyNoTimezone (default: Europe/Madrid)
appointmentsarraybodyYesArray of appointment objects
appointments[].servicestring (UUID)bodyYesService UUID
appointments[].back_office_staff_calendarstring (UUID)bodyYesStaff calendar UUID
appointments[].fromstring (ISO 8601)bodyYesStart datetime in UTC
appointments[].tostring (ISO 8601)bodyYesEnd datetime in UTC
appointments[].notestringbodyNoNote for the appointment
send_reminderbooleanbodyNoSend reminder to client (default: true)
behaviourstringbodyNoStatus: "confirmed", "pending", "cancelled" (default: confirmed)
forcebooleanbodyNoAllow overlapping appointments (default: false)

Request Body

{
  "client": "68b70480-e924-4841-8038-e2e695971ff6",
  "timezone": "Europe/Madrid",
  "appointments": [
    {
      "service": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "back_office_staff_calendar": "9cf404c3-951e-4895-8a14-18c68bd91ef4",
      "from": "2026-02-05T15:00:00Z",
      "to": "2026-02-05T15:30:00Z",
      "note": "First consultation"
    }
  ],
  "send_reminder": true,
  "behaviour": "confirmed"
}

Response Example

{
  "data": [
    {
      "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
      "appointment_number": 12346,
      "client_id": "68b70480-e924-4841-8038-e2e695971ff6",
      "service_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "service_name": "Fisioterapia",
      "booked_from": "2026-02-05T15:00:00Z",
      "booked_to": "2026-02-05T15:30:00Z",
      "status": "confirmed",
      "note": "First consultation"
    }
  ],
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
PUT /api-connector/v1/backofficeclinics/{backOfficeClinicId}/appointments/{appointmentId}/behaviour

Change the behaviour (status) of an appointment. Use this to confirm, cancel, mark as no-show, or revert to unconfirmed.

Scope: appointments:write

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
appointmentIdstring (UUID)pathYesUUID of the appointment
behaviourstringbodyYesNew status: "unconfirmed", "confirmed", "cancelled" or "no_show"
force_capacity_increasebooleanbodyNoForce capacity increase when reactivating a cancelled participant in a full group appointment (default: false)
cancel_participantsbooleanbodyNoWhen cancelling a group appointment, also cancel all participants (default: false)

Request Body

{
  "behaviour": "cancelled"
}

Response Example

{
  "data": {
    "appointment_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "behaviour": "cancelled",
    "message": "Appointment behaviour updated successfully"
  },
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}
DELETE /api-connector/v1/backofficeclinics/{backOfficeClinicId}/appointments/{appointmentId}

Delete an appointment permanently. The appointment id is obtained from the availability or create endpoints.

Scope: appointments:write

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
appointmentIdstring (UUID)pathYesUUID of the appointment to delete

Response Example

{
  "data": {
    "message": "Appointment deleted successfully"
  },
  "errors": [],
  "meta": { "timestamp": "2026-02-05T12:00:00+00:00", "api_version": "v1" }
}

Sales

Endpoints to retrieve sales information for a clinic. The light list view (paginated, header-level fields only) is paired with a per-sale detail endpoint for drill-downs.

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/sales

List sales for a clinic (light view, paginated, ordered by saleNumber DESC). Each row carries only the aggregate-level fields (id, saleNumber, status, saleStatus, createdAt, paidAt, invoiceId, pit). Products and payments are NOT included — drill down with GET /sales/{saleNumber} for the full detail. The date window applies to the sale's created_at, is required, and capped at 366 days.

Scope: sales:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
start_datestring (ISO 8601 UTC, e.g. 2026-01-01T00:00:00Z)queryYesStart of date window. Applied on the sale created_at.
end_datestring (ISO 8601 UTC)queryYesEnd of date window. Max range: 366 days.
limitintegerqueryNoItems per page (default 50, 1-100)
offsetintegerqueryNoItems to skip (default 0, must be a multiple of limit)
sale_statusstring (CSV)queryNoFilter by sale status: completed, paid_partially, unpaid

Response Example

{
  "data": {
    "sales": [
      {
        "id": "sale-uuid",
        "saleNumber": 1234,
        "status": "active",
        "saleStatus": "paid_partially",
        "createdAt": "2026-05-20T11:30:00Z",
        "paidAt": null,
        "invoiceId": "550e8400-e29b-41d4-a716-446655440099",
        "pit": "0.00"
      }
    ],
    "meta": { "limit": 50, "offset": 0, "total": 1 }
  },
  "errors": [],
  "meta": { "timestamp": "2026-05-20T12:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/sales/{saleNumber}

Get the full sale aggregate by its per-clinic sale number: payments[], appointments[], clientVouchers[], clientItems[], clientBudgets[], clientSubscriptions[], invoiceId, saleStatus, pit, receipt. Use the saleNumber returned by /payments or /sales to drill down.

Scope: sales:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
saleNumberintegerpathYesSequential sale number within the clinic

Response Example

{
  "data": {
    "id": "sale-uuid",
    "saleNumber": 1234,
    "payments": [],
    "pit": null,
    "invoiceIssuer": null,
    "discountValue": null,
    "discountType": "amount",
    "discountScope": "sale",
    "discountedProducts": [],
    "appointments": [],
    "clientVouchers": [],
    "clientItems": [],
    "clientBudgets": [],
    "clientSubscriptions": [],
    "invoiceId": null,
    "receipt": null
  },
  "errors": [],
  "meta": { "timestamp": "2026-05-20T12:00:00+00:00", "api_version": "v1" }
}

Products

Granular sold-line-items endpoint: equivalent to the dashboard ARTÍCULOS tab. Each row is one transactional line within a Sale (appointment, voucher, item, subscription or budget). This is NOT the service catalog — for that use /services.

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/products

List sold products for a clinic, one row per line item, ordered by product/appointment date DESC. Monetary values (subTotal, tax, irpf, price, amountPaid, commission) come in the clinic's local currency (not cents). amountPaid is the portion of price already collected — compare against price to spot partial payments. The client's DNI is exposed under client.idCard. Use by_payments=true to swap the date window semantics from product/appointment date to payment registration date (Spanish 'fecha de cobro') — handy for cash-flow reconciliation by charge date. Drill-downs: sale.sequenceNumber → GET /sales/{saleNumber}; invoice.id (when non-null) → GET /invoices/{id}. Date window is required and capped at 366 days.

Scope: products:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
start_datestring (ISO 8601 UTC)queryYesStart of date window (applied on product/appointment date by default, or on payment createdAt if by_payments=true)
end_datestring (ISO 8601 UTC)queryYesEnd of date window. Max range: 366 days.
limitintegerqueryNoItems per page (default 50, 1-100)
offsetintegerqueryNoItems to skip (default 0, must be a multiple of limit)
type_of_productstring (CSV)queryNoProduct types: appointment, voucher, item, subscription, budget
staff_idstring (CSV of UUIDs)queryNoFilter by staff member(s)
calendar_idstring (CSV of UUIDs)queryNoFilter by calendar(s)
client_idstring (UUID)queryNoFilter by client
servicesstring (CSV of UUIDs)queryNoFilter by service(s)
payment_statusstring (CSV)queryNocompleted, paid_partially, unpaid, free
payment_methodstring (CSV)queryNoefectivo, transferencia, tarjeta, bizum, paypal, otro, …
by_paymentsbooleanqueryNoIf true, the date window applies to payment.createdAt instead of product/appointment date

Response Example

{
  "data": {
    "products": [
      {
        "id": "product-uuid",
        "type": "appointment",
        "name": "Consulta inicial",
        "sequenceNumber": 4521,
        "subTotal": 50.00,
        "tax": 10.50,
        "irpf": 0.00,
        "price": 60.50,
        "amountPaid": 60.50,
        "commission": 0.00,
        "sale": {
          "id": "sale-uuid",
          "sequenceNumber": 1234,
          "paymentStatus": "completed",
          "paymentMethod": "tarjeta",
          "paidAt": "2026-05-20T11:30:00Z"
        },
        "client": {
          "id": "client-uuid",
          "name": "María García",
          "phone": "+34600000000",
          "clientNumber": 56,
          "idCard": "12345678A"
        },
        "employee": { "id": "staff-uuid", "name": "Dra. López" },
        "calendar": { "id": "cal-uuid", "name": "Consulta 1" },
        "invoice": { "id": "invoice-uuid", "sequenceNumber": 99 }
      }
    ],
    "meta": { "limit": 50, "offset": 0, "total": 1 }
  },
  "errors": [],
  "meta": { "timestamp": "2026-05-20T12:00:00+00:00", "api_version": "v1" }
}

Payments

Cash-flow movements (cobros y reembolsos) for a clinic. Each row is one monetary transaction. Use transactionType to distinguish PAYMENT (positive amount) from REFUND (negative amount). Sum amount directly to get period nets — refunds self-cancel against their original charge.

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/payments

List payment transactions for a clinic, ordered by paidAt DESC. amountRefunded semantics: on PAYMENT rows, the cumulative amount already returned FROM this specific charge. On REFUND rows, always 0 (refunds are not refundable). Do NOT use amountRefunded to compute period nets — sum amount instead. Drill-down: every row carries saleNumber (per-clinic sequential ID). Use it with GET /sales/{saleNumber} to fetch the full sale (products, invoice, aggregated payments). The optional client_id filter walks payments → sale_payments → sales → products (JOINED inheritance) and matches the client_id stored on each Product subclass. Date window is required and capped at 366 days.

Scope: payments:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
start_datestring (ISO 8601 UTC)queryYesStart of date window (applied on payment paidAt)
end_datestring (ISO 8601 UTC)queryYesEnd of date window. Max range: 366 days.
limitintegerqueryNoItems per page (default 50, 1-100)
offsetintegerqueryNoItems to skip (default 0, must be a multiple of limit)
client_idstring (UUID)queryNoReturns only payments whose sale has a product linked to this client (appointment, voucher, item, budget or subscription).

Response Example

{
  "data": {
    "payments": [
      {
        "id": "payment-uuid",
        "sequence": 4321,
        "amount": 60.50,
        "paymentMethod": "tarjeta",
        "saleNumber": 1234,
        "paidAt": "2026-05-20T11:35:00Z",
        "user": "[email protected]",
        "amountRefunded": 0,
        "transactionType": "PAYMENT",
        "customPaymentMethodId": null
      },
      {
        "id": "refund-uuid",
        "sequence": 4322,
        "amount": -5.00,
        "paymentMethod": "tarjeta",
        "saleNumber": 1234,
        "paidAt": "2026-05-21T09:00:00Z",
        "user": "[email protected]",
        "amountRefunded": 0,
        "transactionType": "REFUND",
        "customPaymentMethodId": null
      }
    ],
    "meta": { "limit": 50, "offset": 0, "total": 2 }
  },
  "errors": [],
  "meta": { "timestamp": "2026-05-20T12:00:00+00:00", "api_version": "v1" }
}

Invoices

Fiscal documents for a clinic: PermanentInvoice (type=invoice) and RectifiedInvoice (type=rectified_invoice, the Spanish factura rectificativa, equivalent to a credit note when amounts are negative). Both families are merged at SQL level and paginated together for a chronologically coherent stream. Invoice drafts (mutable, no legal value) are excluded by design.

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/invoices

List invoices and rectified invoices (unified, light view), paginated, ordered by issue date DESC. Each row carries a type discriminator (invoice / rectified_invoice). On rectified_invoice rows, references_invoice_id points to the original invoice. Status semantics: created (live), rectified (a rectified_invoice references it), voided. links.pdf gives a relative URL to download the invoice PDF. For the optional TicketBai XML link, use the detail endpoint. For full detail (lines, totals, addresses), use GET /invoices/{invoiceId}. The date window applies to the document's issue date and is capped at 366 days.

Scope: invoices:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
start_datestring (ISO 8601 UTC)queryYesStart of date window (applied on invoice date)
end_datestring (ISO 8601 UTC)queryYesEnd of date window. Max range: 366 days.
limitintegerqueryNoItems per page (default 50, 1-100)
offsetintegerqueryNoItems to skip (default 0, must be a multiple of limit)
typestringqueryNoFilter by document family: invoice, rectified_invoice
client_idstring (UUID)queryNoFilter by a single client

Response Example

{
  "data": {
    "invoices": [
      {
        "id": "550e8400-e29b-41d4-a716-446655440099",
        "type": "invoice",
        "invoice_number": "A-0001",
        "date": "2026-05-20",
        "status": "created",
        "client": {
          "id": "client-uuid",
          "name": "María García",
          "id_card": "12345678A",
          "number": 56
        },
        "business_name": "María García",
        "references_invoice_id": null,
        "rectification": null,
        "links": {
          "pdf": "/api-connector/v1/backofficeclinics/{backOfficeClinicId}/invoices/550e8400-e29b-41d4-a716-446655440099/pdf"
        },
        "created_at": "2026-05-20T11:40:00Z"
      },
      {
        "id": "660e8400-e29b-41d4-a716-446655440111",
        "type": "rectified_invoice",
        "invoice_number": "R-0001",
        "date": "2026-05-21",
        "status": "created",
        "client": {
          "id": "client-uuid",
          "name": "María García",
          "id_card": "12345678A",
          "number": 56
        },
        "business_name": "María García",
        "references_invoice_id": "550e8400-e29b-41d4-a716-446655440099",
        "rectification": { "type": "ordinary" },
        "links": {
          "pdf": "/api-connector/v1/backofficeclinics/{backOfficeClinicId}/invoices/660e8400-e29b-41d4-a716-446655440111/pdf"
        },
        "created_at": "2026-05-21T09:05:00Z"
      }
    ],
    "meta": { "limit": 50, "offset": 0, "total": 2 }
  },
  "errors": [],
  "meta": { "timestamp": "2026-05-21T10:00:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/invoices/{invoiceId}

Show a single invoice or rectified invoice by UUID. The endpoint resolves the UUID transparently in both tables — the client doesn't need to know upfront which family the document belongs to. Monetary semantics: type=invoice carries positive amounts; type=rectified_invoice carries NEGATIVE amounts by convention. Sum invoices + rectified_invoices to get net revenue. links: pdf (always present) and xml_tbai (only on TicketBai-enabled invoices, otherwise null).

Scope: invoices:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
invoiceIdstring (UUID)pathYesUUID of the invoice or rectified invoice

Response Example

{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440099",
    "type": "invoice",
    "invoice_number": "A-0001",
    "date": "2026-05-20",
    "status": "created",
    "client": {
      "id": "client-uuid",
      "name": "María García",
      "id_card": "12345678A",
      "number": 56
    },
    "business_name": "María García",
    "vat_number": "B12345678",
    "address": "Calle Mayor 1, 28013 Madrid",
    "lines": [
      { "name": "Consulta inicial", "quantity": 1, "subtotal": 50.00, "tax": 10.50, "total": 60.50 }
    ],
    "totals": { "subtotal": 50.00, "taxes": 10.50, "total": 60.50 },
    "references_invoice_id": null,
    "rectification": null,
    "links": {
      "pdf": "/api-connector/v1/backofficeclinics/{backOfficeClinicId}/invoices/550e8400-e29b-41d4-a716-446655440099/pdf",
      "xml_tbai": null
    }
  },
  "errors": [],
  "meta": { "timestamp": "2026-05-21T10:05:00+00:00", "api_version": "v1" }
}
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/invoices/{invoiceId}/pdf

Download the invoice PDF as a binary stream (Content-Type: application/pdf). Works for both invoice and rectified_invoice. Returns 404 INVOICE_PDF_NOT_AVAILABLE if the PDF has not been generated yet for this document.

Scope: invoices:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
invoiceIdstring (UUID)pathYesUUID of the invoice or rectified invoice

Response Example

(binary PDF body — Content-Type: application/pdf)
GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/invoices/{invoiceId}/xml-tbai

Download the TicketBai XML for the invoice (Content-Type: application/xml). Only available on invoices registered with TicketBai (Basque Country territory). Returns 404 TBAI_NOT_AVAILABLE for non-TBAI invoices.

Scope: invoices:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic
invoiceIdstring (UUID)pathYesUUID of the invoice or rectified invoice

Response Example

(TBAI XML body — Content-Type: application/xml)

Invoice Issuers

Invoice issuers (emisores) configured for a clinic — the fiscal entities (autónomos, sociedades) under which invoices are issued. Each clinic can have multiple issuers; each invoice carries the issuer used at the time of emission.

GET /api-connector/v1/backofficeclinics/{backOfficeClinicId}/invoice-issuers

List all invoice issuers configured for the clinic, with their fiscal data (id, name, vat_number, address, business_name, …). Use the returned id to filter or interpret invoice responses.

Scope: invoices:read

Parameters

NameTypeInRequiredDescription
backOfficeClinicIdstring (UUID)pathYesUUID of the back office clinic

Response Example

{
  "data": {
    "invoice_issuers": [
      {
        "id": "issuer-uuid",
        "name": "María García Autónoma",
        "business_name": "María García",
        "vat_number": "12345678A",
        "address": "Calle Mayor 1, 28013 Madrid"
      }
    ]
  },
  "errors": [],
  "meta": { "timestamp": "2026-05-21T10:10:00+00:00", "api_version": "v1" }
}