Publisher sections ›
Publisher API reference
The core, live in production at livecal.ai/api/v1. Create Sources, push live-state, and read aggregate analytics. New here? Start with the quickstart, then grab a key from the dashboard.
Live. The Source API, the MCP server, the Track Widget, and the WordPress plugin are shipped and callable in production. Push-source facts render as a structured, labeled block with the (tentative) marker; the publisher-declared typed facts_schema (pull lane) is still deferred.
Authentication
Exchange your site key for a short-lived JWT, then send it as a bearer token. $LIVECAL_TOKEN below is a placeholder — request a real per-site key out-of-band and never inline it.
| Endpoint | What it does |
|---|---|
| PUT /api/v1/sources/{external_id}Upsert a Source. Idempotent on your external_id — safe to replay. | Upsert a Source. Idempotent on your external_id — safe to replay. |
| POST /api/v1/sources/batchUpsert up to 100 Sources in one call. Partial-success: each row reports its own result. | Upsert up to 100 Sources in one call. Partial-success: each row reports its own result. |
| POST /api/v1/sources/{id}/statePush a live-state update. Debounced — only material changes reach trackers' calendars. | Push a live-state update. Debounced — only material changes reach trackers' calendars. |
| POST /api/v1/sources/validateDry-run a Source — validates payload shape + time fields. No writes, no trackers touched. | Dry-run a Source — validates payload shape + time fields. No writes, no trackers touched. |
| GET /api/v1/sources/{id}Read a Source's current state, facts, and feed flags. | Read a Source's current state, facts, and feed flags. |
Create a Source — idempotent on your external_id
Each fact carries a confidence of "known" or "provisional". starts_at is required (ISO 8601); ends_at + all_day cover multi-day and all-day events (for all-day, ends_at is the inclusive last day).
Push a live-state update
Send the new live-state line and any changed facts. LiveCal debounces — only material changes reach a tracker's calendar.
Manifests & confidence tiers
A Manifest slug (airshow, flights, earnings, …) selects the facts vocabulary for a Source. Promoting a fact from provisional to known is a material change that updates trackers; because LiveCal debounces, you can write freely as information firms up.
Slug handling. The manifest slug is stored as-sent; it is not yet validated against a catalog — a typo gets a clean 201 and falls back to a generic render. Push-source facts render as a structured, labeled block today; the publisher-declared typed facts_schema in your manifest (pull lane) is still deferred.
The error contract
Every error returns the same envelope. The retryable flag tells you whether to back off and retry (429 / 5xx, honoring Retry-After) or to fix the request and resend (4xx / 422).
Analytics you get
Aggregate and privacy-safe, over two app-scoped REST endpoints — GET /api/v1/apps/{id}/stats and GET /api/v1/apps/{id}/funnel. No PII — never who tracks you, only how many. Any bucket below five trackers is suppressed (k-anonymity).
| Metric | What it covers |
|---|---|
| Widget funnel & conversion | Impressions → Track clicks → completed Tracks, by state (Unauthenticated / Recognized / Tracking). |
| Tracker count, growth & churn | Net trackers over time per Source, plus stop-tracking rate. |
| Provider split | Share of trackers on Google vs. Apple calendars. |
| Propagation latency | Time from your state push to the PATCH landing on tracker calendars (p50 / p95). |
| Tracking-options engagement | Which per-App update toggles trackers keep on vs. mute. |
Ingestion — push-preferred
If you push your updates, we never poll you — your state pushes are the source of truth and propagate the instant they land. We poll only third-party feeds that nobody pushes, and retire that polling as push paths appear. The destination is a publisher-owned push for every Source.
Integration libraries (the Widget embed, the WordPress plugin, the MCP server) live on Libraries →