Certification Intelligence
Find, file, renew, and complete certification records with validity dates and supporting files tied to the right business record.
Certification Intelligence connects discovery with certificate maintenance:
GET /certification-typeslists the organization's certification vocabulary.GET /certification-recordsfinds individual stored records.GET /certification-records/{recordId}returns one exact record.GET /certification-subjectsfinds customers, suppliers, products, customer addresses, warehouses, and supplier-product combinations with matching records.POST /certification-recordsfiles a certification record.PATCH /certification-records/{recordId}renews, reactivates, or completes a selected record.
Access
The read endpoints require certifications:read plus the acting user's current access to the related customer, supplier, product, customer address, or supplier-product combination. Warehouse certification results also require warehouses:read and current Warehouse access. GET /me reports effectiveCapabilities.certifications.view and the available viewableSubjectTypes.
Filing, renewal, and pending-record completion use certifications:write with current subject viewing and edit access. See the File a certificate section below for the complete write requirements and examples.
curl "$SHELFCYCLE_API_BASE_URL/certification-types?subjectType=supplier" \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
-H "X-ShelfCycle-Client: Supplier quality workspace"
Learn the organization's vocabulary
Use GET /certification-types before a broad search when the workflow needs the exact type title or ID used by the organization.
{
"data": [
{
"id": "certification-type-id",
"title": "Third Party Audit",
"description": "Annual third-party quality audit",
"enabled": true,
"documentationRequired": true,
"expiryNoticeDaysBefore": 30,
"subjectType": "supplier",
"type": "certification_type"
}
],
"meta": {
"populationCount": 8,
"returnedRecords": 1,
"complete": true,
"hasMore": false,
"nextCursor": null,
"evaluatedAt": "2026-08-24T16:30:00.000Z",
"requestId": "request-id"
}
}
Filter by subjectType using supplier, customer, product, customer_address, warehouse, or supplier_combination. Add includeDisabled=true only when the workflow needs historical type configuration. expiryNoticeDaysBefore supplies the notice window used to determine when a record is expiring.
Find stored records
Use GET /certification-records to search individual certification rows. Common filters include:
| Filter | Use it for |
|---|---|
typeId or typeQuery | One exact certification type or matching type title and description. |
subjectTypes and subjectId | One or more business record classes, or one exact business record. |
recordedStatuses | Recorded PENDING, ACTIVE, or EXPIRED values. |
effectiveStates | Current interpretation at the response's exact evaluation time: pending, current, expired, or incomplete. |
renewalStates | Renewal timing at the same evaluation time: current, expiring, expired, renewed, or not_tracked. |
expiresAtOrAfter and expiresAtOrBefore | Exact date-time boundaries for expiration review. |
evidenceRecordedState | recorded, not_recorded, or invalid_metadata. |
evidenceFileNameQuery | An explicit filename search when the source wording points to a recorded filename. |
curl "$SHELFCYCLE_API_BASE_URL/certification-records?subjectTypes=supplier&subjectId=supplier-id&effectiveStates=current&limit=25" \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY"
{
"data": [
{
"recordId": "certification-record-id",
"resourceKind": "stored_certification_record",
"type": {
"id": "certification-type-id",
"title": "Third Party Audit",
"description": "Annual third-party quality audit",
"enabled": true,
"documentationRequired": true,
"expiryNoticeDaysBefore": 30,
"subjectType": "supplier"
},
"subject": {
"subjectType": "supplier",
"id": "supplier-id",
"displayName": "Northstar Chemical",
"externalId": "SUP-1042",
"archived": false,
"customerId": null,
"locationId": null,
"addressId": null
},
"recordedStatus": "ACTIVE",
"effectiveState": "current",
"renewalState": "expiring",
"daysLeft": 24,
"validFrom": "2026-01-01T00:00:00.000Z",
"validTo": "2026-12-31T23:59:59.000Z",
"recordCompleteness": "populated",
"evidence": {
"recordedState": "recorded",
"fileName": "northstar-third-party-audit-2026.pdf"
},
"matchBasis": ["unfiltered"],
"searchedFields": [],
"createdAt": "2026-01-02T14:00:00.000Z",
"updatedAt": "2026-01-02T14:00:00.000Z"
}
],
"meta": {
"populationCount": 1,
"returnedRecords": 1,
"complete": true,
"hasMore": false,
"nextCursor": null,
"evaluatedAt": "2026-08-24T16:30:00.000Z",
"currentState": true,
"snapshotIsolatedAcrossRequests": false,
"requestId": "request-id"
}
}
recordedStatus preserves the status stored on the record. effectiveState interprets the record at the exact meta.evaluatedAt time, including its expiration boundary. validFrom remains informational record context.
renewalState applies the certification type's expiryNoticeDaysBefore setting at the same evaluation time. daysLeft is the number of organization-calendar days until expiration. A past record reports renewed when a current certification of the same type exists for the same subject.
The evidence object reports whether a filename was recorded and returns that filename when available. Use it as stored record context. The certification endpoints do not return file links or file contents.
Certification results describe records stored in ShelfCycle. Present them as the organization's recorded certification information, with the returned status, dates, and evidence filename.
Find subjects with matching records
Use GET /certification-subjects when the workflow needs a customer, supplier, product, customer-address, warehouse, or supplier-product-combination view rather than one result per certification record. It accepts the same record filters and returns each available subject once.
curl "$SHELFCYCLE_API_BASE_URL/certification-subjects?typeQuery=Third%20Party%20Audit&effectiveStates=current&subjectTypes=supplier" \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY"
Each row includes matchingRecordCount, currentMatchingRecordCount, and latestCurrentValidTo. Use those returned counts directly when building summaries.
Warehouse subjects carry the warehouse identity. A supplier_combination subject carries a combination object with shipFromLocationId, shipFromLocationName, productId, and productDisplayName, so a workflow can keep the certification tied to the exact supplier origin and product.
For an exact subject question, first request that subject without a type or text filter to understand the complete visible record set. Then apply the requested type or date filters. This keeps a filtered zero result clearly tied to the selected subject and filter.
Inspect one exact record
After selecting a recordId, use GET /certification-records/{recordId} for the exact stored row:
curl "$SHELFCYCLE_API_BASE_URL/certification-records/certification-record-id" \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY"
The detail response uses the same type, subject, status, date, completeness, and evidence fields as the list row.
Continue and refresh
For certificate filing and renewal, use the write flow below after resolving the certification type and exact subject.
When meta.hasMore is true, call the same collection endpoint again with meta.nextCursor by itself. Do not combine a cursor with the original filters.
Certification records are read one page at a time. meta.populationCount and coverage.totalRecords are available only when the first page contains the complete matching result. Use returnedRecords, hasMore, and nextCursor for continued traversal.
Certification responses include meta.evaluatedAt, currentState: true, and snapshotIsolatedAcrossRequests: false. A continued traversal keeps its evaluation time for consistent effective-state interpretation. Restart from the original filters for a new current view.
File a certificate
Certificate writes require certifications:write, current viewing access to the subject, and permission to edit that subject. Supplier certificates use Supplier update permission; customers and customer addresses use Customer update; products use Product update. Supplier-product combinations require Supplier update and Product viewing access. Warehouse certificates additionally require warehouses:read, warehouses:write, and current Warehouse access.
Check GET /me for effectiveCapabilities.certifications.records.create, update, and writableSubjectTypes. Use an enabled certification type that matches the subject type.
Upload a PDF, PNG, JPEG, or WebP through POST /document-uploads with documents:upload, send the file using the returned upload values, then copy the returned data.document into the request. See Attached documents for the upload steps. A supporting document is required when the type's documentationRequired is true; otherwise it can be omitted. Replace the example document below with the descriptor from your completed upload.
Send validFrom and validTo as real YYYY-MM-DD calendar days in the organization's timezone. The API stores the start of each selected day and returns date-time values on reads. A record stops being valid at the start of its validTo day; choose that boundary deliberately. A past validTo is refused.
curl "$SHELFCYCLE_API_BASE_URL/certification-records" \
-X POST \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"certificationTypeId": "certification-type-id",
"subject": { "subjectType": "supplier", "id": "supplier-id" },
"validFrom": "2026-10-14",
"validTo": "2027-10-14",
"document": {
"fileName": "supplier-certification.pdf",
"url": "<returned data.document.url>"
}
}'
Subjects can be supplier, customer, customer_address, product, warehouse, or supplier_combination. For a combination, id is the supplier ID and the subject also includes the exact ship-from location and product:
{
"subjectType": "supplier_combination",
"id": "supplier-id",
"combination": {
"shipFromLocationId": "ship-from-location-id",
"productId": "product-id"
}
}
POST returns 201 with status: "created". Repeating the same validity days and document returns 200 with status: "unchanged". If a different record already exists for that type and subject, 409 certification_record_exists includes impactAnalysis.existingRecordIds; read the selected record and update it through PATCH. This flow uses the saved record for safe repeats and does not require Idempotency-Key.
Renew or complete a record
Read GET /certification-records/{recordId} with certifications:read to obtain the latest updatedAt. Send that value as If-Match, then PATCH at least one of validFrom, validTo, or document. Omitted fields retain their values; the combined dates and document must form an active certificate. This same operation can fill a pending placeholder, renew or reactivate an expired record, or correct dates.
curl "$SHELFCYCLE_API_BASE_URL/certification-records/certification-record-id" \
-X PATCH \
-H "Authorization: Bearer $SHELFCYCLE_API_KEY" \
-H "Content-Type: application/json" \
-H "If-Match: 2026-10-14T14:00:00.000Z" \
-d '{
"validFrom": "2026-10-14",
"validTo": "2027-10-14",
"document": {
"fileName": "renewed-certification.pdf",
"url": "<returned data.document.url>"
}
}'
A missing or outdated If-Match returns 409 stale_record when the request changes the record. Read again and review the current values before retrying. An exact request that changes nothing returns 200 unchanged, even without that header. Successful writes return the record detail, its status, and a verification GET path. Responses report the evidence filename without returning a file URL.
Preview and recover
Add ?dryRun=true to POST or PATCH to preview the exact request. PATCH previews use the record's current If-Match when changing it. Check data.status and the returned checks before applying the request without dryRun=true.
The readiness operations are certification_records.create and certification_records.update. A blocked preview reports the same correction code, parameter, and message used by the applied request. For an impossible calendar date, fix the named validFrom or validTo; for a rejected file, send a fresh supported upload descriptor; for invalid_combination, correct the selected ship-from location or product.
Use the returned verification.path with certification read access for readback. For a batch of incoming files, process each file separately, record its outcome, and resume using the same intended dates and document.