Changelog
Every public-facing change to the Park Graph API, agent surfaces, dashboard, billing, security perimeter, and developer docs since the v1 launch in October 2025. It includes every release of the parkgraph-mcp package. Newest first. Breaking changes are marked with a red badge — there is no fine print and no quiet deprecations.
OpenAPI spec v1.4.0 · Page generated June 2026. Machine-readable JSON: /llms-full.txt.
Stability contract
Park Graph follows a strict additive-only policy inside a major version. Anything that would break a v1 client lands under /api/v2/... with at least six months of overlap and a deprecation banner inside the v1 response body. We never change response shapes silently. If you depend on a field that does not appear in the OpenAPI spec, email developers@parkgraph.com and we will either promote it or warn you before it goes away.
Every breaking change, in the API or in parkgraph-mcp, gets a red badge here and at least 30 days of notice before it takes effect; the entry shows when it was announced and the date it takes effect.
Webhook contracts evolve on the same cadence: the v2 webhook envelope (HMAC-SHA256, deterministic event ids) replaced v1 in January 2026, and v1 endpoints continue to be delivered to until 2026-06-01. Operators on v1 webhooks were emailed individually and the migration is a single signature-verification helper swap.
Releases
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published: 2 webhook events added.
Webhook events: added alert.triggered, daily_stats.created.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. The public API, agent tools, webhook events and developer pages are unchanged.
OpenAPI spec v1.4.0, unchanged.
Release published. From this release on, each publish adds an entry listing the public surfaces it changed.
This release serves OpenAPI spec v1.4.0 with 7 API operations, 6 MCP tools, 6 Gemini functions, 4 Grok tools, 13 webhook events and 25 developer pages.
- October 15, 2026Agent
@parkgraph/agent-sdk 1.4.0 and parkgraph 1.3.0: a typed SDK, a CLI, and pk_test_ keys for the sandbox.
`@parkgraph/agent-sdk` 1.4.0 is the typed TypeScript client: `ParkGraphClient` with `searchLots`, `createSession`, `getSession`, `endSession` and `health()`, and `ParkGraphError` with the HTTP `status`. Its types are generated from the OpenAPI spec. `apiKey` is optional, because lot search works without a key. `parkgraph` 1.3.0 is the CLI (`parkgraph search`, `book`, `status` and `end`); the SDK is bundled inside, so it has no dependencies. Both versions are staged on npm and published only after the owner approves them.
Test keys (`pk_test_…`) can now be created next to live keys on the dashboard API keys page, or with `"mode": "test"` on POST /api/v1/api-keys. A test key uses the same URLs but sees only the three sandbox lots listed on /developers/sandbox, and its sessions are paid in Stripe test mode: the sandbox-only `test_card` field on POST /api/v1/sessions picks one of the listed test cards. Endpoints without a sandbox answer a test key with 403 `TEST_KEY_NOT_SUPPORTED`.
The OpenAPI spec now documents GET /health. Search results carry `lat` and `lng` next to `latitude` and `longitude`, `availability.occupancy_pct` is a number, and `pricing.rate_unit` is `hour`, `day` or `flat` as documented.
parkgraph-mcp 0.1.0: run the hosted MCP server from a local command, plus an overview resource, a prompt and per-key limits.
Clients that only launch local (stdio) servers can now run `npx -y parkgraph-mcp`, or install it with `npm install -g parkgraph-mcp`. The package is a thin proxy to https://parkgraph.com/api/mcp, so it always offers the same six tools as the hosted server. Set `PARKGRAPH_API_KEY` and it is sent as `Authorization: Bearer`; search, lot details, quotes and holds work without one. `parkgraph-mcp serve --port 5050` runs it as a Streamable HTTP server with bearer-token auth and optional mTLS for teams that host their own copy. Versions are staged on npm and published only after the owner approves them.
The hosted server now advertises the resource `parkgraph://docs/overview` (a Markdown overview of the API, authentication and coverage) through resources/list and resources/read, and one prompt, `find_and_book_parking`, through prompts/list and prompts/get.
Each API key (or each IP address, without a key) gets 60 tool calls a minute and 60 reserve calls a minute. Over the budget the server answers HTTP 429 with a Retry-After header; parkgraph-mcp waits and retries. GET /api/v1/lots/search and the search_lots tool now return a short top-level `summary` line describing the results.
Six more webhook events: session, reservation, pricing-rule, capture and refund lifecycle.
Endpoints can now subscribe to `session.started`, `reservation.created`, `reservation.cancelled`, `pricing.rule_triggered`, `payment.captured` and `payment.refunded`, in the dashboard or with `POST /api/v1/webhooks`. They go through the same queue as the first seven events: signed with HMAC-SHA256, retried on the documented schedule, listed in the delivery log, and resendable for 7 days.
`pricing.rule_triggered` is read from the session's final price, so peak-hour, weekend, occupancy and any later pricing rule all send it. `payment.refunded` is sent when a refund settles in Stripe, once per settled refund, with `amount_refunded` and `total_refunded`; `reservation.cancelled` carries `reason` (`released` or `expired`).
`pricing.rule_triggered` also carries `rule`, the rule that set the price (`event`, `surge_today`, `busy_lot`, `peak`, `weekend` or `stacked`), and is sent for a flat event price too, with `multiplier` 1.
Refund a session from the API: POST /api/v1/sessions/{id}/refund, in full or in part.
Uses the same refund path as the dashboard's Refund button: settled in Stripe, Park Graph's fee returned in proportion, never more than was charged. Needs a key with the `sessions:write` scope; another owner's session answers 404.
Omit `amount_cents` for a full refund; repeating a finished one answers 409 `ALREADY_REFUNDED`. A partial refund needs an `Idempotency-Key` header, and repeating it with the same key returns the same refund (`replayed: true`) or finishes one that stopped part way.
X-RateLimit headers on API responses, and a daily quota of 10,000 requests per API key.
Responses now carry `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (Unix seconds) for whichever limit is closest to running out. Each API key may make 10,000 requests a day (Enterprise accounts can be given more); over that, the API answers 429 `RATE_LIMITED` with `Retry-After` until midnight UTC. Per-minute limits are unchanged.
A request no other limit counts (a missing or refused key, the OpenAPI spec) is counted in its IP address's public allowance of 100 requests a minute and carries that count, so every `/api/v1` response has the three headers.
Hosted MCP server at https://parkgraph.com/api/mcp with six tools; nothing to install.
Point any MCP client at the URL: `{ "mcpServers": { "parkgraph": { "url": "https://parkgraph.com/api/mcp" } } }`. It speaks Streamable HTTP (JSON-RPC 2.0), and /mcp is an alias. Tools: search_lots, get_lot, quote, reserve, get_session and extend_session. Each runs on the public API's own rules and limits, and each returns JSON.
Lots on the Starter plan answer reserve with status `pay_at_qr_page` and the lot's pay link, so the assistant sends the driver there. An API key (Bearer header in the client config) adds live availability to search and unlocks the session tools.
The old instructions to install a local MCP package are gone: that package was never published to npm, so they never worked. GET /api/v1/lots/{lotId} now returns `latitude` and `longitude`, and the OpenAPI spec is also served at /api/v1/openapi.json.
occupancy.changed now also fires when a lot's total spaces or alert level change.
Until now, occupancy was only re-checked when a car arrived or left. If you added spaces to a lot reported as full, or raised its capacity alert level, no `below` event was sent until the next car moved, so a gate or sign driven by the webhook kept showing FULL. Changing a lot's total spaces or alert level now re-checks it right away and sends one `occupancy.changed` when the lot crosses to the other side, from the dashboard or any other path. Changes that leave it on the same side send nothing.
Resend a webhook event your server missed, from the dashboard or the API.
An event that failed every attempt, or was cancelled because its endpoint was paused, can now be resent for 7 days. Press Resend in the endpoint's delivery log, or call `POST /api/v1/webhooks/deliveries/{event_id}/resend`. The resend carries the same body and `X-Park-Graph-Delivery` id as the original, so receivers that skip ids they have already handled stay correct, and it appears in the delivery log as a new attempt.
`GET /api/v1/webhooks/deliveries?webhook_id=...` lists an endpoint's attempts with each event's status and whether it can be resent, plus `unsent_events`: events cancelled before their first attempt, which have no attempt to show. Each list pages with its own cursor (`deliveries_next_cursor`, `unsent_events_next_cursor`; pass one back as `cursor`), so every event from a long outage can be found, and the dashboard log can show older entries the same way. Both endpoints need the `webhooks:manage` scope and a Pro or Enterprise plan.
Webhook endpoints now receive real events, with retries and a per-attempt delivery log.
Until now, Pro and Enterprise endpoints could only receive the dashboard's test event. All seven documented events are now sent when they happen: session.created, session.ended, session.extended, payment.completed, payment.failed, lot.updated and occupancy.changed. Payloads are signed with the same `X-Park-Graph-Signature` header as the test event.
Events are queued and sent separately from the request that caused them. A failed delivery is retried up to 6 times over about 21 hours, and every attempt appears on the dashboard webhooks page. If 10 events in a row fail every attempt, the endpoint is paused; resume it from the dashboard or with `PATCH /api/v1/webhooks`.
GET /api/v1/lots.geojson now accepts an optional ?bbox= viewport filter.
Map renderers can fetch only the lots inside the current viewport instead of the full dataset on every pan or zoom. Pass `?bbox=west,south,east,north` (four floats in GeoJSON lon/lat axis order) and the FeatureCollection is filtered to that box.
Latitudes must satisfy south ≤ north; a box that crosses the antimeridian (west > east) is supported. Omitting `bbox` keeps the existing behavior of returning all listed, active lots, so the change is fully backwards compatible.
Developer / AI / GEO documentation cluster ships (T6).
Every page under /developers/* now meets the 2,000-word documentation bar with a shared security-model, rate-limits, error-codes, and AI-agent-use-cases appendix.
Three new pages launched: /developers/openai-actions (full ChatGPT Actions tutorial), /developers/geojson (GeoJSON spec for /api/v1/lots.geojson and /api/v1/projection-sites.geojson), and /developers/changelog (this page).
Six GEO landing pages launched under /ai/* covering AI-agent parking booking, ChatGPT parking booking, MCP server for parking, parking data for AI agents, parking availability for AI search, and the best-of comparison page.
New machine-readable surfaces: /openapi.json, /.well-known/ai-plugin.json, /llms.txt, and /llms-full.txt — all served from a route handler so they stay in lockstep with shipped capabilities.
Realtime voice models (gpt-realtime, Gemini Live) supported in /api/agents/openai/actions.
The agent dispatcher now accepts streamed tool-call deltas from realtime models. The contract is unchanged — the same action / parameters envelope works whether the upstream model is text or voice.
/developers/chatgpt and /developers/gemini both gained voice-only worked examples.
POST /api/v1/sessions/extend returns the new expected_end and an extended_count counter.
Drivers can extend an active session up to 24 hours in 30-minute increments. The previous response returned only a 200; we now return the full session shape so clients can update local state without a follow-up GET.
Existing clients see an additive change only — the response is a strict superset of v1.2.x.
GET /api/v1/lots.geojson ships a public GeoJSON feed of all listed, active lots.
Fetch every listed, active lot as an RFC 7946 FeatureCollection — ideal for map-based discovery in Mapbox GL, Leaflet, QGIS, or geopandas without first computing a center and radius.
Each Feature carries the lot id, name, slug, address, total_spaces, lot_type, feature tags, and a url. Responses are cached with `Cache-Control: public, max-age=300`.
API-key responses now include a `last_used_at` timestamp.
Operators asked for a way to retire dormant keys without guessing. /dashboard/api-keys and the corresponding management API both surface the timestamp of the last successful authentication.
Existing keys backfill from the audit log when first inspected.
Local MCP server v1.2.0 built with four tools and a docs resource (never published; see 1.5.3).
A local (stdio) MCP server was built with four tools to search lots and to start, check and end a parking session, each a thin wrapper around the equivalent /api/v1 REST endpoint.
It also advertises one resource, parkgraph://docs/overview, a Markdown summary of the platform's API, authentication, and coverage for Claude Desktop and other MCP clients.
It was never published to npm. The hosted server at https://parkgraph.com/api/mcp replaced it on 2026-10-12.
Enterprise tier transaction take dropped from 5% to 3.3%.
Operators above $50k in monthly gross are charged a lower platform fee. Existing Enterprise contracts re-baseline automatically on the next billing cycle.
The change is reflected in /pricing and the Offer entries inside the SoftwareApplication JSON-LD on every page.
Real-time AI-agent attribution shows on the lot revenue chart.
Every paid session now carries an attribution tuple {agent_platform, agent_name} when the booking arrived through an agent. The dashboard renders an overlay band so operators can see what fraction of revenue is coming from agentic distribution.
Attribution data is also surfaced via /api/v2/intelligence/agent-demand for analysis at the city level.
Announced December 2025 · takes effect June 1, 2026 · 152+ days' notice
Webhooks v2: HMAC-SHA256 signing and deterministic event id.
Webhook payloads are signed with the operator's webhook secret using HMAC-SHA256. The signature is delivered in the `X-Park-Graph-Signature` header as `sha256=<hex>`; recompute the HMAC over the raw request body and compare before acting on it.
Every event has a stable `id` of the form `evt_…` that is identical across retries. Idempotency is now the consumer's responsibility (see /developers/webhooks).
BREAKING: the legacy v1 webhook signature header (`X-Webhook-Sig`) is removed. Operators on v1 webhooks were emailed in December 2025; v1 endpoints will continue to be delivered to until 2026-06-01.
POST /api/v1/reserve places an idempotent hold for pre-booked spots.
Reservation-style flows (event venue parking, hospital procedure visits) can describe what they need in a single `intent` string; Park Graph parses it, resolves a matching lot, and atomically places a short-lived hold. Every call must carry an `Idempotency-Key` header so retries are safe. Park Graph charges only when the driver activates the session on arrival; unredeemed holds release back to the pool when the hold's TTL expires.
Public OpenAPI spec exposed at /api/agents/openai/openapi.yaml.
The same spec backs ChatGPT Actions, the Park Graph SDKs, and the public API reference. Versioning follows the API itself, so spec_version == api_version.
A JSON copy is now served at /openapi.json for tooling that does not parse YAML.
Public v1 API generally available.
/api/v1/lots/search, /api/v1/sessions, /api/v1/sessions/{id}, /api/v1/sessions/end, and /api/v1/health are now generally available with a documented stability contract.
Breaking changes within v1 will be additive only; truly breaking changes will live under /api/v2 with at least six months of overlap.
Subscribe
Three ways to track changes:
- • JSON feed: /llms-full.txt includes the full changelog at the bottom and is the easiest source for an agent or automated pipeline.
- • Email: any operator with an active API key gets release notes via transactional email. Manage subscriptions at /dashboard/notifications.
- • Status: /trust/status publishes uptime, incident history, and scheduled maintenance windows alongside the version that landed in production.
Rate limits
Limits are enforced per API key (or per IP for unauthenticated reads) using a rolling token bucket. Every response carries X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers; 429 responses additionally carry Retry-After. Bursts above the per-minute budget should be backed off with jitter — the official SDK does this automatically.
| Scope | Budget | Window |
|---|---|---|
| Public read endpoints (search, lot detail, health) | 120 requests | per IP per minute |
| Authenticated read endpoints (sessions, payouts, webhooks) | 600 requests | per API key per minute |
| Authenticated write endpoints (create / end / extend session, refunds) | 120 requests | per API key per minute |
| Sandbox endpoints (`pk_test_…` keys) | 30 requests | per key per minute |
Need a higher ceiling? Email developers@parkgraph.com with your projected throughput and we will lift the burst budget on a per-key basis.
Error codes
Every error response uses the same envelope: { "error": { "code": "…", "message": "…", "request_id": "req_…" } }. The HTTP status indicates the broad class; the code field disambiguates within a class. Surface the request_id to your support team — we can look up the full server-side trace by id alone.
| Code | HTTP status | Meaning |
|---|---|---|
| BAD_REQUEST | 400 | Required parameter missing or out of range. Response body lists the offending field. |
| UNAUTHORIZED | 401 | Missing or malformed Authorization header. Send `Authorization: Bearer pk_live_…`. |
| FORBIDDEN | 403 | API key is valid but the plan does not include this scope (e.g. agent or intelligence endpoints on Starter). |
| NOT_FOUND | 404 | Lot, session, or webhook id does not exist or has been deleted. |
| CONFLICT | 409 | Idempotent retry of a non-terminal session, or attempt to end an already-completed session. |
| RATE_LIMITED | 429 | Per-key burst budget exceeded. Inspect `Retry-After` and back off. |
| PAYLOAD_TOO_LARGE | 413 | Webhook delivery body or batch upload exceeds 1 MB. |
| INTERNAL | 500 | Unexpected server error. Park Graph automatically opens an incident and retries idempotent writes. |
| BAD_GATEWAY | 502 | Upstream payment processor returned an error. Safe to retry with the same idempotency key. |
Architecture
Every Park Graph request — whether it arrives from the API and developer surface, the dashboard, the QR-driven mobile checkout, or an agent — runs through the same Next.js Edge front door, hits the same Postgres-backed core, and shares the same audit log and webhook fan-out. There is no divergent code path between "agent traffic" and "human traffic": anything an agent can do, a human can do, and vice versa.
Sandbox & getting help
Every operator gets a sandbox key prefixed with pk_test_. Sandbox traffic uses Stripe test mode, synthetic lots, and never charges a real card. Spin one up at /developers/sandbox, then point your client at https://parkgraph.com/api/v1 exactly as you would in production.
For integration help, reach the developer team at developers@parkgraph.com or open an issue on the public GitHub org. Status and incident history live at /developers/changelog; subscribe to the JSON feed for machine-readable updates.