FSMA 204 (the FDA Food Traceability Rule, 21 CFR § 1.1320) requires that any entity handling a food on the Food Traceability List (FTL) maintain Key Data Elements (KDEs) for each Critical Tracking Event (CTE) — harvest, cooling, initial pack, first land-receive, shipping, receiving, transformation. § 1.1455(c) further requires those records be furnished to FDA within 24 hours of request. This skill walks an agent through auditing one or more GTINs for KDE coverage by reading the EPCIS event ledger and the materialized CTE rows that Closient produces automatically when FSMA-relevant events are captured.Documentation Index
Fetch the complete documentation index at: https://docs.closient.com/llms.txt
Use this file to discover all available pages before exploring further.
When to use
- A brand owner needs to know “are we FSMA 204-compliant for batch X?” before the Jan 20, 2026 enforcement date — and afterward, every day.
- Before issuing a recall, audit which lots have enough KDE coverage to construct the FDA Sortable Spreadsheet export.
- A 3PL onboarding a new shipper needs to gap-analyze their KDE posture before contracting.
- Continuous-readiness dashboards.
GET /epcis/api/2.0/traceability/lots/{lot_id}/fda-export. This skill
is the gap-analysis step that runs before the export to flag missing
KDEs.
Auth
OAuth token (orX-API-Key) with OWNER or MANAGER membership on
the organization that owns the GTINs being audited.
Flow
Note: The dedicated/compliance/api/v1/products/{gtin}/fsma204-readiness
endpoint called out in the original ticket scope does NOT yet exist.
Until it ships (see Known gaps), an agent audits readiness by
composing existing queries — described in Steps 1-4 below.
Step 1 — Resolve GTINs to lots
For each GTIN you want to audit, list the lots that have any EPCIS activity:/10/{lot}) — the server matches
EPC URIs by exact string, so a prefix-trimmed URI captures every lot
under the GTIN. Collect distinct epcList values from the response,
parse the AI(10) lot segment off each one.
Alternatively, pull lots directly from the products API:
GET /products/api/v1/products/{gtin}/lots (if exposed for the org).
Step 2 — Audit CTE coverage per lot
For each lot, ask the EPCIS ledger which bizSteps were observed:bizStep values from the response. Compare against
the FSMA 204 CTE set expected for the product’s food category. The
generic checklist:
| Food category | Required CTEs (per § 1.1320 subpart and FTL row) |
|---|---|
| Fresh produce (FTL Cat 1) | harvesting → cooling → packing → shipping → receiving |
| RTE foods (FTL Cat 9) | packing (initial) → shipping → receiving |
| Fishery products (FTL Cat 17) | accepting (LAND_RECEIVE) → shipping → receiving |
| Cheese / dairy (FTL Cat 6) | packing → shipping → receiving |
| Eggs, in shell (FTL Cat 7) | packing → shipping → receiving |
| Generic processed | shipping → receiving (no INITIAL_PACK if the lot wasn’t packed by this org) |
Step 3 — Audit KDE completeness per CTE
For each captured EPCIS event in the lot’s chain, verify that the KDEs FSMA 204 expects for that CTE type are present. Required KDEs by CTE type (per FDA Sortable Spreadsheet template):| CTE type | Required KDEs |
|---|---|
HARVEST | Lot code, growing area, harvest start date, harvest end date, location (GLN). |
COOLING | Lot code, cooling date, location (GLN), reference document (PO/BOL). |
INITIAL_PACK | Lot code, packing date, quantity, location (GLN), reference document. |
LAND_RECEIVE | Lot code, vessel name, vessel identifier (USCG), species, landing date, location (GLN). |
SHIP | Lot code, quantity, ship date, ship-to location (GLN), trading partner. |
RECEIVE | Lot code, quantity, receive date, ship-from location (GLN), trading partner. |
TRANSFORM | Input lots, output lots, transform date, location (GLN), reference document. |
ilmd block (Step 7 of
capture-epcis-event) and the resolved trading-partner / location
records. An event with bizStep=harvesting but no cbvmda:harvest_start_date
in ilmd is a KDE gap.
Step 4 — Compose a readiness score
A per-GTIN readiness score is a simple two-dimensional rubric:cte_coverage_pct= (CTEs observed for the lot ∩ CTEs required for the food category) / required.kde_coverage_pct= (KDE fields populated across captured CTEs) / expected KDE fields across those CTE types.
Required inputs
gtin— GTIN-8 / 12 / 13 / 14 (server zero-pads shorter forms).lot(when scoping to a specific batch).
Optional inputs
food_category— to pick the correct CTE checklist. Closient infers this fromProduct.product_categorywhen it’s set.date_range— bound the audit to a recent window (e.g. last 365 days of shipments).
Output
The composed-from-existing-queries form is a list of structured rows, one per (GTIN, lot):Guidance for agents
- Run the audit on the materialized CTE table, not raw events,
where you can. The
CriticalTrackingEventmodel (seeapps.epcis.models) is the authoritative source of CTE rows — EPCIS events that didn’t produce a CTE (because the bizStep isn’t FSMA-relevant) are noise for this audit. The/traceability/lots/{lot_id}/fda-exportendpoint already does this filtering; reading its 202-pending response tells you which CTEs exist for the lot. - Don’t conflate “lot exists” with “lot is ready”. A lot with
zero EPCIS events is
0.0readiness, not “no data”. The product exists in the catalog; FSMA 204 requires CTEs. - Lock-state matters. Once a
ProductLothas been used in a CTE, itsLOCKED_FIELDS(lot code, harvest dates, expiration) are immutable. Don’t propose a fix that requires editing those fields — instead, the agent should surface a “capture a corrective event with the missing KDE in ILMD” workflow (callscapture-epcis-eventwith the right bizStep + ilmd block). - Audit BY ORGANIZATION’s role in the chain. A brand owner who
only packs (not harvests) is not on the hook for HARVEST KDEs —
those belong to the grower upstream. The CTE checklist in Step 2
is conditional on the org’s role; for a packer-only, only
INITIAL_PACK+SHIPare owed. - Surface the fix path, not just the gap. A missing
growing_areaKDE on a HARVEST event is fixable by capturing a correctivebizStep=harvestingevent with the rightcbvmda:growing_area— hand the agent the exact endpoint and JSON shape it needs. - Don’t recompute on every page render. When the dedicated endpoint ships, it will cache the per-(GTIN, lot) score for a short TTL. Until then, audits cost ≥ 2 EPCIS queries per lot — batch them.
Known gaps (planned)
- No dedicated readiness endpoint. The
/compliance/api/v1/products/{gtin}/fsma204-readinessendpoint called out in the ticket scope does NOT exist today. Filed as a follow-up: a real endpoint that walks CTE + KDE coverage and emits the structured shape above, with a 60s server-side cache. Until then, agents must compose the audit fromGET /epcis/api/2.0/eventsqueries as described above. - No food-category-aware CTE checklist on the server. The expected-CTE-by-FTL-category table lives in this skill doc rather than as a server-side rule. When the readiness endpoint ships, the checklist will move to the server and the skill will reference it by URL.
- No bulk-GTIN readiness scan. Agents auditing dozens of GTINs
have to fan out queries. A bulk endpoint
(
POST /compliance/api/v1/fsma204-readiness/scantaking a GTIN list) is planned for the FSMA dashboard refactor. - Trading-partner KDE coverage is not enforced. The audit assumes
SHIP/RECEIVECTEs already have a resolvedTradingPartnerdestination; if the event captured but the partner GLN couldn’t be resolved, the CTE row exists withtrading_partner=NULLand is silently 100% on the KDE rubric. A separate “trading-partner resolution” health check is filed. - No historical-snapshot scoring. The audit is point-in-time (current state of the ledger). FSMA 204 § 1.1455(c) responses require historical snapshots (“what KDEs did you have on date X”), which is reconstructable from the immutable event ledger but not yet surfaced as a first-class query.
Related skills
capture-epcis-event— the corrective-action surface; agents capture missing-KDE events to close gaps surfaced by this audit.query-epcis-events— the underlying read used by this audit until the dedicated endpoint ships.manage-recall— pre-recall sanity check; only issue recalls on lots whose readiness score is high enough to compose a defensible FDA Sortable Spreadsheet.check-recalls— consumer side of recalls; orthogonal to readiness but reads the same CTE ledger.