Migrating from v1
The v1 surface is the original Trefle-compatible API. It still works, but it is frozen and deprecated, with a sunset on 31 January 2027. v2 is its successor. The data is the same; the presentation is not. A few response shapes are corrected, field names and casing are tidied, and errors follow a modern format.
Most of a v1 client moves over by changing the base URL. Authentication is the change that breaks a request outright: v2 rejects the old credential. There are also a handful of response-shape changes a v1 parser needs to handle. This guide walks them in the order they are likely to affect you.
Search, filtering, and pagination behavior is shared between v1 and v2, so migrating does not change which records you get back or in what order. What changes is the presentation: a record's shape in a couple of places, some field names and casing, and the error format.
Point your client at v2
The base URL is https://api.floracodex.com/v2. Swap it in wherever your client targets v1:
# Before (v1)
curl https://api.floracodex.com/v1/species
# After (v2): the same path, new base URL
curl https://api.floracodex.com/v2/species
The older /api/v1 base path was a Trefle convention. v2 is served only at
/v2; there is no /api/v2.
Update authentication
This is the breaking change. Over the years v1 grew several ways to pass a
credential: the x-api-key header, the x-key header, and the key or token
query parameter. v2 accepts none of them. It reads the key from the
Authorization header with the ApiKey scheme:
# Before (v1): any of these worked
curl "https://api.floracodex.com/v1/species?token=YOUR_KEY"
curl https://api.floracodex.com/v1/species -H "x-api-key: YOUR_KEY"
# After (v2): Authorization header only
curl https://api.floracodex.com/v2/species -H "Authorization: ApiKey YOUR_KEY"
A request that authenticated on v1 by query parameter or x-api-key header will
fail on v2 with a 401. Move the key into the Authorization header before you
switch the base URL.
If you authenticate as a member rather than a project (with OAuth or a personal
access token), send Authorization: Bearer YOUR_TOKEN instead.
Handle the new error format
v1 returns Trefle's error shape, a status code and a message:
{ "statusCode": 404, "message": "Not Found" }
v2 returns RFC 9457 problem+json, with a stable, machine-readable code to
branch on:
{
"type": "https://docs.floracodex.com/problems/codex-not-found",
"title": "Resource not found",
"status": 404,
"code": "codex/notFound",
"instance": "urn:floracodex:request:01J9Z3F6Q2K8M4T7V0XB5N1WCE"
}
If your v1 client matched on statusCode or on the message text, switch it to
the code field, which is specific and stable. The Errors guide covers the
envelope in full.
What changed in the response shape
The records carry the same information. A handful of presentation details were corrected:
- Detail responses are wrapped. v1 returned a single record at the top
level; v2 wraps it in a
dataobject, so a detail response matches the collection envelope. Readresponse.datainstead ofresponse. flower_or_seedis nowfruit_or_seed. v1 inherited a Trefle-era quirk: the fruit-trait block was keyedflower_or_seed. v2 renames it to say what it actually holds.rank,status, anddurationare now lowercase. They came back UPPERCASE on v1 (SPECIES,ACCEPTED); on v2 they are lowercase (species,accepted). Trait value tokens did not change: flower, foliage, and fruitcolor, plusgrowth_rate, stay UPPERCASE on both versions, so do not lowercase those when matching.- Common-name keys are ISO codes. v1 keyed
common_namesby full language name (ENGLISH); v2 uses the ISO 639 code (en). - Pages hold 20 records, not 10. If you page by counting records, recompute against the new size.
- Pagination
metais richer. v1 sent{ "total": N }; v2 addsper_page,current_page, andlast_pagealongsidetotal.
You can compare the two contracts field by field in the API reference: v1 and v2.
What's new in v2
v2 adds enumeration routes v1 never had:
GET /families/{id}/genusGET /genus/{id}/speciesandGET /genus/{id}/plantsGET /plants/{id}/species
Those return 404 on v1. Everything v1 served is still here, at the same paths.
Timeline
v1 is Deprecated. Its responses carry Deprecation and
Sunset headers, and it stops serving on 31 January 2027. There is no
obligation to move before then, but new integrations should start on v2.