# Timezone Scheduler > A meeting planner API for scheduling across timezones. The schedule, suggest, and validate actions accept any valid IANA timezone ID (450+ in the IANA database); the search action covers a curated database of ~140 major cities by name. All times are DST-aware. Available at https://timezones.centminmod.com > > **API versioning**: All API endpoints support an optional `/v1/` prefix (e.g. `/api/v1/timezone-data`, `/schedule/api/v1?action=schedule`). Unversioned paths continue to work. The Timezone Scheduler helps coordinate meetings across global timezones. It classifies each participant's local time into business hours (9 AM-5 PM), extended hours (7-9 AM or 5-9 PM), or off hours (9 PM-7 AM), and can suggest optimal meeting times. > **IMPORTANT — Parameter names are `from` and `to`.** Do NOT use "source", "destination", "timezone", or "tz". The API returns 400 for wrong parameter names. ## GET URL Template (copy and fill in values) ``` /schedule/api?action=schedule&from={IANA_TIMEZONE}&date={YYYY-MM-DD}&hour={0-23}&minute={0-59}&to={IANA_TIMEZONE} ``` For multiple destinations, repeat the `to` parameter: `&to=Europe/London&to=America/New_York` ## Common City → Timezone Quick Reference Use this table to map city names directly to IANA timezone IDs without calling search first. | City | IANA Timezone | |------|--------------| | New York, Miami, Toronto | America/New_York | | Chicago, Houston | America/Chicago | | Denver | America/Denver | | Phoenix | America/Phoenix | | Los Angeles, San Francisco, Vancouver | America/Los_Angeles | | Anchorage | America/Anchorage | | Honolulu | Pacific/Honolulu | | Mexico City | America/Mexico_City | | Bogota | America/Bogota | | Lima | America/Lima | | Santiago | America/Santiago | | Sao Paulo | America/Sao_Paulo | | Buenos Aires | America/Argentina/Buenos_Aires | | London | Europe/London | | Paris, Amsterdam, Berlin, Madrid, Rome | Europe/Paris | | Istanbul | Europe/Istanbul | | Moscow | Europe/Moscow | | Cairo | Africa/Cairo | | Dubai | Asia/Dubai | | Mumbai, Delhi, Bangalore, Kolkata | Asia/Kolkata | | Singapore | Asia/Singapore | | Kuala Lumpur | Asia/Kuala_Lumpur | | Bangkok | Asia/Bangkok | | Jakarta | Asia/Jakarta | | Hong Kong | Asia/Hong_Kong | | Shanghai, Beijing | Asia/Shanghai | | Tokyo, Osaka | Asia/Tokyo | | Seoul | Asia/Seoul | | Sydney | Australia/Sydney | | Melbourne | Australia/Melbourne | | Brisbane | Australia/Brisbane | | Perth | Australia/Perth | | Auckland, Wellington | Pacific/Auckland | For unlisted cities, use `action=search&q=city_name` to find the IANA timezone ID. ## Quick Start — One-Call Examples Most timezone questions can be answered in a single API call. If you recognize the city, map it to an IANA timezone ID from the reference table above and call `schedule` directly — do NOT call `search` first. When the user does not specify a date, use today's date in YYYY-MM-DD format. When they do not specify a time, default to 9:00 AM in the source timezone. Minutes must be 0-59. **"Find the timezones for Brisbane to Denver"** ``` GET /schedule/api?action=schedule&from=Australia/Brisbane&date=2026-03-23&hour=9&minute=0&to=America/Denver ``` **"What time is it in London when it's 3pm in New York?"** ``` GET /schedule/api?action=schedule&from=America/New_York&date=2026-03-23&hour=15&minute=0&to=Europe/London ``` **"Schedule a 2:30pm meeting in Tokyo for people in London and New York"** ``` GET /schedule/api?action=schedule&from=Asia/Tokyo&date=2026-03-23&hour=14&minute=30&to=Europe/London&to=America/New_York ``` **"Best time for a call between Brisbane, Denver, and London?"** ``` GET /schedule/api?action=suggest&from=Australia/Brisbane&date=2026-03-23&to=America/Denver&to=Europe/London ``` **"What timezone is Kathmandu in?"** (only use search when the city is unfamiliar) ``` GET /schedule/api?action=search&q=kathmandu ``` **Always use today's actual date** in YYYY-MM-DD format — do not copy the example dates above. ## Which Action to Use - **User mentions cities and wants to compare or convert times** → Use `schedule`. Map city names to IANA timezone IDs from the reference table above. No search call needed. - **User asks for "best time" or "find a good time" for a meeting** → Use `suggest` with all participant timezones. - **User asks about an unfamiliar city or "what timezone is X in"** → Use `search` to look it up, then use the returned IANA timezone ID in a `schedule` or `suggest` call. - **You only need to check whether a proposed time works (pre-flight guard before booking)** → Use `validate`: same inputs as schedule, returns only business-hours/weekend/holiday assessment (no invite text or share link). Do NOT call `search` before `schedule` when you already know the IANA timezone ID. Most major world cities are in the reference table above. ## API Endpoint - [Schedule API](/schedule/api): Single endpoint for scheduling meetings, finding optimal times, and searching cities. Supports GET and POST. - [OpenAPI Schema](/schedule/api/schema): Machine-readable OpenAPI 3.1 specification. - [MCP Tool Definition](/schedule/api/mcp): Ready-to-use MCP tool definition for AI systems. ## Actions The `/schedule/api` endpoint accepts an `action` parameter with four values: schedule, suggest, search, validate. ### schedule Schedule a meeting and get converted times for all participants. Required parameters: - action: "schedule" - from: Source IANA timezone (e.g., "America/New_York") - date: Valid calendar date in YYYY-MM-DD format (overflow dates like 2026-02-30 are rejected) - hour: Hour 0-23 - minute: Minute (0-59) - to: One or more destination timezones (max 6). **In GET requests, repeat the parameter:** `&to=Europe/London&to=Asia/Tokyo`. **In POST requests, use a JSON array:** `[{"timezone":"Europe/London"},{"timezone":"Asia/Tokyo"}]`. Each object has "timezone" (required), optional "name" (max 100 chars), and optional "hours" `{"start":10,"end":18}` to override the default 9-17 business window for that participant (POST/MCP only). Optional parameters: - durationMinutes: Meeting duration in minutes (default 60, range 15-480) - fromHours: Source timezone's own working hours `{"start":8,"end":16}` to override the default 9-17 window when classifying the source participant (POST/MCP JSON, or GET `fromHours=8-16`) - title / notes: optional meeting title (max 120 chars) and notes (max 500 chars); both round-trip into the v:3 share link and the invite text - recurrence (POST/MCP only): `{"freq":"daily"|"weekly"|"biweekly"|"monthly","count":2-12}` — expands the meeting into occurrences. Each occurrence is resolved independently, so DST transitions show up as `"dstShifted": true` with the actual per-occurrence destination times. - format: "ics" returns a downloadable text/calendar file instead of JSON (one VEVENT per occurrence with exact UTC instants — DST-correct for recurring meetings). Honored over MCP too (ICS text comes back in the content block). POST requests must include Content-Type: application/json header. Max body size: 4KB. Response extras: source and each destination include `isWeekend` (regional weekends: Fri-Sat in most of the Middle East, Sat in Nepal) and `holiday` (national holiday name, or null). Holidays cover fixed-date national holidays PLUS movable ones — Easter-derived (Good Friday, Easter Monday), a curated lunisolar table (Eid al-Fitr, Eid al-Adha, Diwali, Lunar New Year, refreshed yearly), and observed-in-lieu substitute days when a fixed holiday lands on a weekend. Lunisolar dates are the widely-observed national date and may shift ±1 day by local moon sighting. GET example (jq): ``` curl -s "https://timezones.centminmod.com/schedule/api?action=schedule&from=America/New_York&date=2026-03-22&hour=14&minute=30&to=Europe/London&to=Asia/Tokyo" | jq . ``` GET example (python3): ``` curl -s "https://timezones.centminmod.com/schedule/api?action=schedule&from=America/New_York&date=2026-03-22&hour=14&minute=30&to=Europe/London&to=Asia/Tokyo" | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" ``` POST example (jq): ``` curl -s -X POST https://timezones.centminmod.com/schedule/api \ -H "Content-Type: application/json" \ -d '{"action":"schedule","from":"America/New_York","date":"2026-03-22","hour":14,"minute":30,"to":[{"timezone":"Europe/London"},{"timezone":"Asia/Tokyo"}]}' | jq . ``` POST example (python3): ``` curl -s -X POST https://timezones.centminmod.com/schedule/api \ -H "Content-Type: application/json" \ -d '{"action":"schedule","from":"America/New_York","date":"2026-03-22","hour":14,"minute":30,"to":[{"timezone":"Europe/London"},{"timezone":"Asia/Tokyo"}]}' | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" ``` Returns: meeting times in each timezone, business hours classification, day offsets, UTC start/end timestamps, a shareable link, and a plain-text invite. If the requested time falls in a DST gap, the response includes `"timeAdjusted": true` in the meeting object. ### suggest Find optimal meeting times where the most participants are in business hours. Required parameters: - action: "suggest" - from: Source IANA timezone - date: Date in YYYY-MM-DD format - to: One or more destination timezones (max 6); POST/MCP destination objects accept optional "hours" `{"start":10,"end":18}` per participant Optional parameters: - limit: Max suggestions to return (1-20, default 5) - dateEnd: End date (YYYY-MM-DD) to search a range — every day from date to dateEnd (max 7 days) is scored and ranked together; each suggestion carries its `date` - durationMinutes: Meeting length (15-480, default 60). Each slot is scored by the WORSE of its start and end hour, so a long meeting that runs out of business hours ranks lower - fromHours: Source timezone's own working hours `{"start":8,"end":16}` (POST/MCP JSON, or GET `fromHours=8-16`) — overrides the 9-17 default when scoring the source participant GET example (jq): ``` curl -s "https://timezones.centminmod.com/schedule/api?action=suggest&from=Australia/Brisbane&date=2026-03-22&to=Europe/London&to=America/New_York" | jq . ``` GET example (python3): ``` curl -s "https://timezones.centminmod.com/schedule/api?action=suggest&from=Australia/Brisbane&date=2026-03-22&to=Europe/London&to=America/New_York" | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" ``` Returns: Top suggestions (default 5, configurable via limit) ranked by business-hours overlap score. Each participant is classified by the WORSE of the meeting's start and end hour (duration-aware via durationMinutes), scored business=3pts, extended=1pt, off=0pts per participant; weekend penalty: -1pt per participant whose LOCAL day is a weekend in their region — Sat/Sun by default, Fri/Sat in most of the Middle East, Sat only in Nepal; holiday penalty: -1pt per participant whose local date is a national holiday — fixed-date plus movable (Easter/Good Friday, Eid, Diwali, Lunar New Year) and observed-in-lieu days), then by comfort tie-break (minComfort: circular distance from 3 AM, 0-12 scale, min across all participants — prefers 11 PM over midnight, 9 PM over 2 AM). Top-level response includes isWeekend (boolean). Each suggestion includes date, score, scorePercent, minComfort, allBusiness, allExtended, and times for all participants (each with businessHours classification and a holiday name when applicable). ### search Search for cities and timezones. Required parameters: - action: "search" - q: Search query (2-100 characters) GET examples (jq): ``` curl -s "https://timezones.centminmod.com/schedule/api?action=search&q=brisbane" | jq . curl -s "https://timezones.centminmod.com/schedule/api?action=search&q=london%20united" | jq . ``` GET examples (python3): ``` curl -s "https://timezones.centminmod.com/schedule/api?action=search&q=brisbane" | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" curl -s "https://timezones.centminmod.com/schedule/api?action=search&q=london%20united" | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" ``` The query matches against city name, country name, and IANA timezone ID combined. Use "city country" format (e.g., "london united") to disambiguate cities with the same name in different countries. Returns: Matching cities with timezone and UTC offset. Note: search covers a curated ~140-city database. Some curated cities that share a timezone with a larger city (e.g., Miami shares America/New_York) may not appear in search results — use the IANA timezone ID directly in schedule/suggest actions instead (any valid IANA ID is accepted). ### validate Lightweight pre-flight check: same parameters as `schedule` (required action, from, date, hour, minute, to; optional durationMinutes and fromHours) and the same validation rules, but returns only the assessment — per-participant time24h, businessHours, endTime24h, endBusinessHours, isWeekend, holiday, plus the summary booleans (allInBusinessHours, allInExtendedHours). No invite text, share link, or recurrence expansion. Use it as a cheap guard step before booking a slot in a calendar. GET example: ``` curl -s "https://timezones.centminmod.com/schedule/api?action=validate&from=America/New_York&date=2026-07-04&hour=10&minute=0&to=Europe/London" | jq . ``` ## Business Hours Classification - business: 9 AM - 5 PM local time (ideal) - extended: 7-9 AM or 5-9 PM local time (acceptable) - off: 9 PM - 7 AM local time (avoid if possible) ## Response Format All responses are JSON with an `ok` boolean. On success, fields vary by action. On error: ```json {"ok": false, "error": {"code": "ERROR_CODE", "message": "Human-readable description", "field": "field_name"}} ``` ## Curated Cities 80+ major business and tech hubs covering: Americas (Anchorage to Montevideo), Europe (Reykjavik to Moscow), Middle East (Riyadh, Dubai, Tehran), Asia (Karachi to Tokyo), Africa (Casablanca to Johannesburg), and Oceania (Perth to Fiji). Search covers a curated ~140-city database; schedule/suggest/validate accept any valid IANA timezone ID (450+). ## Share Links The shareable link encodes meeting state as URL-safe base64 in the `?m=` query parameter. Opening the link in a browser loads the interactive scheduler with all participants pre-filled. ## Integration Setup instructions for registering the Timezone Scheduler as a tool in AI coding harnesses. ### As a Skill (SKILL.md) SKILL.md is an open standard supported by Claude Code, Codex CLI, Copilot CLI, OpenCode, and Kilo CLI. Create a `timezone-scheduler` directory in the appropriate skill path and add this SKILL.md: ```yaml --- name: timezone-scheduler description: Schedule meetings across timezones, find optimal meeting times, and search cities/timezones. Use when the user asks about scheduling meetings, comparing times, or finding the best time for participants in different cities. allowed-tools: Bash(curl *) --- # Timezone Scheduler Call the API at https://timezones.centminmod.com/schedule/api via POST with Content-Type: application/json. ## schedule — Convert a meeting time across timezones Using jq: curl -s -X POST https://timezones.centminmod.com/schedule/api \ -H "Content-Type: application/json" \ -d '{"action":"schedule","from":"Australia/Brisbane","date":"2026-03-22","hour":14,"minute":30,"to":[{"timezone":"Europe/London"},{"timezone":"America/New_York"}]}' | jq . Using python3: curl -s -X POST https://timezones.centminmod.com/schedule/api \ -H "Content-Type: application/json" \ -d '{"action":"schedule","from":"Australia/Brisbane","date":"2026-03-22","hour":14,"minute":30,"to":[{"timezone":"Europe/London"},{"timezone":"America/New_York"}]}' | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" Required: action, from (IANA timezone), date (YYYY-MM-DD), hour (0-23), minute (0-59), to (array of {timezone, name?}, max 6). Optional: durationMinutes (15-480, default 60). ## suggest — Find optimal meeting times Using jq: curl -s -X POST https://timezones.centminmod.com/schedule/api \ -H "Content-Type: application/json" \ -d '{"action":"suggest","from":"Australia/Brisbane","date":"2026-03-22","to":[{"timezone":"Europe/London"},{"timezone":"America/New_York"}]}' | jq . Using python3: curl -s -X POST https://timezones.centminmod.com/schedule/api \ -H "Content-Type: application/json" \ -d '{"action":"suggest","from":"Australia/Brisbane","date":"2026-03-22","to":[{"timezone":"Europe/London"},{"timezone":"America/New_York"}]}' | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" Required: action, from, date, to. Optional: limit (1-20, default 5), dateEnd (range search up to 7 days). Returns top N slots ranked by business-hours overlap score (weekend penalty: -1pt per weekend participant, regional weekends respected; holiday penalty: -1pt per participant on a fixed-date national holiday), then by comfort tie-break (minComfort — prefers civil evening hours over deep night for off-hours participants). Response includes isWeekend, allBusiness, allExtended fields. ## search — Find a city or timezone Using jq: curl -s "https://timezones.centminmod.com/schedule/api?action=search&q=tokyo" | jq . curl -s "https://timezones.centminmod.com/schedule/api?action=search&q=london%20united" | jq . Using python3: curl -s "https://timezones.centminmod.com/schedule/api?action=search&q=tokyo" | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" curl -s "https://timezones.centminmod.com/schedule/api?action=search&q=london%20united" | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" Required: action, q (2-100 chars). Matches against city name, country, and IANA timezone ID. Use "city country" to disambiguate same-name cities. ## Response format JSON with ok:true on success. Schedule returns times, business hours (business/extended/off), UTC timestamps, share link, invite text. Suggest returns scored time slots with isWeekend, allBusiness, allExtended, and minComfort tie-break (0-12, higher=more civil hours for worst-off participant). Errors: {"ok":false,"error":{"code":"...","message":"...","field":"..."}}. ``` Skill directory paths by harness: - Claude Code CLI: `.claude/skills/timezone-scheduler/SKILL.md` (project) or `~/.claude/skills/timezone-scheduler/SKILL.md` (global) - Codex CLI / Codex App: `.codex/skills/timezone-scheduler/SKILL.md` (project) or `~/.codex/skills/timezone-scheduler/SKILL.md` (global) - Copilot CLI: `.github/skills/timezone-scheduler/SKILL.md` (project) or `~/.copilot/skills/timezone-scheduler/SKILL.md` (global) - OpenCode CLI: `.opencode/skills/timezone-scheduler/SKILL.md` (project) or `~/.config/opencode/skills/timezone-scheduler/SKILL.md` (global) - Kilo CLI: `.kilocode/skills/timezone-scheduler/SKILL.md` (project) or `~/.config/kilo/skills/timezone-scheduler/SKILL.md` (global) #### Claude Code SKILL.md Frontmatter Reference Claude Code skills support these YAML frontmatter fields: | Field | Description | |-------|-------------| | name | Display name and /slash-command (lowercase, hyphens, max 64 chars) | | description | What the skill does — Claude uses this to decide when to auto-load | | allowed-tools | Tools Claude can use without permission prompts (e.g., `Bash(curl *), Read, Grep`) | | disable-model-invocation | Set `true` to prevent Claude from auto-triggering (manual /invoke only) | | user-invocable | Set `false` to hide from / menu (background knowledge only) | | context | Set `fork` to run in an isolated subagent | | agent | Subagent type when context=fork (e.g., `Explore`, `Plan`, `general-purpose`) | | model | Override model (e.g., `sonnet`, `opus`, `haiku`) | | argument-hint | Autocomplete hint (e.g., `[issue-number]`) | Common allowed-tools values: `Bash`, `Read`, `Write`, `Edit`, `Grep`, `Glob`, `Agent`, `TodoWrite`, `WebFetch`, `WebSearch`, `LSP`, `NotebookEdit`. Use `Bash(pattern)` to restrict to specific commands (e.g., `Bash(curl *)`, `Bash(npm *)`). MCP tools use the `mcp__server__tool` format. String substitutions in skill content: `$ARGUMENTS` (all args), `$ARGUMENTS[N]` or `$N` (positional), `${CLAUDE_SKILL_DIR}` (skill directory path), `${CLAUDE_SESSION_ID}` (session ID). ### As an MCP Server The endpoint at `https://timezones.centminmod.com/schedule/api/mcp` is a real MCP server implementing the streamable-HTTP transport (JSON-RPC 2.0). It supports initialize, tools/list, tools/call, and ping. Claude Code CLI: ``` claude mcp add --transport http timezone-scheduler https://timezones.centminmod.com/schedule/api/mcp ``` Claude Desktop: Add via Settings > Connectors. URL: https://timezones.centminmod.com/schedule/api/mcp Gemini CLI (~/.gemini/settings.json): ```json { "mcpServers": { "timezone-scheduler": { "command": "npx", "args": ["-y", "mcp-remote@latest", "https://timezones.centminmod.com/schedule/api/mcp"] } } } ``` OpenCode CLI (~/.config/opencode/opencode.json): ```json { "mcp": { "timezone-scheduler": { "type": "remote", "url": "https://timezones.centminmod.com/schedule/api/mcp" } } } ``` Kilo CLI (~/.config/kilo/opencode.json): ```json { "mcp": { "timezone-scheduler": { "type": "remote", "url": "https://timezones.centminmod.com/schedule/api/mcp" } } } ``` ### Quick Test ``` curl -s "https://timezones.centminmod.com/schedule/api?action=search&q=london" | jq . curl -s "https://timezones.centminmod.com/schedule/api?action=search&q=london" | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" ``` ## Optional - [Interactive Scheduler](https://timezones.centminmod.com/): Web UI with world map, 24-hour comparison grid, and clipboard invite export - [Timezone Data API](/api/timezone-data?ref=UTC): Raw timezone data for all 80 curated cities - [Search API](/api/search?q=london&ref=UTC): Search a curated ~140-city database by name (any IANA ID works directly in schedule/suggest) - [MCP Tool Definition](/schedule/api/mcp/definition): Static JSON tool definition for reference