Flora CodexFlora Codex

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 data object, so a detail response matches the collection envelope. Read response.data instead of response.
  • flower_or_seed is now fruit_or_seed. v1 inherited a Trefle-era quirk: the fruit-trait block was keyed flower_or_seed. v2 renames it to say what it actually holds.
  • rank, status, and duration are 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 fruit color, plus growth_rate, stay UPPERCASE on both versions, so do not lowercase those when matching.
  • Common-name keys are ISO codes. v1 keyed common_names by 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 meta is richer. v1 sent { "total": N }; v2 adds per_page, current_page, and last_page alongside total.

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}/genus
  • GET /genus/{id}/species and GET /genus/{id}/plants
  • GET /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.

Last updated 19 June 2026