Facility Categories API Documentation
Last Updated: 2025-02-11
API Version: v2
Base URL: https://api.kulcare.com/api/v2
Table of Contents
Overview
Facility Categories represent patient categorization rules at the facility level. Categories can:
- Filter patients by age/gender rules
- Associate services with discounts
- Track patient counts per category
- Support soft deletion
Data Model
Facility Category
| Field | Type | Description |
|---|---|---|
id | UUID | Unique identifier |
name | String | Category name (required) |
description | Text | Category description |
color_code | String | 7-character hex color code |
camp_category | Boolean | Whether this is a camp category |
active | Boolean | Whether category is active (not deleted) |
patient_count | Integer | Number of patients in this category |
created_at | DateTime | ISO8601 timestamp |
Category Rule
| Field | Type | Description |
|---|---|---|
id | UUID | Unique identifier |
rule_type | String | Rule type (e.g., "AGE_GENDER") |
min_age | Integer | Minimum age (optional) |
max_age | Integer | Maximum age (optional) |
gender_list | Array) | Genders: ["Male", "Female", "Other"] |
created_at | DateTime | ISO8601 timestamp |
Category Service Group
| Field | Type | Description |
|---|---|---|
id | UUID | Unique identifier |
discount_percentage | Decimal | Discount percentage (0-100) |
facility_service_ids | Array | Associated service IDs |
facility_services | Array | Service details with junction record info |
Endpoints
1. List Facility Categories
Get all facility categories with rules and services.
Endpoint: GET /clinical/facilities/:facility_id/facility_categories
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
filter_name | String | Filter by category name (partial match) |
filter_age | Integer | Filter by age (matches age range rules) |
filter_gender | String | Filter by gender (male, female, other) |
filter_service_id | UUID | Filter by service ID |
page | Integer | Page number (default: 1) |
per_page | Integer | Items per page (default: 25, max: 100) |
Example Request:
GET /api/v2/clinical/facilities/01900002-0000-7000-8000-000000000001/facility_categories?page=1&per_page=25Response:
{
"data": [
{
"id": "019c4bf4-4e0b-7eac-98d2-9c55d88705bb",
"created_at": "2026-02-11T09:07:07Z",
"updated_at": "2026-02-11T09:07:07Z",
"name": "Diabetes Care",
"description": "Diabetes management category",
"color_code": "#222222",
"camp_category": false,
"active": true,
"patient_count": 0,
"category_rules": [
{
"id": "019c4bf4-4e89-7d54-ab75-2b804e318d6c",
"created_at": "2026-02-11T09:07:08Z",
"updated_at": "2026-02-11T09:07:08Z",
"rule_type": "AGE_GENDER",
"min_age": 18,
"max_age": 65,
"gender_list": ["Male", "Female"]
}
],
"category_services": [
{
"id": "019c4bf4-4ee9-7420-9f21-5344ae894e8a",
"created_at": "2026-02-11T09:07:08Z",
"updated_at": "2026-02-11T09:07:08Z",
"discount_percentage": "10.0",
"facility_service_ids": ["019c4742-0e42-7de2-91f9-56122dc732fd"],
"facility_services": [
{
"id": "019c4bf4-4f9d-744c-81cd-508308efb0a6",
"facility_service_id": "019c4742-0e42-7de2-91f9-56122dc732fd",
"name": "General Consultation"
}
]
}
]
}
],
"meta": {
"pagination": {
"total_entries": 1,
"total_pages": 1,
"current_page": 1,
"per_page": 1
},
"request_id": "7577cfc9-99f4-43f4-9348-d9a5bab0ec06"
}
}2. Create Facility Category
Create a new facility category with rules and services.
Endpoint: POST /clinical/facilities/:facility_id/facility_categories
Request Body:
{
"facility_category": {
"name": "Diabetes Care",
"description": "Diabetes management category",
"camp_category": false,
"category_rules": [
{
"rule_type": "AGE_GENDER",
"min_age": 18,
"max_age": 65,
"gender_list": ["male", "female", "other"]
}
],
"category_service_groups": [
{
"discount_percentage": 10.0,
"facility_service_ids": [
"019c4742-0e42-7de2-91f9-56122dc732fd"
]
}
]
}
}Field Descriptions:
| Field | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Category name |
description | String | No | Category description |
camp_category | Boolean | No | Default: false |
category_rules | Array | No | Array of rule objects |
category_service_groups | Array | No | Array of service group objects |
Category Rule Fields:
| Field | Type | Description |
|---|---|---|
rule_type | String | Rule type (default: "AGE_GENDER") |
min_age | Integer | Minimum age (optional) |
max_age | Integer | Maximum age (optional) |
gender_list | Array | Gender filter: ["male", "female", "other"] |
Category Service Group Fields:
| Field | Type | Description |
|---|---|---|
discount_percentage | Decimal | Discount percentage (default: 0.0) |
facility_service_ids | Array | Array of facility service IDs |
Response (201 Created):
{
"data": {
"id": "019c4bed-8e14-7529-8d5e-530b9d2d573e",
"created_at": "2026-02-11T08:59:45Z",
"updated_at": "2026-02-11T08:59:45Z",
"name": "Diabetes Care",
"description": "Diabetes management category",
"color_code": "#222222",
"camp_category": false,
"active": true,
"patient_count": 0,
"category_rules": [
{
"id": "019c4bed-8e1e-71df-ac3a-218005c6a204",
"created_at": "2026-02-11T08:59:45Z",
"updated_at": "2026-02-11T08:59:45Z",
"rule_type": "AGE_GENDER",
"min_age": 18,
"max_age": 65,
"gender_list": ["Male", "Female"]
}
],
"category_services": [
{
"id": "019c4bed-8e21-794e-885b-dd43785a1542",
"created_at": "2026-02-11T08:59:45Z",
"updated_at": "2026-02-11T08:59:45Z",
"discount_percentage": "10.0",
"facility_service_ids": ["019c4742-0e42-7de2-91f9-56122dc732fd"],
"facility_services": [
{
"id": "019c4bed-8e2e-7e9c-b9f4-b8c7e9d1a3f5",
"facility_service_id": "019c4742-0e42-7de2-91f9-56122dc732fd",
"name": "General Consultation"
}
]
}
]
},
"meta": {
"request_id": "e9e1c761-a16d-40d0-9601-9a9c4d8e0dec"
}
}3. Get Facility Category
Get a single facility category by ID.
Endpoint: GET /clinical/facilities/:facility_id/facility_categories/:id
Response (200 OK): Same as create response.
4. Update Facility Category
Update an existing facility category.
Endpoint: PUT /clinical/facilities/:facility_id/facility_categories/:id
Request Body: Same as create request.
Response (200 OK): Same as create response.
Notes:
- Include existing records with their
idto update them - Omit records to remove them
- Add new records without
idto create them
5. Delete Facility Category
Soft delete a facility category.
Endpoint: DELETE /clinical/facilities/:facility_id/facility_categories/:id
Response (204 No Content)
Error Handling
All error responses follow this standard format:
{
"data": null,
"error": {
"code": "error_code",
"message": "Human-readable error message",
"details": [
{
"field": "field_name",
"message": "Specific error message"
}
]
},
"meta": {
"request_id": "unique-request-id"
}
}Validation Error (422)
{
"data": null,
"error": {
"code": "validation_failed",
"message": "Name is required",
"details": [
{
"field": "name",
"message": "Name is required"
}
]
},
"meta": {
"request_id": "abc-123-def-456"
}
}Common validation errors:
| Error | Field | Message |
|---|---|---|
| Name required | name | Name is required |
| Duplicate name | base | Category 'X' already exists |
| Invalid age | filter_age | Age must be between 0 and 150 |
| Invalid gender | filter_gender | Gender must be male, female, or other |
| Service not found | filter_service_id | Service not found |
Not Found (404)
{
"data": null,
"error": {
"code": "not_found",
"message": "Resource not found",
"details": [
{
"field": "base",
"message": "Resource not found"
}
]
},
"meta": {
"request_id": "7b2115b5-08e1-4e3e-802a-c66be04776f7"
}
}Unauthorized (401)
{
"data": null,
"error": {
"code": "unauthorized",
"message": "Authentication required",
"details": []
},
"meta": {
"request_id": "xyz-789-ghi-012"
}
}Forbidden (403)
{
"data": null,
"error": {
"code": "forbidden",
"message": "You don't have permission to perform this action",
"details": []
},
"meta": {
"request_id": "xyz-789-ghi-012"
}
}Frontend Tips
-
Color Codes: The
color_codefield is auto-assigned based on the least used color in the facility. Display this color for visual distinction. -
Patient Count: This is calculated dynamically and may require refresh after patient categorization changes.
-
Gender Display: The API returns capitalized gender values ("Male", "Female", "Other") for display purposes, but accepts lowercase ("male", "female", "other") in requests.
-
Age Validation:
min_ageandmax_agecan be null (no age restriction)min_agemust be <=max_age(when both are present)- Valid age range: 0-150
-
Service Association: Services must belong to the same facility. Invalid service IDs are silently ignored.
-
Soft Delete: Deleted categories are filtered out by default. Use the
deleted_atfield internally for recovery if needed.