budtags/skills/canix/SKILL.md
Use this skill when working with Canix cannabis ERP API integration, managing sales/purchase orders, syncing items/products, tracking inventory/packages, or handling cultivation and manufacturing data from Canix.
npx skillsauth add jwilly246/budtags-claude-plugin canixInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are now equipped with comprehensive knowledge of the complete Canix API v1.3.5 via modular category files, scenario templates, and pattern guides. This skill uses progressive disclosure to load only the information relevant to your task.
When the user asks about Canix integration, you can:
where syntax, facility scoping, async submissions)This skill has access to 8 category files, 5 scenario templates, 8 pattern files, and 9 OpenAPI schema files:
Commerce:
categories/sales-orders.md — 8 operations (sales order CRUD, contents, payments, status transitions)categories/purchase-orders.md — 6 operations (PO CRUD, contents, payments)categories/crm.md — 8 operations (customer read, vendor full CRUD)Products & Inventory:
categories/products-items.md — 17 operations (items CRUD, types, sub-types, brands, NCI, standard costs, photos, files)categories/inventory.md — 8 operations (packages, locations, weight units)Cultivation & Manufacturing:
categories/cultivation.md — 12 operations (strains CRUD, plant batches, plants, harvests)categories/manufacturing.md — 6 operations (manufacturing batches, runs, bills of materials)System & Logistics:
categories/logistics-system.md — 11 operations (transfers, destinations, company, facilities, submissions, audited actions, standard costs)scenarios/sales-order-import-workflow.md — Import sales orders into BudTagsscenarios/product-import-workflow.md — Import items/products and reference datascenarios/customer-import-workflow.md — Import customers and vendorsscenarios/sales-order-writeback-workflow.md — Push BudTags orders back to Canixscenarios/manufacturing-import-workflow.md — Import manufacturing batches, runs, BOMspatterns/authentication.md — X-API-KEY header, key generation, BudTags storagepatterns/pagination.md — Offset-based pagination (limit/offset, max 2000)patterns/filtering.md — SQL-like WHERE clause syntax (=, >, <, BETWEEN, IN, LIKE, AND, OR)patterns/facility-scoping.md — facility_id query parameter on supported endpointspatterns/error-handling.md — HTTP error codes, common errors, retry strategiespatterns/date-formats.md — ISO 8601 timestamps and date-only formatspatterns/async-submissions.md — Write operation polling via Submission UUIDspatterns/write-safety.md — Irreversibility warnings, writable vs read-only entitiesschemas/ directory — 9 OpenAPI JSON files with complete endpoint specificationsENTITY_TYPES.md — TypeScript type reference for all Canix entitiesALWAYS determine the relevant domain before loading category files.
Canix is a full cannabis ERP covering 8 domains. Route the user's question to the correct domain:
Keywords: sales order, SO, sell, ship, accept, order status, delivery, invoice, delivery_fee, payment_terms
Load: categories/sales-orders.md
Scenarios: scenarios/sales-order-import-workflow.md, scenarios/sales-order-writeback-workflow.md
Key endpoints:
GET /sales_orders — List sales orders (with pagination + where filter)POST /sales_orders — Create sales order ⚠️ WRITEGET /sales_orders/{id} — Get single sales order (includes customer, contents, payments)PUT /sales_orders/{id} — Update sales order ⚠️ WRITEGET /sales_orders/{id}/contents — Get line itemsGET /sales_orders/{id}/payments — Get paymentsPUT /sales_orders/{id}/status/{status_name} — Transition status ⚠️ WRITEStatus lifecycle: created → approved → filled → shipped → accepted → archived | requested | canceled
Keywords: purchase order, PO, buy, receive, procurement, vendor order, requested_delivery_date
Load: categories/purchase-orders.md
Related: categories/crm.md (for vendor details)
Key endpoints:
GET /purchase_orders — List purchase ordersPOST /purchase_orders — Create purchase order ⚠️ WRITEGET /purchase_orders/{id} — Get single PO (includes vendor, contents, payments)GET /purchase_orders/{id}/contents — Get line items (can be Item OR NonCannabisProduct)GET /purchase_orders/{id}/payments — Get paymentsStatus lifecycle: CREATED → RELEASED → REQUESTED → PARTIALLY_RECEIVED → RECEIVED → PAID → ARCHIVED
Keywords: customer, vendor, supplier, contact, license, outstanding_balance, territory, dba
Load: categories/crm.md
Scenario: scenarios/customer-import-workflow.md
Key endpoints:
GET /customers — List customers (returns CustomerExtended with outstanding_balance)GET /customers/{id} — Get single customerGET /vendors — List vendorsPOST /vendors — Create vendor ⚠️ WRITEGET /vendors/{id} — Get single vendorPUT /vendors/{id} — Update vendor ⚠️ WRITEDELETE /vendors/{id} — Delete vendor ⚠️ WRITEKeywords: item, product, SKU, brand, item type, sub-type, non-cannabis, NCI, standard cost, photo, file, accounting_inventory_type
Load: categories/products-items.md
Scenario: scenarios/product-import-workflow.md
Key endpoints:
GET /items — List items (supports facility_id filter)POST /items — Create item ⚠️ WRITEGET /items/{id} — Get single item (rich: strain, type, brand, quantities, integrations)PUT /items/{id} — Update item ⚠️ WRITEDELETE /items/{id} — Delete item ⚠️ WRITEPOST /items/{id}/standard_cost — Add standard cost ⚠️ WRITEPOST /items/photos — Upload METRC item photos (base64) ⚠️ ASYNCPOST /items/files — Upload METRC item files (base64) ⚠️ ASYNCGET /item_types — List item types (with requirement flags)GET /item_sub_types — List item sub-typesGET /brands — List brandsGET /non_cannabis_products — List non-cannabis products (supports facility_ids filter)GET /non_cannabis_products/{id} — Get single NCIGET /non_cannabis_products/{id}/boms — Get bills of materials for NCIKeywords: strain, plant, plant batch, harvest, grow, flowering, vegetative, indica, sativa, clone, cutting
Load: categories/cultivation.md
Key endpoints:
GET /strains — List strains (supports facility_id filter)POST /strains — Create strain ⚠️ WRITEGET /strains/{id} — Get single strain (includes cross_strains)PUT /strains/{id} — Update strain ⚠️ WRITEGET /plant_batches — List plant batches (mature/immature/veg/flowering counts)GET /plant_batches/{id} — Get single plant batchGET /plants — List plants (tag, growth_phase, lifecycle dates)GET /plants/count — Get total plant countGET /plants/{id} — Get single plantGET /harvests — List harvests (weights, plant/package counts)GET /harvests/{id} — Get single harvestKeywords: package, tag, location, weight unit, test results, COA, lab test, COGS, terpene, cannabinoid
Load: categories/inventory.md
Key endpoints:
GET /packages — List all submitted packages (all statuses)GET /packages/{id} — Get single package (rich: test_results, COGS, source/dest packages, lab info, COA URL)GET /locations — List locations (supports facility_id, includes parent_location)GET /locations/count — Get location countGET /locations/{id} — Get single locationGET /weight_units — List all weight units (id, name, abbreviation)Keywords: manufacturing, manu batch, manu run, BOM, bill of materials, recipe, labor, waste, machine, solvent, temperature
Load: categories/manufacturing.md
Scenario: scenarios/manufacturing-import-workflow.md
Key endpoints:
GET /manu_batches — List manufacturing batchesGET /manu_batches/{id} — Get single batch (template_name, run IDs)GET /manu_batch_runs — List manufacturing runsGET /manu_batch_runs/{id} — Get single run (MOST COMPLEX: cannabis I/O, NCI, labor, waste, machine)GET /bills_of_materials — List BOMsGET /bills_of_materials/{id} — Get single BOM (source items, output items, proportion_type)Keywords: transfer, manifest, destination, shipping, company, facility, license number, submission, async, audit, standard cost
Load: categories/logistics-system.md
Pattern: patterns/async-submissions.md (if submission/async questions)
Key endpoints:
GET /transfers — List transfers (manifest_number, destinations, sales_order link)GET /transfers/{id} — Get single transferGET /transfer_destinations — List transfer destinationsGET /transfer_destinations/{id} — Get single destination (contents with shipped/received weights)GET /companies/{id} — Get company by IDGET /facilities — List facilities (license_number, address)GET /facilities/{id} — Get single facilityGET /submissions/{id} — Poll async operation status (9 statuses)GET /audited_actions — List audit trail entriesGET /standard_costs/{id} — Get standard costPUT /standard_costs/{id} — Update standard cost ⚠️ WRITEDELETE /standard_costs/{id} — Delete standard cost ⚠️ WRITEIMPORTANT: Only load files relevant to the user's question. DO NOT load all categories.
Determine from the user's question:
User asks: "How do I import sales orders from Canix?"
Load:
scenarios/sales-order-import-workflow.md (complete workflow)categories/sales-orders.md (endpoint details)patterns/filtering.md (IF date range filtering needed)patterns/pagination.md (IF paginating large datasets)User asks: "What's the response format for GET /packages/{id}?"
Load:
categories/inventory.md (endpoint + schema highlights)schemas/openapi-inventory.jsonUser asks: "How do I create a sales order in Canix?"
Load:
categories/sales-orders.md (endpoint + request body)patterns/write-safety.md (irreversibility warnings)patterns/async-submissions.md (IF Metrc-bound operation)scenarios/sales-order-writeback-workflow.mdUser asks: "How does the where filter work in Canix?"
Load:
patterns/filtering.md (SQL-like WHERE syntax)patterns/date-formats.md (IF date filtering involved)When answering:
User: "How do I fetch and import sales orders from Canix?"
Your Response:
[Load scenarios/sales-order-import-workflow.md]
[Load categories/sales-orders.md]
**Workflow**:
1. GET /sales_orders with pagination and date filter
2. For each order, contents and payments are embedded in the response
3. Map to BudTags MarketplaceOrder (source='canix')
**Laravel Example**:
$orders = $api->get('/sales_orders', [
'limit' => 2000,
'offset' => 0,
'where' => "updated_at >= '2024-01-01'",
'order_by' => 'id asc',
]);
**Pattern References**: scenarios/sales-order-import-workflow.md, patterns/filtering.md
User: "How do I update a sales order status to shipped?"
Your Response:
[Load categories/sales-orders.md]
[Load patterns/write-safety.md]
**Endpoint**: PUT /sales_orders/{id}/status/shipped
**No request body needed** — status is in the URL path
**Laravel Example**:
$response = $api->put("/sales_orders/{$id}/status/shipped");
// Returns: { previous_status: "filled", new_status: "shipped" }
⚠️ **Write Safety**: This is irreversible. Cannot cancel orders that are shipped.
**Valid transitions**: created → approved → filled → shipped → accepted → archived
**Cannot cancel if**: shipped, accepted, returned, or archived
**Pattern References**: categories/sales-orders.md, patterns/write-safety.md
User: "How do I filter Canix items by facility and active status?"
Your Response:
[Load patterns/filtering.md]
[Load patterns/facility-scoping.md]
Items support BOTH facility_id param AND where filtering:
**Laravel Example**:
$items = $api->get('/items', [
'facility_id' => 123,
'where' => "is_active=true AND updated_at >= '2024-06-01'",
'limit' => 2000,
'order_by' => 'name asc',
]);
**Supported where operators**: =, >, <, >=, <=, BETWEEN, IN, LIKE, AND, OR
**Facility-scoped endpoints**: items, item_types, item_sub_types, strains, locations
**Pattern References**: patterns/filtering.md, patterns/facility-scoping.md
User: "Show me the full Package schema with test results"
Your Response:
[Load categories/inventory.md]
[Read schemas/openapi-inventory.json for exact format]
The Package schema is one of the richest in the Canix API:
**Key fields**: id, tag, status, item, weight, original_weight, weight_unit,
packaged_date, expiration_date, location, brand, source_packages[],
destination_packages[], test_results, lab_test_url, coa_url, lab_test_info, cogs
**test_results** contains arrays of {value, measure} for:
thc, cbd, cbn, cbg, cbga, cbc, cbca, cbda, thca, delta_8_thc, delta_9_thc,
thcv, thcva, total_thc, total_cbd, total_cannabinoid + full terpene profile
**Pattern Reference**: categories/inventory.md
Want me to load the full OpenAPI schema for exact field definitions?
Header: X-API-KEY: {your_api_key}
Generate key at: https://app.canix.com/company/api
Base URL: https://api.canix.com/api/v1
limit — Max records per page (default: 2000, max: 2000)
offset — Starting position (default: 0)
order_by — SQL format: "id desc", "updated_at asc"
⚠️ Responses are RAW ARRAYS (no count/next/previous wrapper)
⚠️ Last page: response.length < limit
where=status='Active'
where=updated_at >= '2024-01-01'
where=id BETWEEN 1 AND 10000
where=status IN ('Active', 'Pending')
where=sku LIKE 'ABC%'
where=facility_id=123 AND is_active=true
⚠️ This is NOT Django-style (__gte/__lte) — it's raw SQL-like syntax
⚠️ URL-encode the where parameter value
✅ Supports facility_id: items, item_types, item_sub_types, strains, locations, facilities, non_cannabis_products
❌ No facility_id: sales_orders, purchase_orders, customers, vendors, packages, brands
⚠️ ALL write endpoints are marked IRREVERSIBLE
⚠️ Writable: sales_orders, purchase_orders, items, strains, vendors, standard_costs, photos, files
⚠️ Read-only: packages, plants, plant_batches, harvests, transfers, locations, customers
⚠️ Metrc-bound writes (photos/files) return Submission UUIDs — poll /submissions/{uuid}
❌ Using Django-style filters (__gte) — Canix uses SQL-like WHERE strings
❌ Expecting pagination wrapper — responses are raw arrays, not {count, results}
❌ Exceeding limit=2000 — max page size is 2000
❌ Forgetting to URL-encode the where parameter
❌ Not polling Submission UUID after Metrc-bound writes (photos/files)
❌ Writing to production without testing on sandbox first
Help users successfully integrate with the Canix API by:
You have complete knowledge of all 68 Canix API v1.3.5 operations across 8 domains via modular, focused files. Use progressive disclosure to provide fast, relevant answers!
testing
Comprehensive Redis 7.x reference with BudTags-specific patterns. Covers all commands, data types, persistence, memory optimization, performance tuning, high availability, security, and Laravel integration.
development
React 19 changes, new hooks, Actions, Activity component, and migration guides for upgrading from React 18
development
Use this skill when working with Quill.js rich text editor - API methods, configuration, modules, Delta format, and custom implementations.
testing
Use this skill when working with QuickBooks Online integration, OAuth authentication, creating invoices, managing customers, handling payments, or syncing with Metrc data.