API Changelog

← API reference

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.