Supercollections
- T3 API Supercollections
- What is a Supercollection?
- Available Supercollection Endpoints
- The
includeParameter - Superpackages Example
- Next Steps
T3 API Supercollections¶
With Metrc data, users frequently encounter these sorts of problems:
- "I want to load my packages, but also need test results for each"
- "I want to load my transfers, but also want all the packages"
- "I want to load my items, but I also want all the images and ingredients"
Enter supercollections
What is a Supercollection?¶
The best way to understand supercollections is to compare them to T3 collections:
- T3 collection endpoints are designed to send exactly one request to Metrc per request to T3.
- Examples: Active Packages, Incoming Transfers, Active Items.
- This ensures the endpoints are fast, have generous rate limits, and are flexible to use.
- If you want to load metadata for a collection, you need to explicitly request it per row.
- T3 supercollection endpoints are designed to eagerly load all metadata for each collection object.
- Examples: Active Superpackages, Incoming Supertransfers, Superitems.
- They extend existing collection endpoint behavior.
- This allows the endpoint to efficiently load, organize, and analyze the metadata for you.
- Endpoints have lower rate limits, and are slower to use.
- Metadata is loaded declaratively. For example, you'd specify you want lab results and history for an active superpackages request.
Available Supercollection Endpoints¶
| Supercollection | Path | include options |
|---|---|---|
| Superitems | /v2/items/super | notes, history, ingredients, images |
| Active Superpackages | /v2/packages/active/super | labResults, labResultBatches, sourceHarvests, history |
| Inactive Superpackages | /v2/packages/inactive/super | labResults, labResultBatches, sourceHarvests, history |
| In Transit Superpackages | /v2/packages/intransit/super | labResults, labResultBatches, sourceHarvests, history |
| On Hold Superpackages | /v2/packages/onhold/super | labResults, labResultBatches, sourceHarvests, history |
| Incoming Active Supertransfers | /v2/transfers/incoming/active/super | packages, transporters |
| Incoming Inactive Supertransfers | /v2/transfers/incoming/inactive/super | packages, transporters |
| Outgoing Active Supertransfers | /v2/transfers/outgoing/active/super | packages, transporters |
| Outgoing Inactive Supertransfers | /v2/transfers/outgoing/inactive/super | packages, transporters |
| Rejected Supertransfers | /v2/transfers/rejected/super | packages, transporters |
| Hub Supertransfers | /v2/transfers/hub/super | packages, history |
| Active Superharvests | /v2/harvests/active/super | history, plants, packages |
| Inactive Superharvests | /v2/harvests/inactive/super | history, plants, packages |
| On Hold Superharvests | /v2/harvests/onhold/super | history, plants, packages |
| Vegetative Superplants | /v2/plants/vegetative/super | history |
| Flowering Superplants | /v2/plants/flowering/super | history |
| Inactive Superplants | /v2/plants/inactive/super | history |
| On Hold Superplants | /v2/plants/onhold/super | history |
| Active Mother Superplants | /v2/plants/mother/active/super | history |
| Inactive Mother Superplants | /v2/plants/mother/inactive/super | history |
| On Hold Mother Superplants | /v2/plants/mother/onhold/super | history |
| Active Superplantbatches | /v2/plantbatches/active/super | history |
| Inactive Superplantbatches | /v2/plantbatches/inactive/super | history |
| On Hold Superplantbatches | /v2/plantbatches/onhold/super | history |
| Active Supersales | /v2/sales/active/super | transactions |
| Inactive Supersales | /v2/sales/inactive/super | transactions |
| Available Supertags | /v2/tags/available/super | (none) |
| Used Supertags | /v2/tags/used/super | (none) |
| Voided Supertags | /v2/tags/voided/super | (none) |
| Active Superlocations | /v2/locations/active/super | (none) |
| Superstrains | /v2/strains/super | (none) |
The last five have no include options: there is no related Metrc data to attach to a tag, location or strain. They exist as /super paths so that a caller building URLs by pattern does not have to special-case them, and they return the same records their plain collection counterparts do.
The include Parameter¶
The include parameter controls which additional data is fetched and attached to each object in the response. Without it, a supercollection request behaves like a regular collection request.
Each include value does two things:
- Attaches raw Metrc data as a new array on each object (e.g.
labResults,sourceHarvests). - Populates fields on the
metadataobject with extracted, cleaned-up values derived from that raw data.
You can combine multiple include values by repeating the parameter: include=labResults&include=sourceHarvests.
A comma-joined list is not supported — include=labResults,sourceHarvests is one value, not two.
An include value the endpoint does not accept returns 400 Invalid Include, and the response lists the values it does accept:
GET /v2/packages/active/super?licenseNumber=EX-00001&include=labresults
400 Invalid Include
Unrecognized include `labresults`. This endpoint accepts: history, sourceHarvests,
labResultBatches, labResults.
Include values are case-sensitive, so labresults above is rejected while labResults is accepted. The valid values for each endpoint are also published as an enum in the OpenAPI spec, so an API client can read them programmatically rather than copying them from this page.
The same include values work on super reports, which return the whole enriched dataset in one request instead of paging through it — useful for spreadsheet exports. See Super Reports.
A few metadata fields are populated unconditionally (no include required), when the underlying data is available:
- Superpackages:
netWeightOrVolume,netWeightOrVolumeUnitOfMeasure - Superitems:
approvalNumber,itemImages
Superpackage includes¶
include | Raw data attached | metadata fields populated |
|---|---|---|
labResults | labResults[] | extractedLabResults, testSamplePackageLabels, labResultPdfs, indexedLabResults |
labResultBatches | labResultBatches[] | extractedLabResults, testSamplePackageLabels, labResultPdfs, indexedLabResults |
sourceHarvests | sourceHarvests[] | harvestDates |
history | history[] | initialQuantity, initialQuantityUnitOfMeasure, manifestNumber², destinationFacilityLicenseNumber², destinationFacilityName², transferType² |
² Only present for in-transit packages.
indexedLabResults is a simplified dictionary intended for templating (e.g. on a label). Example access:
{{ package.metadata.indexedLabResults.totalThc.name }} → "Total THC"
{{ package.metadata.indexedLabResults.totalThc.value }} → 12.5
{{ package.metadata.indexedLabResults.totalThc.unit }} → "%"
{{ package.metadata.indexedLabResults.totalThc.full }} → "Total THC: 12.5 %"
Also indexed: totalCbd, topTerpene1, topTerpene2, etc.
Superitem includes¶
include | Raw data attached | metadata fields populated |
|---|---|---|
notes | notes[] | (none) |
history | history[] | (none) |
ingredients | ingredients[] | (none) |
images | images[] | itemImages |
approvalNumber and itemImages are populated on every superitem when the data is available — you don't need include=images to get image metadata, only the raw base64/image records themselves.
Supertransfer includes¶
include | Raw data attached | metadata fields populated |
|---|---|---|
packages | packages[] | (none) |
transporters | transporters[] | (none) |
Hub supertransfer includes¶
Hub transfers — the ones your license transports — take a different include set:
include | Raw data attached | metadata fields populated |
|---|---|---|
packages | packages[] | (none) |
history | history[] | (none) |
There is deliberately no transporterDetails include. Metrc embeds the driver legs directly in the hub response as shipmentTransporterDetails, so they are present on every record without spending a request:
import requests
response = requests.get(
"https://api.trackandtrace.tools/v2/transfers/hub/super",
headers={"Authorization": f"Bearer {access_token}"},
params={
"licenseNumber": "DIS000038",
"pageSize": 20,
"include": ["packages", "history"],
},
)
for transfer in response.json()["data"]:
# Already present -- no include was needed for this
for leg in transfer["shipmentTransporterDetails"]:
print(transfer["manifestNumber"], leg["lineNumber"], leg["driverName"])
# These two required the includes above
print(f" {len(transfer['packages'])} packages, {len(transfer['history'])} history entries")
Note that transporterFacilityName, driverName, vehicleMake and friends are also flattened onto the transfer itself. When multiVehicle or isLayover is true those top-level fields describe only the first leg — read shipmentTransporterDetails for the rest.
Superharvest includes¶
include | Raw data attached | metadata fields populated |
|---|---|---|
history | history[] | (none) |
plants | plants[] | (none) |
packages | packages[] | (none) |
Superplant includes¶
include | Raw data attached | metadata fields populated |
|---|---|---|
history | history[] | (none) |
Supersales includes¶
include | Raw data attached | metadata fields populated |
|---|---|---|
transactions | transactions[] | (none) |
Superpackages Example¶
This is the most commonly used supercollection. Below is an example that loads all active superpackages with lab results for packages in the "Buds" product category:
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.8"
# dependencies = [
# "t3api-utils",
# ]
# ///
from t3api_utils.api.parallel import load_all_data_sync
from t3api_utils.main.utils import (get_authenticated_client_or_error,
interactive_collection_handler,
pick_license)
def main():
api_client = get_authenticated_client_or_error()
license_number = pick_license(api_client=api_client)
all_packages = load_all_data_sync(
client=api_client,
path="/v2/packages/active/super",
license_number=license_number["licenseNumber"],
page_size=50,
include="labResults",
filter="item.productCategoryName__eq:Buds"
)
interactive_collection_handler(data=all_packages)
if __name__ == "__main__":
main()
Each object in the response will contain:
- All the standard package fields (label, item, quantity, etc.).
- A
labResultsarray with the raw Metrc lab result data. - A
metadataobject withextractedLabResults,testSamplePackageLabels,labResultPdfs,indexedLabResults, plus the unconditionalnetWeightOrVolume/netWeightOrVolumeUnitOfMeasure.
You can find more supercollection examples in the T3 API examples repository.
Next Steps¶
- If you haven't yet, set up Python and write your first API script.
- Compare against Reports, which return a whole dataset in one call. A plain report doesn't attach related objects; a super report does, using the same
includevalues documented above. - Browse the OpenAPI spec — each supercollection's
includeoptions are documented there. - Refer to the T3 API documentation to explore all the available endpoints.
- Most API endpoints require a T3+ subscription. If you don't have a T3+ subscription, you can sign up here.