Documentation
Migration guides
Moving between API versions without breaking.
There is one version, so there is nothing to migrate between
The FlowFinds API carries no version identifier — no URL prefix, no version header — and has never carried one. There has been no second version, so there is no version-to-version migration to describe, and this page does not invent one. See Versioning and deprecation for what that means in practice.
When a migration is ever required, a guide appears here on the day the change is announced — not on the day it takes effect. The notice guarantee is that a breaking change ships with its migration guide, not after it. If we cannot describe the migration, the change is not ready.
What has changed inside the one version
The absence of versions does not mean the absence of change. Breaking changes have shipped within this single version, and each is recorded and dated on the changelog. If your client predates one of them, that entry is your migration, and there are two worth checking against your code today.
Handling 409 from POST /api/account
A client written before 29 August 2026 assumed that posting an email address always bound it. It does not: an address already belonging to a verified account is refused with 409 and a sign-in link is sent instead. A client that treats 409 as a fatal error strands the person one click from their own account.
# before
r = s.post(f"{BASE}/api/account", json={"email": email})
r.raise_for_status() # 409 raises, and the journey stops here
# after
r = s.post(f"{BASE}/api/account", json={"email": email})
if r.status_code == 409:
body = r.json() # reason: "account_required", verified: true
show("That address already has an account — open the sign-in link we just sent.",
mail_reached_the_provider=body["email_sent"])
elif r.status_code == 400:
show("That is not an email address.")
else:
r.raise_for_status()Dropping the non-JSON error fallback
Before 30 August 2026 an uncaught server exception was answered with an HTML error page, so careful clients parsed defensively. Every route is now wrapped by one dispatch guard and answers {"status":"error","reason":"internal"} as JSON with a 500. The HTML branch on /api/ paths can go — and if it ever fires again, something between you and the origin answered, not the origin.
Note the one genuine exception: a path that matches no route at all still answers 404 as text/plain, not JSON. Check Content-Type before parsing.
The shape every migration guide here will follow
So you know what to expect, and can plan against it before one exists. Each guide states, in this order:
- What changed and why — including, honestly, when the reason is that the old design was wrong.
- Who is affected, expressed as something you can test for in your own code rather than as a version number you may not have recorded.
- The dates. Announced, and the last day the old behaviour is served. Both absolute, never relative.
- A field-by-field mapping — old name, new name, type change, and what happens to a value with no equivalent.
- Before-and-after code for the request and the response handling, in curl and in one language.
- How to verify you have migrated — a call you can make whose answer proves it, rather than an assurance that you probably have.
- What happens if you do not. The exact status and reason code your client will receive after the deadline.
Keeping ahead of the next one
- Subscribe your team to the changelog; entries marked Breaking are the ones that will ever appear here.
- Diff
GET /api/reasonsin CI. A refusal code disappearing is the earliest mechanical signal that something you handle is being retired. - Make sure the email address on your account is one a person reads. Breaking-change notice goes to the address on every account that has called the affected endpoint.
- Follow the client rules in Versioning. Most migrations are only migrations for clients that validated responses as closed schemas.
If you are planning an integration and want to know whether something you depend on is likely to move, ask before you build it: [email protected].
Next: Versioning and deprecation · Changelog · Quickstart