Skip to content

Tuning Search Results

Tuning Result Volume with pageSize

The pageSize parameter controls how many matches each downstream Metrc endpoint may return. It defaults to 10 and is capped at 100. The total number of items in data is at most len(queriedMetrcEndpointIds) * pageSize.

Use a larger pageSize when the default isn't enough; for example, when a license has many similarly-named items and the top 10 from each endpoint isn't covering the matches you're looking for. Use a smaller pageSize when the request is purely a "did anything match" check.

curl 'https://api.trackandtrace.tools/v2/search?licenseNumber=LIC-00001&query=Blue%20Dream&pageSize=50' \
  -H 'Authorization: Bearer <TOKEN>'

pageSize applies uniformly to every queried endpoint. Out-of-range values (< 1 or > 100) return 400 Bad Request.

If you're not sure whether a higher pageSize would yield more results, look at endpointMetadata in the response: any entry with truncated: true had more matches available than your pageSize returned, and totalAvailable reports Metrc's full count.

Filtering Noise with minScore

The minScore query parameter drops results whose relevance score is below the threshold, server-side. Scores are in [0, 1], where 1.0 is an exact full-string match. Defaults to 0.0 (no filtering).

curl 'https://api.trackandtrace.tools/v2/search?licenseNumber=LIC-00001&query=Blue%20Dream&minScore=0.1' \
  -H 'Authorization: Bearer <TOKEN>'

Useful when:

  • A short or common query string produces a long tail of low-score matches that the UI just discards anyway.
  • You're looking for "is there a strong match?" and want the server to filter out the dross before serializing it.

The filter is per-result and applied before sorting. In SSE mode, result events still fire even when every match was filtered out, the event's results array will simply be empty. That tells the client the endpoint completed without truncation lying about availability.

Streaming Responses (SSE)

For interactive UIs that want to render results as soon as each Metrc endpoint replies (instead of waiting for the slowest one) /search can stream Server-Sent Events. There are two equivalent ways to opt in:

  • Add ?stream=true to the URL (easy to test from curl, easy to document).
  • Send Accept: text/event-stream (what EventSource does natively).

The response is a text/event-stream body containing two kinds of events:

  • event: result: emitted once per completed downstream endpoint, in completion order (fastest first). Payload contains endpointId, status (success or failed), an error string (failures only), and a results array sorted by score descending.
  • event: done: emitted once after every downstream endpoint has finished. Payload mirrors the JSON-mode summary: queriedMetrcEndpointIds, failedMetrcEndpointIds, skippedMetrcEndpointIds, and detectedQueryFormats.

Sample stream:

event: result
data: {"endpointId":"AVAILABLE_TAGS","status":"success","results":[{"score":1.0,"matchedEntry":{"...":"..."}}],"truncated":false,"totalAvailable":1}

event: result
data: {"endpointId":"ACTIVE_PACKAGES","status":"success","results":[{"score":0.71,"matchedEntry":{"...":"..."}}],"truncated":true,"totalAvailable":47}

event: result
data: {"endpointId":"INTRANSIT_PACKAGES","status":"failed","error":"Metrc Connection Failed","results":[]}

event: done
data: {"queriedMetrcEndpointIds":["AVAILABLE_TAGS","ACTIVE_PACKAGES"],"failedMetrcEndpointIds":["INTRANSIT_PACKAGES"],"skippedMetrcEndpointIds":["ACTIVE_ITEMS"],"detectedQueryFormats":["HEX_STRING","INTEGER"],"request":{"query":"1A4FF...","licenseNumber":"LIC-00001","pageSize":10,"minScore":0.0}}

Browser usage with EventSource:

const url = `/v2/search?licenseNumber=LIC-00001&query=${encodeURIComponent('Blue Dream')}`;
const source = new EventSource(url, { withCredentials: true });

source.addEventListener('result', (e) => {
  const { endpointId, status, results } = JSON.parse(e.data);
  // Render incrementally
});

source.addEventListener('done', (e) => {
  source.close();
});

curl usage:

curl -N 'https://api.trackandtrace.tools/v2/search?licenseNumber=LIC-00001&query=Blue%20Dream&stream=true' \
  -H 'Authorization: Bearer <TOKEN>'

(-N disables curl's output buffering so events appear as they arrive.)

Note

The SSE stream emits results in completion order, not score order. Each event's own results array is locally sorted by score, but the global ranking that JSON mode produces requires the client to merge events as they arrive.

Limits and Behavior

  • Per-endpoint cap of pageSize matches. Each downstream endpoint returns at most pageSize results (default 10, max 100). The total number of items in data is at most len(queriedMetrcEndpointIds) * pageSize. Watch endpointMetadata[].truncated to know when raising pageSize would yield more.
  • Per-endpoint timeout (~10s). Each downstream Metrc call is bounded so a single slow endpoint can't dominate total response time. Endpoints that exceed the timeout land in failedMetrcEndpointIds with an error of "Metrc Request Timeout". In SSE mode the corresponding result event still fires, failed endpoints don't block the rest of the stream.
  • Latency varies by endpoint. Tag, item, location, and strain searches typically return in well under a second. Package, plant, and especially transfer searches can take several seconds. JSON-mode total request time is bounded by the per-endpoint timeout; SSE-mode delivers fast endpoints' results first.
  • Narrow scope for speed. If you know the kind of object you're after, pass endpointIds to drop everything else. A query against endpointIds=AVAILABLE_TAGS,USED_TAGS will be much faster than the default fan-out.
  • Per-license. Like every collection endpoint, /search is scoped to the licenseNumber query parameter. Searching across multiple licenses requires multiple requests.
  • Free. No T3+ subscription required.

Next Steps

  • Back to the endpoint catalog and response shape: Search.
  • Check what your account may query first with Permissions.