Flora CodexFlora Codex

Filtering and search

The species list takes four families of query parameter that you can mix freely: filter for exact matches, filter_not to exclude, range for numeric bounds, and order to sort. For everything else there is q, a single full-text search that reaches across names and authors at once.

Everything here applies to https://api.floracodex.com/v2/species. Each parameter narrows or orders the same paginated list, so the pagination rules apply unchanged: the result still comes back 20 to a page, and the links block carries your filters forward across pages.

Exact-match filters

filter[field]=value keeps only records whose field equals the value. The fields you will reach for most:

  • scientific_name is matched exactly and is case-sensitive (Quercus robur).
  • common_name matches a common-name token (Common Oak).
  • year is the publication year of the name (1753).
  • genus and family match the genus or family name (Quercus, Fagaceae).
  • genus_id matches a genus by its identifier.
  • author matches the author citation, often a single initial (L. for Linnaeus).

The supported set is wider than that. It also covers the name variants family_name, genus_name, and name, and a set of trait fields: flower_color, foliage_color, fruit_color, growth_form, growth_habit, growth_rate, nitrogen_fixation, toxicity, rank, and status. Trait coverage varies from one species to the next, so a trait filter narrows to the records that carry that trait. The API reference lists every parameter the species endpoint accepts.

Pass more than one value for a field as a comma-separated list, and it reads as "any of these." So filter[year]=1753,1758 returns names published in either year. The rule is OR within a field, AND across fields: the request below wants oaks named by Linnaeus, not oaks plus everything else Linnaeus named.

https://api.floracodex.com/v2/species?filter[genus]=Quercus&filter[author]=L.

Excluding with filter_not

filter_not[field]=value is the inverse: it drops records that match. It takes the same fields and the same comma-separated lists as filter.

It also understands the absent value. filter_not[year]=null excludes records that have no year set, which is the way to ask for "only records where this field is populated." Combine the two ideas to exclude both the unset and a few specific values at once:

https://api.floracodex.com/v2/species?filter_not[year]=null,1753

Numeric ranges

range[field]=min,max filters a numeric field to a span. Either side may be left empty for an open-ended bound, which is how you express "or later" and "or earlier":

  • range[year]=1700,1800 is 1700 through 1800.
  • range[year]=1700, is 1700 or later.
  • range[year]=,1800 is 1800 or earlier.

Sorting

order[field]=asc|desc sorts the result. Apply more than one and they take effect in the order you write them, so the first is the primary sort and the rest break ties. The common sort keys are scientific_name, common_name, family_name, and year, and most of the filterable fields above can be sorted on as well.

https://api.floracodex.com/v2/species?order[family_name]=asc&order[year]=desc

An internal identifier is always appended as the final tiebreaker. Two records that are otherwise equal still come back in a fixed order, so a record never drifts between pages as you page through a result with ties.

q is the search you reach for when you do not know which field the match lives in. The text is broken into terms, and each term is matched across several fields at once, weighted so the most telling matches rise to the top:

  • common names carry the most weight
  • scientific names come next
  • author citations, genus names, and family names share a lower weight beneath those two

A search for oak therefore surfaces plants known as oaks ahead of a genus that merely contains the letters.

The final term in the query is matched as a prefix, so a partial word still finds something. This is what makes q work as you type: quer matches Quercus without a separate autocomplete endpoint.

curl "https://api.floracodex.com/v2/species?q=oak&order[year]=desc" \
  -H "Authorization: ApiKey YOUR_KEY"
const params = new URLSearchParams({ q: "oak", "order[year]": "desc" });
const res = await fetch(`https://api.floracodex.com/v2/species?${params}`, {
  headers: { Authorization: "ApiKey YOUR_KEY" },
});
const data = await res.json();
import requests

res = requests.get(
    "https://api.floracodex.com/v2/species",
    params={"q": "oak", "order[year]": "desc"},
    headers={"Authorization": "ApiKey YOUR_KEY"},
)
data = res.json()

You can pair q with filters to scope a search. q=robur&filter[genus]=Quercus searches only within the genus.

Unknown parameters and unsupported fields are rejected, not ignored. A stray query parameter, a misspelled filter field like filter[famly], or a sort on a field that is not sortable comes back as a 400 with a validation/failed problem whose fieldViolations name the parameter at fault, so a typo surfaces right away instead of quietly returning results that were never narrowed. The Errors guide covers the envelope.

Last updated 19 June 2026