API Documentation
ChronoShield API is a REST API that validates, resolves, and converts datetimes across timezones with explicit handling of DST ambiguity. It catches the edge cases that cause silent production bugs — invalid times that don't exist (spring-forward gaps) and ambiguous times that occur twice (fall-back overlaps).
https://chronoshieldapi.com
Not needed for simple UTC display formatting. Built for apps that interpret and act on user-entered local times.
When should I use ChronoShield API?
Use it whenever your application accepts, stores, or acts on local datetimes in any timezone. Specifically:
Real-World Scenarios
These are the exact situations where timezone bugs happen in production. Here's how ChronoShield API prevents each one.
Scenario 1: Scheduling a meeting during a DST gap
A user in New York picks March 8, 2026 at 2:30 AM for a standup. That time will never exist — clocks jump from 2:00 AM to 3:00 AM.
Your app stores 2:30 AM. The calendar event either fires at 3:30 AM (wrong) or not at all (worse). No error is raised.
Call /validate → get status: "invalid" + suggested_fixes: ["3:00 AM"]. Show the user: "That time doesn't exist. Use 3:00 AM instead?"
Scenario 2: Cron job during a fall-back overlap
A billing job runs at 1:30 AM on November 1, 2026 in New York. Clocks fall back, so 1:30 AM happens twice — once at UTC-4 and again at UTC-5.
The job runs twice (charging customers double), or the system silently picks one offset and processes at the wrong moment.
Call /resolve with ambiguous: "earlier" → get a single deterministic UTC instant. Job runs exactly once.
Scenario 3: AI agent booking a flight
An AI assistant is asked: "Book me a 2:30 AM departure from JFK on March 8." The agent needs to convert this to UTC for the airline API.
The agent converts naively, gets the wrong UTC time, and books a flight that departs at the wrong hour. The user misses their flight.
Agent calls validate_local_datetime tool → sees DST_GAP → tells user "That time doesn't exist, the next available time is 3:00 AM. Should I use that?"
Quick Start
Get your first timezone-safe API call working in under 2 minutes:
- Get a free API key — enter your email on the home page (no credit card required)
- Copy the curl command below — replace
YOUR_API_KEYwith your key - Run it — you'll get back a DST gap detection with suggested fixes
curl -X POST https://chronoshieldapi.com/v1/datetime/validate \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"local_datetime": "2026-03-08T02:30:00",
"time_zone": "America/New_York"
}'
{
"status": "invalid",
"reason_code": "DST_GAP",
"message": "This time does not exist due to DST transition.",
"suggested_fixes": [
{ "strategy": "next_valid_time", "local_datetime": "2026-03-08T03:00:00" },
{ "strategy": "previous_valid_time", "local_datetime": "2026-03-08T01:59:59" }
]
}
Authentication
All /v1/* endpoints require an API key via the x-api-key header:
x-api-key: cg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Getting a key
- Visit the landing page and click "Get Free API Key"
- Enter your email — a key prefixed with
cg_live_is generated instantly - Store it securely — it won't be shown again
Tiers
| Tier | Price | Requests / month |
|---|---|---|
| Free | $0 | 1,000 |
| Pro | $19/month | 100,000 |
| Enterprise Starter | $250/mo (annual) | ~417k/mo (5M/yr included) |
| Enterprise Growth | $800/mo (annual) | ~833k/mo (10M/yr included) |
| Enterprise Strategic | Custom | Contact us |
Enterprise plans include invoice billing, SLA response times, and declining overage rates. Full pricing details →
Starter — best for one team needing annual billing & SLAs. Growth — best for multi-product or high-volume SaaS. Strategic — custom volume, dedicated environments, procurement & legal support.
Unauthorized response
HTTP 401
{ "error": "Unauthorized: invalid or missing API key" }
/v1/datetime/validate
Check whether a local datetime is valid, invalid (DST gap), or ambiguous (DST overlap) in the given timezone.
When to use: Before storing or acting on a user-provided local time. Call this first to detect problems, then decide how to handle them — or use /resolve to handle them automatically.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| local_datetime | string | Yes | ISO 8601 local datetime without offset, e.g. 2026-03-08T02:30:00 |
| time_zone | string | Yes | IANA timezone identifier, e.g. America/New_York |
Response — valid time
{
"status": "valid",
"message": "The provided datetime is valid in the given timezone."
}
Response — DST gap (invalid)
{
"status": "invalid",
"reason_code": "DST_GAP",
"message": "This time does not exist due to DST transition.",
"suggested_fixes": [
{ "strategy": "next_valid_time", "local_datetime": "2026-03-08T03:00:00" },
{ "strategy": "previous_valid_time", "local_datetime": "2026-03-08T01:59:59" }
]
}
Response — DST overlap (ambiguous)
{
"status": "ambiguous",
"reason_code": "DST_OVERLAP",
"message": "This time is ambiguous due to DST transition (fall-back).",
"possible_instants": [
{ "offset": "-04:00", "instant_utc": "2026-11-01T05:30:00.000Z" },
{ "offset": "-05:00", "instant_utc": "2026-11-01T06:30:00.000Z" }
]
}
Response — invalid timezone
{
"status": "invalid",
"reason_code": "INVALID_TIMEZONE",
"message": "Invalid IANA timezone: Fake/Zone"
}
/v1/datetime/resolve
Resolve a local datetime to a single UTC instant, automatically handling DST gaps and overlaps using your specified policy.
When to use: When you need a definitive UTC timestamp from a local time and want deterministic behavior for edge cases.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| local_datetime | string | Yes | ISO 8601 local datetime |
| time_zone | string | Yes | IANA timezone identifier |
| resolution_policy | object | No | Edge-case handling (see below) |
Resolution policies
resolution_policy.ambiguous
When the time occurs twice (DST overlap):
"earlier"(default) — first occurrence"later"— second occurrence"reject"— return 400 error
resolution_policy.invalid
When the time doesn't exist (DST gap):
"next_valid_time"(default) — jump forward"previous_valid_time"— jump backward"reject"— return 400 error
Example request
{
"local_datetime": "2026-11-01T01:30:00",
"time_zone": "America/New_York",
"resolution_policy": {
"ambiguous": "earlier",
"invalid": "next_valid_time"
}
}
Success response
{
"instant_utc": "2026-11-01T05:30:00.000Z",
"offset": "-04:00"
}
| Field | Type | Description |
|---|---|---|
| instant_utc | string | Resolved UTC instant (ISO 8601, Z suffix) |
| offset | string | UTC offset that was applied (e.g. -04:00) |
Rejected response (policy = reject)
HTTP 400
{
"error": "This time is ambiguous due to DST transition and policy is set to reject.",
"code": "DST_OVERLAP"
}
/v1/datetime/convert
Convert a UTC instant to a local datetime in the target timezone. This is always unambiguous — one UTC instant maps to exactly one local time.
When to use: Displaying stored UTC timestamps to users in their local timezone.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
| instant_utc | string | Yes | ISO 8601 UTC datetime (must end with Z) |
| target_time_zone | string | Yes | IANA timezone identifier |
Example
Request
{
"instant_utc": "2026-06-15T15:00:00Z",
"target_time_zone": "Europe/London"
}
Response
{
"local_datetime": "2026-06-15T16:00:00",
"offset": "+01:00",
"time_zone": "Europe/London"
}
/v1/datetime/batch
Process up to 100 validate, resolve, and convert operations in a single request.
When to use: Importing calendar events, migrating scheduling data, or any scenario where you need to check multiple datetimes at once. Partial failures are handled gracefully — each item succeeds or fails independently.
curl -X POST https://chronoshieldapi.com/v1/datetime/batch \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"items": [
{ "operation": "validate", "local_datetime": "2026-03-08T02:30:00", "time_zone": "America/New_York" },
{ "operation": "resolve", "local_datetime": "2026-11-01T01:30:00", "time_zone": "America/New_York", "resolution_policy": { "ambiguous": "earlier" } },
{ "operation": "convert", "instant_utc": "2026-06-15T15:00:00Z", "target_time_zone": "Europe/London" }
]
}'
{
"results": [
{ "index": 0, "operation": "validate", "success": true, "data": { "status": "invalid", "reason_code": "DST_GAP", ... } },
{ "index": 1, "operation": "resolve", "success": true, "data": { "instant_utc": "2026-11-01T05:30:00.000Z", "offset": "-04:00" } },
{ "index": 2, "operation": "convert", "success": true, "data": { "local_datetime": "2026-06-15T16:00:00", "offset": "+01:00" } }
],
"total": 3,
"succeeded": 3,
"failed": 0
}
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
| items | array | Yes | Array of 1–100 operation objects |
| items[].operation | string | Yes | "validate", "resolve", or "convert" |
Each item includes the same fields as its respective individual endpoint. Failed items return success: false with an error object.
/health
Returns service health status. No authentication required.
{ "status": "ok" }
Enums & Constants
status
| Value | Meaning |
|---|---|
| valid | The datetime exists exactly once in the given timezone |
| invalid | The datetime does not exist (DST gap — clocks skipped forward) |
| ambiguous | The datetime exists twice (DST overlap — clocks fell back) |
reason_code
| Value | Meaning |
|---|---|
| DST_GAP | Time falls in a spring-forward gap |
| DST_OVERLAP | Time falls in a fall-back overlap |
| INVALID_TIMEZONE | The timezone is not a valid IANA identifier |
Error Handling
All errors return JSON with an error field and an appropriate HTTP status code.
| Status | Meaning | When it happens |
|---|---|---|
| 400 | Bad Request | Malformed datetime, missing fields, invalid timezone, or rejected by resolution policy |
| 401 | Unauthorized | Missing or invalid API key |
| 429 | Rate Limited | Monthly request quota exceeded |
| 500 | Internal Error | Unexpected server error |
Validation error example
HTTP 400
{
"error": "Validation failed",
"details": [
{
"code": "invalid_string",
"message": "Must be ISO 8601 local datetime (e.g. 2026-03-08T02:30:00)",
"path": ["local_datetime"]
}
]
}
Rate Limits
| Tier | Monthly limit | Effective daily rate | p95 latency |
|---|---|---|---|
| Free | 1,000 | ~33/day | < 50ms |
| Pro | 100,000 | ~3,300/day | < 50ms |
| Enterprise Starter | ~417k (5M/yr) | ~13,700/day | < 50ms |
| Enterprise Growth | ~833k (10M/yr) | ~27,400/day | < 50ms |
| Enterprise Strategic | Custom | Custom | < 50ms |
All endpoints use pure computation with cached timezone lookups — no external I/O in the request path.
Official SDKs
Maintained by the ChronoShield API team. SDK packages will be published to npm and PyPI soon — in the meantime, you can use the API directly via HTTP or copy the SDK source from GitHub.
TypeScript / JavaScript
import { ChronoShieldClient } from "chronoshield";
const client = new ChronoShieldClient({
baseUrl: "https://chronoshieldapi.com",
apiKey: "YOUR_API_KEY",
});
const result = await client.validate({
local_datetime: "2026-03-08T02:30:00",
time_zone: "America/New_York",
});
console.log(result.status); // "invalid"
Python
from chronoshield import ChronoShieldClient
client = ChronoShieldClient(
base_url="https://chronoshieldapi.com",
api_key="YOUR_API_KEY",
)
result = client.validate("2026-03-08T02:30:00", "America/New_York")
print(result.status) # "invalid"
AI Agent / Tool Integration
ChronoShield API exposes tool schemas compatible with function-calling AI agents (OpenAI, Anthropic Claude, LangChain, CrewAI, etc.). Download the schemas from agent-tools.json.
Available tools
validate_local_datetime
Check if a local datetime is valid, invalid (DST gap), or ambiguous (DST overlap)
resolve_datetime
Resolve an ambiguous or invalid local datetime to a UTC instant using the specified policy
convert_datetime
Convert a UTC instant to a local datetime in the target timezone
Example: AI scheduling assistant
- User says: "Schedule a call at 2:30 AM ET on March 8, 2026"
- Agent calls
validate_local_datetime→ getsstatus: "invalid",reason_code: "DST_GAP" - Agent reads
suggested_fixes→ responds: "That time doesn't exist (daylight saving). The next available time is 3:00 AM. Use that?" - User confirms → agent calls
resolve_datetimewithinvalid: "next_valid_time" - Agent stores
2026-03-08T07:00:00Z— no bug, no silent misconversion