REST API
Create and control timers programmatically. Integrate with your app, dashboard, or automation tools.
Authentication
All API requests (except GET /events) require authentication via a Bearer token in the Authorization header.
Get your API key from your dashboard at castimer.com/dashboard/api-keys. API keys are available on Pro and Enterprise plans.
Authorization: Bearer YOUR_API_KEYKeep your API key secret. Never expose it in client-side JavaScript or public repositories.
Base URL
https://castimer.com/api/v1Required Headers
Content-Type: application/json
Authorization: Bearer YOUR_API_KEYEndpoints
/eventsReturns a list of upcoming public holidays and events with their countdown data. No authentication required.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| year | integer | No | Filter by year. Default: current year |
| region | string | No | Filter by region code (US, CN, TW, UK, JP, AU) |
| tz | string | No | Timezone for countdown calculation. Default: UTC |
Request
curl 'https://castimer.com/api/v1/events?region=US&year=2026&tz=America/New_York'Response
{
"events": [
{
"name": "Independence Day",
"slug": "independence-day",
"date": "2026-07-04",
"remaining": {
"days": 55,
"hours": 14,
"minutes": 32,
"seconds": 18,
"total_seconds": 4807938
},
"passed": false
},
{
"name": "Thanksgiving",
"slug": "thanksgiving",
"date": "2026-11-26",
"remaining": {
"days": 200,
"hours": 3,
"minutes": 12,
"seconds": 44,
"total_seconds": 17284364
},
"passed": false
}
],
"timezone": "America/New_York",
"region": "US"
}/timersCreate a new timer. Returns viewer URL, embed URL, and control URL.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| title | string | No | Display title. Max 100 chars |
| type | enum | Yes | countdown, event, interval |
| duration | integer | Cond. | Seconds. Required if type=countdown |
| target_date | string | Cond. | ISO8601. Required if type=event |
| work | integer | Cond. | Work seconds. Required if type=interval |
| rest | integer | Cond. | Rest seconds. Required if type=interval |
| rounds | integer | No | Number of cycles. Default: unlimited |
| theme | enum | No | light, dark, auto. Default: light |
| color | string | No | Hex color without #. Default: 6C63FF |
| webhook_url | string | No | URL to notify when timer completes |
Request
curl -X POST 'https://castimer.com/api/v1/timers' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Product Launch Countdown",
"type": "countdown",
"duration": 1800,
"theme": "dark",
"color": "6C63FF",
"webhook_url": "https://yourapp.com/webhooks/castimer"
}'Response
{
"timer_id": "tmr_abc123xyz",
"title": "Product Launch Countdown",
"type": "countdown",
"duration": 1800,
"state": "idle",
"theme": "dark",
"viewer_url": "https://castimer.com/v/tmr_abc123xyz",
"embed_url": "https://castimer.com/widget?id=tmr_abc123xyz",
"control_url": "https://castimer.com/c/tmr_abc123xyz",
"created_at": "2026-05-10T09:00:00Z",
"expires_at": "2026-06-09T09:00:00Z"
}/timers/:idRetrieve the current state and details of a timer.
Request
curl 'https://castimer.com/api/v1/timers/tmr_abc123xyz' \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"timer_id": "tmr_abc123xyz",
"title": "Product Launch Countdown",
"type": "countdown",
"duration": 1800,
"remaining_seconds": 1654,
"state": "running",
"started_at": "2026-05-10T09:03:00Z",
"viewer_url": "https://castimer.com/v/tmr_abc123xyz",
"embed_url": "https://castimer.com/widget?id=tmr_abc123xyz"
}/timers/:id/stateControl timer playback state.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| action | enum | Yes | start, pause, resume, reset, stop |
Request
curl -X PATCH 'https://castimer.com/api/v1/timers/tmr_abc123xyz/state' \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"action": "start"}'Response
{
"timer_id": "tmr_abc123xyz",
"state": "running",
"remaining_seconds": 1800,
"started_at": "2026-05-10T09:05:00Z"
}/timers/:idPermanently delete a timer and all associated data.
Request
curl -X DELETE 'https://castimer.com/api/v1/timers/tmr_abc123xyz' \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"deleted": true,
"timer_id": "tmr_abc123xyz"
}Error Codes
| Code | HTTP Status | Description |
|---|---|---|
| 401 | Unauthorized | Missing or invalid API key |
| 403 | Forbidden | Plan does not include API access |
| 404 | Not Found | Timer not found or expired |
| 422 | Unprocessable | Missing required fields or invalid values |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Server Error | Unexpected error. Contact support |
Error Response Format
{
"error": {
"code": 422,
"message": "duration is required when type is countdown",
"field": "duration"
}
}Rate Limits
| Plan | Requests/minute | Timers stored |
|---|---|---|
| Free | — | Public events only |
| Pro | 60 | 50 active timers |
| Enterprise | 600 | Unlimited |
Rate limit headers are included in every response:X-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Reset
SDK & Libraries
Official SDKs are in development. In the meantime, use the REST API directly or try the community examples below.
JavaScript / Node.js
const response = await fetch('https://castimer.com/api/v1/timers', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
title: 'Team Meeting',
type: 'countdown',
duration: 900
})
});
const timer = await response.json();
console.log(timer.viewer_url);Python
import requests
response = requests.post(
'https://castimer.com/api/v1/timers',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'title': 'Team Meeting',
'type': 'countdown',
'duration': 900
}
)
timer = response.json()
print(timer['viewer_url'])