CANNALIB API · GET ONLY · DOCUMENTED
Read the catalogue by machine. A free key is optional, never required.
Base https://api.cannalib.org. GET, HEAD and OPTIONS only; POST returns 405. There are no write endpoints. The catalogue is public; metrics take a key. Calls without a key get an hourly allowance, reported in X-RateLimit-Remaining; the family tree file needs a website pass or a key.
● 0.8.2-stdlib · 131,603 strains served
● hourly allowance without a key · CORS *
FREE API KEY
Metered access to structured datasets — free to start
Sign up with just an email address and get 5,000 calls a month, 250 an hour, and paging on search results. It is free for personal, hobby, research and open-source use with a short attribution link; no card, no password, and it stays free.
See the free key terms and pricing.
ENDPOINTS
Seven routes. Each one says what it counts.
GET /health
Liveness. Returns status, version, auth mode, db_exists, media_root_exists, trust_proxy.
curl -sS https://api.cannalib.org/health
GET /v1/corpus
Counts precomputed at each publish: served_strains, catalogue_strains, lab_tested_products, facts_evidence_served, lineage_edges_served, awards_served, competition_results, sources and more. If counts_source is not meta.corpus_counts, do not show the numbers.
curl -sS https://api.cannalib.org/v1/corpus
GET /v1/catalogs/strains?q=&limit=
Full-corpus typeahead. q up to 120 characters, limit up to 50. Matches name, normalised name and aliases, then hydrates a slim card.
curl -sS "https://api.cannalib.org/v1/catalogs/strains?q=og%20kush&limit=2"
GET /v1/catalogs/strains/{id}
The full record (schema strain_tree_v1). {id} is the exact normalised name, alias or strain slug, not a search. Every THC, CBD, flowering and height claim with its sources; lab range from three or more flower tests; parents with sources and a family-tree diagram; genetically nearest DNA samples where a strain was tested (evidence.traits.genetic_nearest_samples; each evidence id names its dataset: four published genotyping datasets and Kannapedia); competition results and checked award claims; pictures with credit. 404 if missing; ledgered names redirect or 404.
curl -sS "https://api.cannalib.org/v1/catalogs/strains/blue%20dream"
GET /v1/catalogs/{nutrients|mediums|lights|equipment}
410 Gone since 23 September 2026. CannaLib is plants only. Grow lights, equipment, nutrients and growing media live in DSC-KitLib and DSC-NuteLib, the libraries of Digital Stealth Care. The response names the new home in moved_to. DSC itself reads strain flowering times from this API.
GET /v1/lineage/graph.json
The prebuilt family tree the lineage map draws: 58,203 strains, 119,483 links, layout precomputed. Cached a day, gzip sibling served as-is. Needs a website pass (the lineage page gets one for you) or a key.
curl -sSI https://api.cannalib.org/v1/lineage/graph.json
GET /v1/catalogs/media?kind=
Licensed reference images by kind. Comparative and pathology images are reference material, not cultivar portraits.
GET /media/...
Sandboxed WEBP, PNG and JPEG from the media root. No directory listing.
GET /v1/metrics
Traffic and corpus snapshot. Key required. Used by Home Assistant sensors. The catalogue itself stays public.
RESULT SHAPE
Slim card, then the tree
List (?q=): id, name, name_norm, type, breeder, curated, has_chemistry, thc_range, thc_basis, cbd_range, cbd_basis, top_terpenes, height_cm, height_band, flowering_days, want, matched_via. No branches.
Record ({id}): schema strain_tree_v1, evidence with chemistry and grow spans plus samples, branches.photoperiod and branches.autoflower with combined, subtypes and breeders. Missing science is null or an empty array. Conflicting chemistry keeps its rows; there is no unlabelled average.
LIMITS, STATED
What it will not do
No bulk dump. No write endpoints. No find-by-path filter yet; the explorer has no fake filter box for it. Calls with no key get 60 an hour and 300 a day, ten results per search, no next page (X-RateLimit-Remaining says what is left). A website pass, the kind the explorer and lineage pages give you, raises that to 100 an hour and 300 a day. A free API key raises it further: 5,000 calls a month, 250 an hour, 1,000 a day, ten results per page up to three pages, 1,000 distinct strains a month. The corpus endpoint is edge-cached briefly; the version in X-Cannalib-Version is the truth.
AUTHENTICATION
Send a key, read the headers, handle the errors
AUTHENTICATION
Send your key
Send your key as either header:
X-Cannalib-Key: <your key>
Authorization: Bearer <your key>
Calls without a key are treated as anonymous and get the lowest, unmetered public rate limit.
RESPONSE HEADERS
On every keyed call
- X-Cannalib-Plan — your current plan.
- X-Quota-Limit / X-Quota-Remaining — the monthly allowance and what is left.
- X-Quota-Reset — when the monthly allowance resets (UTC).
- X-Distinct-Remaining — distinct strains still available this period.
- X-Credits-Remaining — purchased or promotional credit balance.
- X-RateLimit-* — per-minute, hourly and daily rate-limit state.
ERRORS
What a rejected call looks like
- 401 invalid_key — key not recognised (the response includes signup_url).
- 401 key_suspended / key_revoked — the key exists but is not active (response includes account_url).
- 429 monthly_limit — the monthly allowance and any credits are used up (resets_at, upgrade_url).
- 429 distinct_limit — the distinct-record cap is reached for this period; records already served still work.
- 429 hourly_limit / daily_limit / too_fast — a rate limit was hit (retry_after_s).
- 403 paging_not_allowed / page_limit — paging is not on your plan, or you are past its page cap.
Every limited or rejected response for a keyed caller includes plan, resets_at where relevant, retry_after_s, and an upgrade_url.
See pricing for plan limits, or the free key terms.
