Skip to content

Versioning & breaking changes

Mildport is at engine v0.2.x, and evaluators are right to ask what that means for the REST API and webhook contract. The honest answer: the product is young, but the contract discipline is not an aspiration — it is how the system is built, and our own CRM depends on it in production.

  • The REST API is URL-versioned: every route lives under /import/v1/…. v1 routes are never broken in place. If we ever need an incompatible transport, it ships as /import/v2 alongside v1 — migration on your schedule, not ours.
  • Published packages follow semver. Pre-1.0: patch releases are always safe to take; breaking changes only land in minor bumps and are flagged BREAKING in the changelog.
  • Changes are additive by default — new optional fields and new routes may appear. Ignore fields and event types you don’t recognize, and additive releases will never affect you.
  • Deprecation before removal. A deprecated route, field, or attribute keeps working for at least one further minor release — and never less than 30 days after the deprecation is published in the changelog and the OpenAPI spec.
Surface The contract
REST API Routes under /import/v1/…, the { status: 'ok', payload } / { status: 'error', code, issues? } envelope, request and response shapes.
Wire schemas @capitality-io/mildport-contract — published Zod schemas that mirror the wire 1:1, plus an OpenAPI 3.1 spec shipped with the distribution.
Apply webhooks The x-import-* headers, the versioned signature scheme (v1= in x-import-signature), and the documented payload fields. See Apply webhooks.
Widget <mildport-import> documented attributes, emitted DOM events, and the --mildport-* theme tokens.
Licensing The offline signed-key format — existing license keys keep verifying across upgrades.

Not covered: the widget’s internal DOM structure, undocumented endpoints, and features marked pilot or experimental in these docs — those may change while they’re being validated with design partners, and they’re labeled so you can tell.

Breaking — only in a flagged release, per the rules above:

  • Removing or renaming a route, response field, webhook payload field, DOM event, or widget attribute.
  • Changing a field’s type or meaning, or the response envelope.
  • Tightening validation so a previously accepted request fails.
  • Changing the webhook signature scheme — that’s why the scheme itself is tagged (v1=); a new scheme would appear as v2= alongside it.

Not breaking — may happen in any release:

  • New routes, new optional request fields, new response or webhook payload fields.
  • New event types and new error codes. Write your handlers to ignore what they don’t recognize.
  • Bug fixes that make behavior match what these docs and the OpenAPI spec already said.

Releases are versioned with changesets: every published package ships a CHANGELOG.md, and breaking entries are flagged BREAKING. Deprecations are also marked in the OpenAPI spec. Pilot customers additionally get breaking changes called out directly in release notes — at this stage you are talking to the people who wrote the change, not a support tier.

A practical setup for hosts:

  1. Pin the widget packages by exact version and upgrade deliberately — the custom element and wrappers are semver’d for exactly this.
  2. Validate deliveries with the contract package. If your integration tests parse webhook payloads with @capitality-io/mildport-contract and still pass after bumping it, the release is compatible for you — the contract is machine-checkable, not prose.

Capitality runs Mildport in production as tenant #1: our own CRM consumes the same /import/v1 routes, the same published packages, and the same webhook contract any host gets — there is no privileged internal path. A breaking change that skipped this policy would break our production first, before it ever reached yours.