API Documentation
COEkaki REST API v1 — access Singapore COE data programmatically.
Authentication
All endpoints support both authenticated and public access. Authenticated requests receive higher rate limits.
Pass your API key via the X-API-Key header. Never send keys as query parameters.
curl -H "X-API-Key: your_api_key_here" \
https://coekaki.com/api/v1/results/latest
Rate Limits
| Access Level | Rate Limit |
|---|---|
| Public (no API key) | 100 requests/minute |
| Authenticated (with API key) | 1,000 requests/minute |
Rate limit status is returned via X-RateLimit-* response headers.
Response Format
All responses return JSON with a consistent structure:
{
"data": [ ... ],
"meta": {
"total": 50,
"page": 1,
"per_page": 50,
"last_page": 1
}
}
Every response includes an X-API-Version: v1 header.
Error Codes
| HTTP Status | Code | Description |
|---|---|---|
| 401 | INVALID_API_KEY | The provided API key is not valid. |
| 404 | NOT_FOUND | The requested resource does not exist. |
| 422 | VALIDATION_ERROR | Request parameters failed validation. |
| 429 | RATE_LIMITED | Too many requests. Slow down and retry. |
COE Results
/api/v1/results
List COE bidding results with pagination and optional filters.
Parameters
| Param | Type | Description |
|---|---|---|
| category | string | Filter by category: A, B, C, D, or E |
| from | date | Start date (YYYY-MM-DD) |
| to | date | End date (YYYY-MM-DD) |
| page | integer | Page number (default: 1) |
| per_page | integer | Results per page (max: 200, default: 50) |
GET /api/v1/results?category=A&from=2025-01-01&to=2025-12-31
/api/v1/results/latest
Get the most recent bidding round results for all categories.
{
"data": [
{
"id": 1,
"bidding_date": "2026-04-09",
"bidding_round": 1,
"category": "A",
"quota_premium": 98000,
"pqp": 95000,
"bids_submitted": 2100,
"bids_successful": 1850
}
],
"meta": { "total": 5, "bidding_date": "2026-04-09" }
}
/api/v1/results/{id}
Retrieve a single COE result by its numeric ID. Returns 404 if not found.
Trends
/api/v1/trends
Historical COE premium trends grouped by category. Returns chart-ready data.
Parameters
| Param | Type | Description |
|---|---|---|
| months | integer | Number of months to look back (1-120, default: 12) |
| category | string | Filter to a single category: A, B, C, D, or E |
| from | date | Start date (YYYY-MM-DD) |
| to | date | End date (YYYY-MM-DD) |
/api/v1/trends/pqp
PQP (Prevailing Quota Premium) trends by category, including premium-vs-PQP spread.
PQP and its spread are null when historical data is insufficient or the category is E. Category E vehicles renew under their corresponding vehicle category A–D.
Accepts the same parameters as /trends.
Bidding Schedule
/api/v1/schedule
List all bidding schedules, ordered by most recent first.
/api/v1/schedule/upcoming
Upcoming bidding rounds that have not yet started.
/api/v1/schedule/current
Current live bidding round, if any. Returns data: null when no exercise is live.
{
"data": null,
"meta": {
"is_live": false,
"message": "No bidding exercise is currently live."
}
}
Deregistrations
/api/v1/deregistrations
List vehicle deregistration data with filters and pagination.
Parameters
| Param | Type | Description |
|---|---|---|
| category | string | Filter by category: A, B, C, D, or E |
| from | date | Start date (YYYY-MM-DD) |
| to | date | End date (YYYY-MM-DD) |
| per_page | integer | Results per page (max: 200, default: 50) |
/api/v1/deregistrations/latest
Latest month's deregistration data for all categories (or filter by category).
COE Quotas
/api/v1/quotas
List quarterly COE quota allocations with pagination and filters.
Parameters
| Param | Type | Description |
|---|---|---|
| category | string | Filter by category: A, B, C, D, or E |
| from | date | Start date for quarter_start (YYYY-MM-DD) |
| to | date | End date for quarter_start (YYYY-MM-DD) |
| per_page | integer | Results per page (max: 200, default: 50) |
/api/v1/quotas/latest
Current quarter's COE quota allocations. Falls back to the most recent quarter if current data is not yet available.
PQP History
/api/v1/pqp
PQP (Prevailing Quota Premium) history with premium-vs-PQP spread for each result.
PQP and its spread are null when historical data is insufficient or the category is E. Category E vehicles renew under their corresponding vehicle category A–D.
Parameters
| Param | Type | Description |
|---|---|---|
| category | string | Filter by category: A, B, C, D, or E |
| from | date | Start date (YYYY-MM-DD) |
| to | date | End date (YYYY-MM-DD) |
| per_page | integer | Results per page (max: 200, default: 50) |
{
"data": [
{
"id": 1,
"bidding_date": "2026-04-09",
"bidding_round": 1,
"category": "A",
"pqp": 95000,
"quota_premium": 98000,
"premium_vs_pqp": 3000
}
],
"meta": { "total": 50, "page": 1, "per_page": 50, "last_page": 1 }
}