The Kal API provides access to Malaysian food nutritional data. All API endpoints require authentication via API key.
🌐 Production API Base URL: https://api.kalori-api.my/api/v1
All API requests require an API key to be passed in the x-api-key header.
curl -H "x-api-key: YOUR_API_KEY" https://api.kalori-api.my/api/v1/foods- Sign in at https://kalori-api.my
- Navigate to the Dashboard
- Generate a new API key
Search natural foods by name.
GET /api/v1/foods/search
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
q |
string | ✅ Yes | Search query (e.g., "nasi lemak") |
Example Request:
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.kalori-api.my/api/v1/foods/search?q=nasi"Example Response:
{
"success": true,
"data": [
{
"id": "6789abc123def456",
"name": "Nasi Lemak",
"calories": 450,
"protein": 12,
"carbs": 55,
"fat": 20,
"serving": "1 plate",
"category": "Rice"
}
],
"count": 1
}Get all natural foods with optional filtering and pagination.
GET /api/v1/foods
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
category |
string | No | Filter by category (e.g., "Rice") |
limit |
integer | No | Max results (default: 50, max: 200) |
offset |
integer | No | Pagination offset (default: 0) |
Example Request:
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.kalori-api.my/api/v1/foods?category=Rice&limit=10"Example Response:
{
"success": true,
"data": [...],
"pagination": {
"total": 25,
"limit": 10,
"offset": 0,
"hasMore": true
}
}Get a single natural food item by its ID.
GET /api/v1/foods/:id
Path Parameters:
| Parameter | Type | Description |
|---|---|---|
id |
string | MongoDB ObjectId |
Example Request:
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.kalori-api.my/api/v1/foods/6789abc123def456"Get all available food categories.
GET /api/v1/categories
Example Request:
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.kalori-api.my/api/v1/categories"Example Response:
{
"success": true,
"data": [
"Basics",
"Desserts",
"Drinks",
"Meat",
"Noodles",
"Rice",
"Seafood",
"Snacks",
"Soups",
"Vegetables"
]
}Search halal-certified foods by name.
GET /api/v1/halal/search
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
q |
string | ✅ Yes | Search query |
Example Request:
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.kalori-api.my/api/v1/halal/search?q=chicken"Get all halal foods with optional filtering and pagination.
GET /api/v1/halal
Query Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
brand |
string | No | Filter by brand |
category |
string | No | Filter by category |
limit |
integer | No | Max results (default: 50, max: 200) |
offset |
integer | No | Pagination offset (default: 0) |
GET /api/v1/halal/:id
Get all halal food brands.
GET /api/v1/halal/brands
Example Response:
{
"success": true,
"data": ["Brand A", "Brand B", "Brand C"]
}Get overall database statistics including food counts and categories.
GET /api/v1/stats
Example Request:
curl -H "x-api-key: YOUR_API_KEY" \
"https://api.kalori-api.my/api/v1/stats"Example Response:
{
"success": true,
"data": {
"naturalFoods": {
"total": 100,
"categories": ["Rice", "Noodles", "Meat", ...]
},
"halalFoods": {
"total": 50,
"brands": ["Brand A", "Brand B", ...]
}
}
}All endpoints return consistent error responses:
{
"success": false,
"error": "Error message"
}| Status | Description |
|---|---|
| 200 | Success |
| 400 | Bad request (invalid params) |
| 401 | Unauthorized (invalid API key) |
| 404 | Resource not found |
| 429 | Too many requests (rate limit) |
| 500 | Internal server error |
API requests are rate-limited per API key with multiple levels of protection:
| Tier | Per Minute | Per Day | Per Month | Burst Bonus | Max Burst |
|---|---|---|---|---|---|
| Free | 65 | 3,300 | 95,000 | +15 | 80 |
| Tier 1 | 130 | 6,600 | 195,000 | +30 | 160 |
| Tier 2 | 145 | 7,500 | 215,000 | +45 | 190 |
- Burst Window: 10 seconds
- Burst Bonus: Extra requests allowed within the burst window
- Max Burst Total: Maximum requests allowed including burst bonus
- Max Requests Per Second: 20 req/sec
- Max Concurrent Per API Key: 5 requests
Rate limit headers are included in all responses:
X-RateLimit-Limit-Minute: 65
X-RateLimit-Remaining-Minute: 60
X-RateLimit-Limit-Daily: 3300
X-RateLimit-Remaining-Daily: 3295
X-RateLimit-Limit-Monthly: 95000
Retry-After: 5
X-RateLimit-Type: minute
interface Food {
id: string; // MongoDB ObjectId
name: string; // Food name
calories: number; // kcal per serving
protein: number; // grams
carbs: number; // grams
fat: number; // grams
serving: string; // Serving size (e.g., "1 plate")
category: string; // Category name
}interface HalalFood extends Food {
brand: string; // Brand name
halalCertifier: string; // Halal certification body
halalCertYear: number; // Year of certification
}The full OpenAPI 3.0 specification is available at:
https://api.kalori-api.my/openapi.json
For API support, please open an issue on GitHub.