Developer docs
Build on the ledger. Draft, never execute.
BudAlly exposes the same objects the product runs on — packages, receipts, lines, proposals, rule results — through an MCP server for AI agents and a REST API for everything else. Both are read-plus-draft: anything that changes the world becomes a proposal in the tenant's approval queue.
MCP server
Add https://mcp.budally.com as a remote MCP server in Claude, ChatGPT, or your own client. The OAuth flow signs the user in with their BudAlly role; tools are filtered by that role and by the tenant's data-use rules. Every draft tool returns a proposal id you can watch in the queue.
// read tools
- inventory.read(location, as_of?)
- → packages with tag, qty, cost, lab results, source taint
- sales.read(location, from, to)
- → receipts joined to Metrc receipt ids, match rate
- ledger.read(tag)
- → every event for one package
- prices.read(location)
- → shelf + OTD, market median (source, n, k) where licensed
- rules.check(pack, action, context)
- → ALLOWED | BLOCKED | UNKNOWN + rule id + citation
// draft tools — each returns a proposal_id
- po.draft(location, lines[])
- price_change.draft(sku, new_price, rationale)
- campaign.draft(segment, copy, holdout)
- bill.draft(invoice_ref, lines[])
// there are no execute tools. proposals execute only from the approval queue,
// under the approver's own POS or Metrc credential.
Every response carries provenance
source, as_of, taint (METRC · POS:<vendor> · LICENSED:<licensor> · OWN_CHECK) so an agent can cite what a human can check.
Rules are enforced at the API, not the prompt
Dutchie-connector rows never appear in benchmarks; Headset data never leaves internal analysis; cells with k < 8 return “—”. A client can't opt out.
REST API
| Method | Path | Returns |
|---|---|---|
| GET | /v1/locations/{id}/packages | Package ledger rows; filters by tag, item, room, as_of |
| GET | /v1/locations/{id}/receipts | Receipts with lines, tags, taxes, tender, metrc_receipt_id |
| GET | /v1/proposals?state=proposed | Queue items with evidence, confidence, rules_applied, precondition_hash |
| POST | /v1/proposals | Create a draft (same schema as MCP draft tools). Never executes. |
| POST | /v1/proposals/{id}/review | Attach a review note. Approval is UI-only, by a signed-in person. |
| GET | /v1/audit?from=&to= | Full audit trail export (JSON, CSV) |
| GET | /v1/exports/{kind} | ledger · members · consent_proofs · documents — the “your data leaves with you” endpoint |
| WEBHOOK | proposal.created · proposal.executed · sync.stale · clock.warning | Signed (HMAC), titles and ids only — details stay in-app |
Data-use registry
Every adapter and every tool is governed by a readable registry. A few entries your integration will hit:
- DU-DUT-03
- Dutchie-connector rows are excluded from all cross-tenant benchmarks and medians.
- DU-SCR-01
- Automated collection of Weedmaps, Leafly, Dutchie or Jane menus is denied; uploads with scraper provenance are rejected and not stored.
- DU-HDS-01
- Licensed market data is internal-analysis only; never syndicated, never returned to vendor-operated MCP clients.
- DU-LLM-01
- Model providers: no training, ≤30-day retention; zero-retention tier on Chain Ops.
- RI-ALL-10
- No segment, cohort or median with fewer than 8 contributors is returned; the field reads “—, k < 8”.
© 2026 BudAlly, Inc. · Pre-release documentation; shapes may change before GA.