These endpoints return the items inside each Bill of Materials across your tenant: technologies, models, datasets, infrastructure and agentic systems. Use them to sync the contents of your Bills of Materials into your own systems without the Application UI.
Syncing Bill of Materials Items
All five feeds share the same authentication, permission, query parameters, pagination and sync rules. This section states them once. The sections that follow give the request, fields and a sample response for each feed.
Authentication
Bearer token. See Authentication & Generating Credentials.
Required Permission
Api_BOM_Read. This is the same permission used by List Bills of Materials.
Query Parameters
Parameter | Type | Value |
|---|---|---|
| GUID | Optional. Limits the feed to one Bill of Materials. Omit it to read items across all your Bills of Materials. An unknown id, or one in another tenant, returns an empty page rather than a 404. |
| integer | Results per page. Default 100. Maximum 1,000. A higher value is rejected, not reduced to 1,000. A value of 0 or less is treated as the default of 100. |
| string | Sync cursor. Omit on the first call to begin from the beginning. Pass |
| ISO 8601 timestamp | Return only records updated at or after this timestamp. Use to recover a lost cursor or reset to a known point in time. Cannot be sent together with |
These feeds are cursor-paginated. The page parameter is not supported.
Pagination
Every response uses the same envelope.
Field | Type | Rules |
|---|---|---|
| array | The records on this page. |
| string | Cursor to send as |
| boolean |
|
| integer | The page size you requested. Present only when |
| object or null | Null on success. On failure, holds |
| object |
|
hasMore: false with a non-null nextCursor is the normal end-of-feed state. Keep the last nextCursor and send it on your next sync. That call returns only items added or changed since.
Keeping a Complete Copy
The cursor returns new and changed items. Three cases need extra handling.
- Removed items are not reported. An item removed from a Bill of Materials does not appear in the feed again. Re-read each feed periodically without a cursor and treat items missing from that full read as removed.
- Changed agentic systems get a new id. A rescan that changes an agentic system replaces it under a new
agenticSystemId. The old id is not reported as removed. The periodic full read also catches these. - Late records can fall behind the cursor. Records saved late by a scan can appear behind a cursor already returned. For a complete incremental sync, use
updatedAfterset a few minutes before the lastupdatedAtyou received.
updatedAt on every feed is UTC, even though it is written without a trailing Z.
List Technologies
Returns the software packages and dependencies found in your Bills of Materials, with an AI label on each.
Request
GET /api/public/billofmaterials/technologies
Response Fields
Field | Type | Rules |
|---|---|---|
| GUID | Identifier for the technology record. |
| GUID | Bill of Materials the technology belongs to. Correlates with the Bills of Materials endpoint. |
| string | Package name. |
| string | Package version. |
| array of string | Languages the package was detected in, for example |
| string |
|
| integer or null | Depth of the dependency. |
| string or null | Dependency group the package was declared in, for example |
| boolean or null |
|
| string | How the scan detected the technology, for example |
| array of string | Files where the technology was found. |
| timestamp (UTC) | The field the sync cursor and |
Sample Response
{"data": [{"billOfMaterialsItemId": "3f6c2a1e-8b4d-4c2a-9e51-0d7a6b2c4f10","billOfMaterialsId": "a1b2c3d4-5e6f-4a1b-8c9d-0e1f2a3b4c5d","name": "langchain","version": "0.2.16","language": ["python"],"dependencyType": "Direct","dependencyDepth": 1,"dependencyGroup": "main","isAi": true,"source": "requirements","filePath": ["services/agent/requirements.txt"],"updatedAt": "2026-10-20T14:32:07.113226"},{"billOfMaterialsItemId": "9d0e4b7a-2c31-4f8e-b6a2-5e1c7d9f0a32","billOfMaterialsId": "a1b2c3d4-5e6f-4a1b-8c9d-0e1f2a3b4c5d","name": "urllib3","version": "2.2.3","language": ["python"],"dependencyType": "Transitive","dependencyDepth": 3,"dependencyGroup": null,"isAi": false,"source": "requirements","filePath": ["services/agent/requirements.txt"],"updatedAt": "2026-10-20T14:32:07.113226"}],"pagination": {"limit": 2,"nextCursor": "eyJ1cGRhdGVkQXQiOiIyMDI2LTEwLTIwVDE0OjMyOjA3LjExMzIyNjAiLCJpZCI6IjlkMGU0YjdhLTJjMzEtNGY4ZS1iNmEyLTVlMWM3ZDlmMGEzMiJ9","hasMore": true},"error": null,"meta": {"requestId": "6b2f0c4e-1d3a-4f7b-9c8e-2a5d1e0f3b47","timestamp": "2026-10-22T15:04:11.5720000Z"}}
This sample was requested with limit=2. langchain is a direct dependency on Cranium's AI package list. urllib3 is a transitive dependency that is not.
List Models
Returns the AI models found in your Bills of Materials, with Cranium's confidence in each detection and a link to Cranium Arena when the model has a match there.
Request
GET /api/public/billofmaterials/models
Response Fields
Field | Type | Rules |
|---|---|---|
| GUID | Identifier for the model record. |
| GUID | Bill of Materials the model belongs to. Correlates with the Bills of Materials endpoint. |
| string | Model name as found in the code. |
| string | Standardized model name, for example |
| string | Cranium's confidence in the detection. One of |
| string | One of |
| string | How the scan detected the model, for example |
| string | Link to the model's reference page. |
| array of string | Files where the model was found. |
| GUID or null | Joins to |
| timestamp (UTC) | The field the sync cursor and |
Sample Response
{"data": [{"billOfMaterialsItemId": "c4a7e2f1-6b3d-4e9a-8f2c-1d5b7a9e3c60","billOfMaterialsId": "a1b2c3d4-5e6f-4a1b-8c9d-0e1f2a3b4c5d","name": "gpt-4o","standardizedName": "gpt-4o","confidenceLevel": "high","modelType": "GenAI","source": "llm","referenceUrl": "https://platform.openai.com/docs/models/gpt-4o","filePath": ["services/agent/llm_client.py"],"arenaModelId": "7e1d9c3b-2a4f-4b8e-9d6c-5f0a1b2c3d4e","updatedAt": "2026-10-20T14:32:07.113226"},{"billOfMaterialsItemId": "e8b3d1c9-4f2a-4a6e-b7d5-3c9e1f0a2b81","billOfMaterialsId": "a1b2c3d4-5e6f-4a1b-8c9d-0e1f2a3b4c5d","name": "sentence-transformers/all-MiniLM-L6-v2","standardizedName": "all-MiniLM-L6-v2","confidenceLevel": "medium","modelType": "DL","source": "llm","referenceUrl": "https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2","filePath": ["services/search/embeddings.py"],"arenaModelId": null,"updatedAt": "2026-10-20T14:32:07.113226"}],"pagination": {"limit": 2,"nextCursor": "eyJ1cGRhdGVkQXQiOiIyMDI2LTEwLTIwVDE0OjMyOjA3LjExMzIyNjAiLCJpZCI6ImU4YjNkMWM5LTRmMmEtNGE2ZS1iN2Q1LTNjOWUxZjBhMmI4MSJ9","hasMore": true},"error": null,"meta": {"requestId": "0f3a9b2c-7e4d-4c1a-8b5f-6d2e9a1c0b38","timestamp": "2026-10-22T15:04:12.0410000Z"}}
gpt-4o has an Arena match, so arenaModelId is set. The second model has no Arena match, so arenaModelId is null.
List Datasets
Returns the datasets found in your Bills of Materials.
Request
GET /api/public/billofmaterials/datasets
Response Fields
Field | Type | Rules |
|---|---|---|
| GUID | Identifier for the dataset record. |
| GUID | Bill of Materials the dataset belongs to. Correlates with the Bills of Materials endpoint. |
| string | Dataset name. |
| string or null | Description of the dataset. |
| string | How the scan detected the dataset, for example |
| array of string | Files where the dataset was found. |
| timestamp (UTC) | The field the sync cursor and |
Sample Response
This sample reads one Bill of Materials with billOfMaterialsId and no limit, so pagination has no limit field.
{"data": [{"billOfMaterialsItemId": "5a2c8e1f-3b7d-4f9a-a6c4-2e8d0b1f7c93","billOfMaterialsId": "a1b2c3d4-5e6f-4a1b-8c9d-0e1f2a3b4c5d","name": "customer_support_transcripts","description": "Support conversation transcripts used to fine-tune the triage classifier.","source": "llm","filePath": ["training/prepare_dataset.py", "training/config.yaml"],"updatedAt": "2026-10-20T14:32:07.113226"}],"pagination": {"nextCursor": "eyJ1cGRhdGVkQXQiOiIyMDI2LTEwLTIwVDE0OjMyOjA3LjExMzIyNjAiLCJpZCI6IjVhMmM4ZTFmLTNiN2QtNGY5YS1hNmM0LTJlOGQwYjFmN2M5MyJ9","hasMore": false},"error": null,"meta": {"requestId": "d7c1e4a9-2b6f-4e3d-8a0c-9f5b1d2e7a64","timestamp": "2026-10-22T15:04:12.6930000Z"}}
List Infrastructure
Returns the infrastructure components found in your Bills of Materials, such as hosted model endpoints.
Request
GET /api/public/billofmaterials/infrastructure
Response Fields
Field | Type | Rules |
|---|---|---|
| GUID | Identifier for the infrastructure record. |
| GUID | Bill of Materials the component belongs to. Correlates with the Bills of Materials endpoint. |
| string | Component name. |
| string or null | Description of the component. |
| string | How the scan detected the component, for example |
| array of string | Files where the component was found. |
| timestamp (UTC) | The field the sync cursor and |
Sample Response
{"data": [{"billOfMaterialsItemId": "b6e0f3a2-9c4d-4b1e-8f7a-0d3c5e2a9b15","billOfMaterialsId": "a1b2c3d4-5e6f-4a1b-8c9d-0e1f2a3b4c5d","name": "Azure OpenAI","description": "Hosted model endpoint used for completions in the agent service.","source": "llm","filePath": ["infra/main.bicep"],"updatedAt": "2026-10-20T14:32:07.113226"}],"pagination": {"limit": 1,"nextCursor": "eyJ1cGRhdGVkQXQiOiIyMDI2LTEwLTIwVDE0OjMyOjA3LjExMzIyNjAiLCJpZCI6ImI2ZTBmM2EyLTljNGQtNGIxZS04ZjdhLTBkM2M1ZTJhOWIxNSJ9","hasMore": true},"error": null,"meta": {"requestId": "8a4d2f6b-1c9e-4a7d-b3f0-5e2c8d1a6b79","timestamp": "2026-10-22T15:04:13.2210000Z"}}
List Agentic Systems
Returns the agentic systems found in your Bills of Materials. Each record is one agentic system. Its agents and the relations between them are nested inside the record, not returned as separate records.
A rescan that changes an agentic system replaces it under a new agenticSystemId, and the old id is not reported as removed. See Keeping a Complete Copy above.
Request
GET /api/public/billofmaterials/agenticsystems
Response Fields
Field | Type | Rules |
|---|---|---|
| GUID | Identifier for the agentic system. Changes when a rescan changes the system. |
| GUID | Bill of Materials the agentic system belongs to. Correlates with the Bills of Materials endpoint. |
| string | Agentic system name. |
| string | Agent framework the system is built on, for example |
| array of object | Agents in the system. See Agent Fields. |
| array of object | Connections between agents and the tools they use. See Relation Fields. |
| timestamp (UTC) | The field the sync cursor and |
Agent Fields
Field | Type | Rules |
|---|---|---|
| GUID | Identifier for the agent. |
| string | Agent name. |
| string or null | Model the agent uses. |
| string or null | Description of the agent. |
| string or null | Instructions given to the agent. |
| array of string | Names of the tools the agent can call. |
| array of string | Names of the agents this agent can hand off to. |
| array of string | Names of the guardrails applied to the agent's input. |
| array of string | Names of the guardrails applied to the agent's output. |
| array of string | Names of the MCP servers the agent connects to. |
| array of string | Files where the agent was found. |
| string | How the scan detected the agent, for example |
| string | Language the agent is written in, for example |
Relation Fields
Field | Type | Rules |
|---|---|---|
| string | Kind of relation, for example |
| object | Where the relation starts. Holds |
| object | Where the relation ends. Holds |
Sample Response
{"data": [{"agenticSystemId": "2d9f7b1c-4e6a-4c3b-a8d2-7f1e0c5b9a46","billOfMaterialsId": "a1b2c3d4-5e6f-4a1b-8c9d-0e1f2a3b4c5d","name": "Support triage","framework": "openai-agents","agents": [{"agentId": "6c1e8a3f-2b9d-4f5a-b7e0-3d4c9a1f8e52","name": "Triage Agent","model": "gpt-4o","description": "Routes customer requests to the right specialist.","instructions": "Classify the request and hand off to the billing or technical agent.","tools": ["lookup_account"],"handoffs": ["Billing Agent", "Technical Agent"],"inputGuardrails": ["pii_filter"],"outputGuardrails": [],"mcpServers": [],"filePath": ["services/agent/triage.py"],"source": "deterministic_ast","language": "python"},{"agentId": "f4b2d9e6-7a1c-4e8b-9c3d-0a5f2e7b1c68","name": "Billing Agent","model": "gpt-4o-mini","description": "Answers billing questions.","instructions": "Answer billing questions using the account tools.","tools": ["lookup_invoice", "issue_refund"],"handoffs": [],"inputGuardrails": [],"outputGuardrails": [],"mcpServers": ["billing-mcp"],"filePath": ["services/agent/billing.py"],"source": "deterministic_ast","language": "python"}],"relations": [{"type": "handoff","source": { "type": "agent", "content": "Triage Agent" },"destination": { "type": "agent", "content": "Billing Agent" }},{"type": "tool","source": { "type": "agent", "content": "Billing Agent" },"destination": { "type": "tool", "content": "issue_refund" }}],"updatedAt": "2026-10-20T14:32:07.113226"}],"pagination": {"limit": 1,"nextCursor": "eyJ1cGRhdGVkQXQiOiIyMDI2LTEwLTIwVDE0OjMyOjA3LjExMzIyNjAiLCJpZCI6IjJkOWY3YjFjLTRlNmEtNGMzYi1hOGQyLTdmMWUwYzViOWE0NiJ9","hasMore": false},"error": null,"meta": {"requestId": "3e7b0d5a-9f2c-4d6e-a1b8-4c0f7e2d9a13","timestamp": "2026-10-22T15:04:13.8050000Z"}}
Error Responses
All five feeds return the same errors.
400 BAD_REQUEST: the request was rejected. Themessagesays why.limit must be 1000 or less.cursor and updatedAfter are mutually exclusive.page is not supported; this feed is cursor-paginated.Invalid cursor value.The cursor is malformed, or it was issued for another feed or anotherbillOfMaterialsId.
401 UNAUTHORIZED: the request is missing a token, or the token lacksApi_BOM_Read.500 INTERNAL_ERROR: an unexpected server error.
{
"data": null,
"pagination": null,
"error": {
"code": "BAD_REQUEST",
"message": "limit must be 1000 or less.",
"traceId": "0HNOVC2K1R7QD:00000001"
},
"meta": {
"requestId": "c2e7a1d4-8b3f-4e6a-9d0c-5f1b2a7e4c83",
"timestamp": "2026-10-22T15:04:15.4470000Z"
}
}
Every error response includes error.traceId. Include it when reporting an issue to Cranium support.





