Every public-API change to /api/v1/*. Subscribe via the GitHub commit history or the RSS feed (coming soon). Breaking changes will only ship under a new /api/v2 with at least 6 months notice.
2026-05-06
Wave 3: changelog page, status endpoint, signed-with-timestamp webhooks
Added
- •Public changelog at /docs/api/changelog (this page).
- •GET /api/v1/status — unauthenticated health endpoint reporting database + Redis connectivity. Returns 200 when fully up, 503 when down. Suitable for uptime monitors.
- •Breadbox-Signature header on all webhook deliveries — Stripe-style format `t=<unix>,v1=<hmac>` with replay-protection guidance in docs.
- •Breadbox-Event and Breadbox-Event-Id headers on every webhook for easier event handling and idempotent deduplication.
Changed
- •Webhook User-Agent updated to `Breadbox-Webhooks/1.1` (was MSP-CRM-Webhooks/1.0).
Deprecated
- •X-MSP-Signature and X-MSP-Timestamp webhook headers — still sent for backwards compatibility but will be removed in a future release. Migrate to Breadbox-Signature.
2026-05-06
Wave 2: idempotency, OpenAPI, bulk endpoints, sort/filter
Added
- •Idempotency-Key header support on all POST/PATCH/DELETE endpoints. Same key + same body returns the cached response (24-hour TTL); same key + different body returns 422 idempotency_conflict. Replays carry X-Idempotent-Replay: true.
- •GET /api/v1/openapi.json — full OpenAPI 3.1 specification covering every endpoint, schema, and security scheme. Pipe into openapi-generator, openapi-typescript, Postman, etc.
- •POST /api/v1/accounts/bulk — upsert up to 500 accounts per request. Idempotent on optional externalId field.
- •POST /api/v1/contacts/bulk — upsert up to 500 contacts per request. Idempotent on email (case-insensitive).
- •POST /api/v1/deals/bulk — create up to 500 deals per request.
- •?updatedAfter= query parameter on all list endpoints for incremental sync.
- •?sort=field:dir,field2:dir2 query parameter on all list endpoints. Allowlisted per endpoint; invalid fields silently ignored.
- •?force=true query parameter on DELETE /accounts/{id} for hard delete (default remains soft delete via lifecycle = CHURNED).
- •New filter params: deals (?ownerId, ?type), touchpoints (?type), contacts (?email).
- •POST endpoints now return HTTP 201 Created where they create resources (was 200).
2026-05-06
Wave 1: trust fixes — docs match code, missing endpoints built
Added
- •POST/GET/PATCH/DELETE /api/v1/devices — full CRUD for device inventory. Fires device.created, device.updated, device.offline, device.end_of_life webhooks.
- •POST /api/v1/devices/bulk — bulk upsert from RMM, idempotent on rmmAgentId, max 500/request.
- •GET/POST/PATCH/DELETE /api/v1/tasks — task management endpoints. Auto-stamps completedAt on status=DONE.
- •GET/POST /api/v1/notes — notes on Account, Deal, Contract, Lead.
- •tasks:read, tasks:write, notes:read, notes:write scopes.
- •Webhook events that now actually fire: contact.created, contact.updated, touchpoint.created. Previously documented but never emitted.
- •Per-endpoint scope listed inline with each endpoint in /docs/api.
- •Per-endpoint request/response examples in /docs/api.
Changed
- •Response envelope now has top-level `success: true|false` boolean. Matches what the docs always claimed; previously the field didn't exist.
- •Error responses now include `docsUrl` pointing to the relevant docs anchor. Validation errors include `details` carrying Zod issues.
- •POST endpoints return HTTP 201 for resource creation (was 200).
- •Test-mode keys (msp_test_) still work but the docs now explicitly note they don't fire outbound webhooks.
Fixed
- •Vapor webhook events removed from docs: health_score.changed, health_score.alert, reconciliation.variance_detected, notification.created. None had source code that emitted them.
- •Endpoint list in docs was referencing /devices, /devices/bulk, /reconciliation — those didn't exist. Devices now exist; reconciliation removed from docs.
Deprecated
- •reconciliation:read and reconciliation:write scopes — the underlying Reconciliation model was removed in PSA cleanup. Scopes return 403 if requested on key creation.
- •onboarding:read scope — model removed, now dead.
- •contracts:read scope — Contract model exists but no /api/v1/contracts endpoint. Scope is ineffective.
Hit a breaking change you weren't expecting?
Email api@breadboxmsp.com with the request ID from a failing call. We commit to a 6-month deprecation window for any public-API breaking change — if something silently broke, that's a regression and we want to know.