Organize a catalog with Collections
Model navigation as one graph
Collections describe navigation relationships, not a required storage model. One catalog graph can contain root Collections, single-parent branches, and Collections that appear beneath multiple parents. Use only the relationships that create useful browse paths.
- Root Collections: omit parent_ids and provide the starting points for browsing the catalog
- Single-parent branches: name one direct parent when a Collection belongs in one broader path
- Multiple-parent branches: name more than one direct parent when the same Collection belongs naturally in several browse paths
A Service can change its navigation design without changing the meaning or identity of the Offerings being organized. Collection membership and Collection hierarchy remain separate relationships.
Describe a Collection
A Full Collection contains odp_version, id, and name. Optional fields add description, imagery, language, browser navigation, hierarchy, and Collection-scoped search capabilities.
{
"odp_version": "1.0",
"id": "research-tools",
"name": "Research tools",
"description": "Tools for finding and analyzing information.",
"images": [
{
"src": "/images/collections/research-tools.png",
"alt": "Research tools"
}
],
"parent_ids": [
"developer-tools"
],
"web_url": "/collections/research-tools"
}A list or search response can return a terse form containing only id, name, and other useful summary fields. Retrieve the Collection individually when its full metadata is needed.
The first image is the primary image, and web_url identifies an optional human-facing browser experience. Neither field changes the Collection's ODP identity.
Model hierarchy as a graph
parent_ids contains the direct parents of a Collection. Omitting it identifies a root Collection. Multiple roots and multiple parents are valid, so Agents treat the hierarchy as a directed acyclic graph rather than assuming one tree.
{
"odp_version": "1.0",
"items": [
{
"id": "business-tools",
"name": "Business tools"
},
{
"id": "developer-tools",
"name": "Developer tools"
},
{
"id": "research-tools",
"name": "Research tools",
"parent_ids": [
"business-tools",
"developer-tools"
]
}
]
}In this example, business-tools and developer-tools are roots. research-tools appears beneath both browse paths while remaining one Collection with one Resource Identity.
- Roots: omit parent_ids; do not serialize an empty array
- Parents: publish only direct parent identifiers that resolve under the same access context
- Children: discover direct children through Collection search because ODP has no child_ids field
- Depth: keep every path through successive parents within 32 edges
An Agent ignores an edge that creates a cycle, exceeds the depth limit, names the current Collection, or names a missing Collection. That edge does not invalidate unrelated Collections, Offering memberships, or operations.
Connect Offerings through direct membership
An Offering's collection_ids lists the Collections in which it is a direct member. An Offering can belong to no Collection, one Collection, or several Collections.
The list-collection-offerings operation must return the Offerings that directly name the Collection in collection_ids for the same authentication context. Membership in a child Collection does not imply membership in its ancestors.
An Agent ignores an unresolved membership identifier without discarding the Offering or its other memberships. See Offerings for the rest of the Offering representation.
Choose the Collection operation
| Goal | Operation | Result |
|---|---|---|
| Traverse Collections | list-collections | The complete accessible Collection sequence without a search constraint. |
| Retrieve one Collection | get-collection | The Collection identified by its local resource identifier. |
| Find Collections | search-collections | Collections matching text, a hierarchy constraint, or both. |
| Browse direct members | list-collection-offerings | Offerings whose collection_ids contains the named Collection. |
| Traverse all Offerings | list-offerings | Every accessible Offering without inventing an all-Offerings Collection. |
Search text and hierarchy
Collection search requires query, parent_id, or both. A JSON null parent selects root Collections; an identifier selects its direct children. Omitting parent_id applies no hierarchy constraint.
{
"odp_version": "1.0",
"query": "research",
"parent_id": "developer-tools"
}The example returns direct children of developer-tools that also match the Service-interpreted text query. ODP does not standardize text matching, tokenization, case folding, or relevance.
Find the roots
Follow one level
Track visited Collections
ODP 1.0 does not define client-selected Collection sorting. The Service chooses a stable sequence, and the Agent preserves it unless its own caller explicitly requests local presentation ordering.
Use List Offerings for the complete catalog
Use list-offerings to retrieve the complete accessible Offering sequence. ODP does not require an artificial Collection containing every Offering, although a Service can publish a similar Collection when it has a real business meaning.
Next steps
Describe individual Offerings
Define the resources that an Agent evaluates, retrieves, and acts upon.
OfferingsConstruct constrained searches
Use text, advertised filters, sort recipes, and refinements correctly.
Search and filtering