Developer Documentation

DevCannabis Docs

How DevCannabis works, how to use public API surfaces, and how to request approved contributor/source access.

Overview

DevCannabis is a transparent platform that extracts, standardizes, and publishes cannabis regulatory data from US state agencies. We turn PDFs, messy spreadsheets, and hard-to-access dashboards into clean, accessible datasets.

Tech Stack

FastAPI + SQLAlchemy + Scrapy + pdfplumber. Python-first, no Java dependencies.

Multi-State

Modular architecture. Each state is a self-contained module with its own scrapers and config.

Data Quality

Operator aliasing, lineage tracking, and validation rules ensure accurate, consistent data.

Quick Start

Public users can start with the API and docs. Local source setup is for approved contributors under project terms.

1. Public path — no access request needed

# Read the data (free, anonymous) browse the live state dashboards, /spec (the open normalization standard), and per-state source notes curl https://devcannabis.com/api/summary curl "https://devcannabis.com/api/market/summary?state=WA" # Contribute without any repo access submit source-backed corrections or new source suggestions at /contribute # API keys and bulk exports are request-gated request non-commercial API access, bulk access, or partner permissions

2. Approved contributor setup (repo is private — request access first)

The platform repo is invite-only; git clone works only after a maintainer adds you as a collaborator via the contributor form. Once approved:

# After your collaborator invite is accepted git clone https://github.com/GJManno/devcannabis.git cd devcannabis/app make setup # installs deps, copies .env, seeds the DB, runs checks make run # serves http://localhost:8500

3. Verify your local dashboard

# Approved local contributor workflow open http://localhost:8500 # Local interactive API docs (enabled in DEBUG only) open http://localhost:8500/api-docs
Source access note

Developer/source access is request-based and approved. Public dashboards are free; API/export access requires signup, auth, API key, or contributor login. Public outputs, issues, source-backed corrections, and methodology review remain available under the controlled public-use terms.

Access Policy

DevCannabis keeps the public site and dashboards free while protecting programmatic access and the core platform. API access, exports, bulk downloads, and automated use require signup/auth, an API key, or contributor login.

Allowed without permission

Non-commercial public-interest use of public dashboards and published notes with attribution to DevCannabis and original regulatory sources.

Written permission required

Bulk export, commercial use, resale/republication, model training, competing products, hosted mirrors, or using DevCannabis as a backend.

Approved contributor access

Developer/source access is reviewed manually. Approved roles include viewer, data_contributor, reviewer, moderator, developer, partner, and admin.

Request statuses should move through submitted, needs_source, under_review, approved, rejected, and published. API-key infrastructure should track key owner, rate limits, request logs, revoke/disable state, and terms acceptance timestamp before broad export access is enabled.

Read the full Access Policy.

Architecture

The project is organized into three main layers:

ommu/ ├── app/ # FastAPI web application │ ├── main.py # App entry point, routing │ ├── models/ # SQLAlchemy ORM models │ ├── api/ # REST API endpoints │ ├── services/ # Business logic │ └── templates/ # Jinja2 templates ├── states/ # State-specific modules │ ├── florida/ # Florida config, operators, scraper settings │ ├── _template/ # Template for new states │ └── regulatory_sources.py # Official state URLs reference ├── scraper/ # Scrapy project │ └── spiders/ # State-specific spiders ├── scripts/ # CLI tools for seeding, migration └── data/ # SQLite DB, PDFs, CSVs

Data Flow

  1. Scraper downloads PDFs from state regulatory websites
  2. Parser (pdfplumber) extracts tables from PDFs
  3. Normalizer applies operator aliases and validation rules
  4. Database stores normalized data with lineage tracking
  5. API/Dashboard serves data to users

Contributor Pathways

Pick the narrowest useful path. Code/source access is approved; source-backed public corrections are welcome.

Data Contributor

Submit Sources & Corrections

Best for official source links, provenance notes, data discrepancies, and evidence-backed corrections.

  • Submit verified regulator source URLs
  • Flag parser or data-quality issues
  • Submit data corrections
  • Improve public methodology notes
  • Cite primary sources where practical
Approved Contributor

Build, Review, or Partner

For developers, moderators/reviewers, and research partners who need deeper collaboration.

  • Request source access for adapters, tests, API, or dashboard work
  • Apply as State Lead or developer contributor
  • Review submissions as moderator/reviewer
  • Request research/partner collaboration
  • Follow licensing and contribution terms
Ready to help?

Use the contributor path to submit sources/corrections or request approved developer, reviewer, or partner access.

Add a New State

Adding a new state involves four main steps:

1. Create State Module

# Copy the template cp -r states/_template states/massachusetts cd states/massachusetts

2. Configure the State

Edit the following files in your new state folder:

File Purpose
operators.py Define operators, aliases (name variations), junk names to filter
regulatory.py State info, license types, regulatory timeline
config.py Data source URLs, scraper settings, PDF parsing coordinates
seed.py Database seeding functions

3. Register the State

# In states/__init__.py from . import massachusetts AVAILABLE_STATES = { "FL": florida, "MA": massachusetts, # Add your state }

4. Build the Spider

Add a Scrapy spider in scraper/spiders/ that downloads data from your state's regulatory portal.

Check the official source registry first

Canonical sources must be verified public government or regulatory organizations. Use /api/sources/official and data/sources/official_regulatory_sources.json before adding a pipeline.

Data Sources Reference

We maintain a canonical registry of verified public government/regulatory portals. Private or unverified links may be useful as non-canonical references, but they are not source-of-truth inputs.

State Regulator Format Status
Florida OMMU PDF Live
Massachusetts Cannabis Control Commission CSV Planned
California Dept of Cannabis Control HTML Planned
Colorado MED CSV Planned
Michigan CRA ArcGIS Research

Canonical registry API: /api/sources/official. Registry data: data/sources/official_regulatory_sources.json.

Trust fields to preserve

Where feasible, every source-backed claim should expose source URL, date fetched, last verified date, confidence, reviewer, correction history, and a challenge/correction link.

API Reference

New: versioned API at /api/v1

Build new integrations on /api/v1 — a stable, curated, jurisdiction-neutral surface with interactive docs at /api/v1/docs and a published schema at /api/v1/openapi.json. Its /observations endpoint returns records exactly as published in the open standard. The unversioned routes below remain available but are not stability-guaranteed.

Public summary endpoints return JSON. Base URL: /api. API/export access for regular programmatic use requires signup/auth/API key or contributor login.

Response note: newer payloads may expose operator-oriented fields such as operator_count and licenses_per_operator alongside backward-compatible legacy aliases.

Route note: prefer /api/operators and /api/operator/{name} in new consumers. Legacy /api/mmtc* paths remain available as compatibility routes during the transition.

Endpoint Method Description
/api/summary GET Current KPIs and market share
/api/timeseries GET Historical data by metric
/api/timeseries/all GET All metrics in one response
/api/operators GET All operators with latest stats
/api/operator/{name} GET Single operator with full history
/api/mmtcs, /api/mmtc/{name} GET Legacy compatibility routes for older consumers
/api/export/csv GET Authenticated contributor export; bulk/commercial use requires approval

Data Models

Key database models:

WeeklyReport

Weekly dispensing data: THC, CBD, smokable oz, patient/physician counts per operator.

Operator

Licensed operators with license info, business structure, and parent company.

OperatorLineage

Tracks acquisitions, mergers, and rebrands over time.

DispensaryLocation

Individual dispensary locations with coordinates.

State Pipeline Status

Current status of state data pipelines:

Complete — Full data, actively maintained
Partial — Some data, gaps exist
In Progress — Pipeline being built
Planned — On roadmap, seeking lead
State Status Dashboard
Florida Live — Full /fl
Colorado Live — Spine /co
Massachusetts Live — Spine /ma
Michigan Live — Spine /mi
Oregon Live — Spine /or
Washington Live — Spine /wa
Illinois Planned — seeking lead

Per-state maintainers are listed on the community page. Want to lead a state? Apply to become a State Lead.

Roadmap: v0 → v1 → v2

Where DevCannabis is, and where it's going. Milestones land as they're built and as real consumers show up — no dates promised, no vaporware. The project is solo-maintained today; the roadmap is sequenced so each stage earns the next.

v0 — the normalized spine (live today)

  • 6 live state dashboards normalized into one provenance-tracked schema — every number traces to a named government regulator with a source link and confidence label.
  • Free anonymous JSON API over summaries, timeseries, market data, operators, locations, and citations.
  • The open normalization standard published at /spec (CC BY 4.0) with machine-readable JSON Schemas.
  • Automated refresh at each regulator's own release cadence, with snapshot-hash provenance and restatement lineage.
  • Public correction and source-submission intake at /contribute — no account required beyond email.

v1 — the consumption layer (in progress)

v0 made the data trustworthy; v1 makes it effortless to build on.

  • Versioned API — a stable /api/v1 with a published OpenAPI schema, so integrations don't break silently.
  • The first cannabis MCP server — a hosted, read-only endpoint so AI agents and assistants can query normalized, citation-backed cannabis data directly.
  • Open bulk data — downloadable CSV dumps of the normalized observations, regenerated automatically, free for research and analysis.
  • Public spec & adapter-commons repo — the standard, JSON Schemas, adapter template, and contract tests in a repo anyone can star, fork, and PR against.
  • Weekly Pulse publishing — the source-backed email brief, delivered on a real cadence.

v2 — the open cannabis data commons (the ambition)

Where this goes once v1 has real consumers — ambitious, and deliberately gated on demand rather than promises.

  • Machine-readable legality dataset — versioned legal status per jurisdiction (medical/recreational status, possession limits, home grow, effective dates, statute citations) with a "what changed this week" feed. US states first, then international jurisdictions.
  • Community-maintained jurisdictions — named state leads growing coverage through the documented Add a New State path, with credit on every state page.
  • Cross-jurisdiction operator identity — track multi-state operators as one entity across every market they operate in.
  • International-ready schema — multi-currency, multi-language jurisdiction support so Canadian provinces and national programs (Germany, Thailand, Uruguay) normalize into the same standard.
How to move this roadmap faster

Use the API and tell us what breaks. Cite the data and tell us where it's wrong. Or submit a source, a correction, or a state-lead request — every verified contribution is credited.