# Doc Store / Collections

## List all collections

> Returns a list of all document collections with their IDs and names. Collections are returned in no particular order. Use this to discover available collections before querying documents.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}}},"paths":{"/sfp/api/doc-store/collections":{"get":{"operationId":"DocStoreCollectionsController_listCollections","summary":"List all collections","description":"Returns a list of all document collections with their IDs and names. Collections are returned in no particular order. Use this to discover available collections before querying documents.","parameters":[],"responses":{"200":{"description":"The list of collections has been successfully retrieved."},"403":{"description":"Forbidden - Requires role: member, application"}},"tags":["Doc Store / Collections"]}}}}
```

## Create a new collection

> Creates a new document collection with the specified name. Collections are logical groupings of related documents. Returns a unique collection ID. Fails if a collection with the same name already exists.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}}},"paths":{"/sfp/api/doc-store/collections":{"post":{"operationId":"DocStoreCollectionsController_createCollection","summary":"Create a new collection","description":"Creates a new document collection with the specified name. Collections are logical groupings of related documents. Returns a unique collection ID. Fails if a collection with the same name already exists.","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"}}}}}},"responses":{"200":{"description":"The collection has been successfully created."},"403":{"description":"Forbidden - Requires role: member, application"},"409":{"description":"The collection already exists."}},"tags":["Doc Store / Collections"]}}}}
```

## Get a specific collection including all documents

> Retrieves a collection by name along with all documents it contains. This can be expensive for large collections. Consider using the query endpoint with pagination for better performance on large datasets. Use store=changelog to retrieve from the dedicated changelog table.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}}},"paths":{"/sfp/api/doc-store/collections/{collectionName}":{"get":{"operationId":"DocStoreCollectionsController_getCollection","summary":"Get a specific collection including all documents","description":"Retrieves a collection by name along with all documents it contains. This can be expensive for large collections. Consider using the query endpoint with pagination for better performance on large datasets. Use store=changelog to retrieve from the dedicated changelog table.","parameters":[{"name":"store","required":false,"in":"query","description":"Target store for the collection. Defaults to \"doc\" for backward compatibility.","schema":{"enum":["doc","changelog","packages","builds"],"type":"string"}},{"name":"collectionName","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The collection and its documents have been successfully retrieved."},"403":{"description":"Forbidden - Requires role: member, application"},"404":{"description":"The collection was not found."}},"tags":["Doc Store / Collections"]}}}}
```

## Delete an entire collection

> Permanently deletes an entire collection and all its documents. This destructive operation:\
> &#x20;       \- Removes the collection and ALL documents within it\
> &#x20;       \- Cannot be undone - all data is permanently lost\
> &#x20;       \- Frees up the collection name for reuse\
> \
> &#x20;       Use with extreme caution. Consider backing up important data before deletion. This endpoint requires elevated privileges.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}}},"paths":{"/sfp/api/doc-store/collections/{collectionName}":{"delete":{"operationId":"DocStoreCollectionsController_deleteCollection","summary":"Delete an entire collection","description":"Permanently deletes an entire collection and all its documents. This destructive operation:\n        - Removes the collection and ALL documents within it\n        - Cannot be undone - all data is permanently lost\n        - Frees up the collection name for reuse\n\n        Use with extreme caution. Consider backing up important data before deletion. This endpoint requires elevated privileges.","parameters":[{"name":"collectionName","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":"The collection has been successfully deleted."},"403":{"description":"Forbidden - Requires role: owner, application"},"404":{"description":"The collection was not found."}},"tags":["Doc Store / Collections"]}}}}
```

## Query documents in a collection (DEPRECATED)

> \*\*DEPRECATED\*\*: This endpoint has issues with nested collection names (e.g., 'org/repo/collection').\
> &#x20;       Please use the cross-collection query endpoint at POST /doc-store/collections/query with pathPattern instead.\
> \
> &#x20;       Executes advanced queries against documents in a specific collection. Features include:\
> &#x20;       \- Complex filtering with multiple operators (eq, ne, gt, lt, gte, lte, in, nin, regex)\
> &#x20;       \- Nested field queries using dot notation (e.g., 'user.email')\
> &#x20;       \- Sorting by multiple fields with ascending/descending order\
> &#x20;       \- Pagination support with limit and offset\
> &#x20;       \- Field projection to return only specific fields\
> \
> &#x20;       This is the recommended way to retrieve documents when you need specific filtering or working with large collections.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"QueryOptionsDto":{"type":"object","properties":{"filters":{"description":"Array of filters to apply","type":"array","items":{"$ref":"#/components/schemas/QueryFilterDto"}},"orderBy":{"description":"Array of sort orders to apply","type":"array","items":{"$ref":"#/components/schemas/OrderByDto"}},"limit":{"type":"number","description":"Maximum number of results to return"},"offset":{"type":"number","description":"Number of results to skip"}}},"QueryFilterDto":{"type":"object","properties":{"field":{"type":"string","description":"Field to filter on"},"operator":{"type":"string","enum":["eq","neq","contains","hasKey","in","gt","gte","lt","lte","like","nlike","isNull"],"description":"Operator to use for filtering"},"value":{"type":"object","description":"Value to filter by (can be null for hasKey operator)"}},"required":["field","operator"]},"OrderByDto":{"type":"object","properties":{"field":{"type":"string","description":"Field to order by"},"ascending":{"type":"boolean","description":"Sort order direction","default":true}},"required":["field"]},"QueryResultDto":{"type":"object","properties":{"collection":{"type":"string","description":"Collection name"},"key":{"type":"string","description":"Document key"},"value":{"type":"object","description":"Document value"},"version":{"type":"number","description":"Document version"}},"required":["collection","key","value","version"]}}},"paths":{"/sfp/api/doc-store/collections/{collectionName}/query":{"post":{"operationId":"DocStoreCollectionsController_queryDocuments","summary":"Query documents in a collection (DEPRECATED)","description":"**DEPRECATED**: This endpoint has issues with nested collection names (e.g., 'org/repo/collection').\n        Please use the cross-collection query endpoint at POST /doc-store/collections/query with pathPattern instead.\n\n        Executes advanced queries against documents in a specific collection. Features include:\n        - Complex filtering with multiple operators (eq, ne, gt, lt, gte, lte, in, nin, regex)\n        - Nested field queries using dot notation (e.g., 'user.email')\n        - Sorting by multiple fields with ascending/descending order\n        - Pagination support with limit and offset\n        - Field projection to return only specific fields\n\n        This is the recommended way to retrieve documents when you need specific filtering or working with large collections.","deprecated":true,"parameters":[{"name":"collectionName","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueryOptionsDto"}}}},"responses":{"200":{"description":"Query executed successfully.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QueryResultDto"}}}}},"403":{"description":"Forbidden - Requires role: member, application"}},"tags":["Doc Store / Collections"]}}}}
```

## Query documents across collections (RECOMMENDED)

> Executes queries across multiple collections using path patterns. This powerful endpoint allows:\
> &#x20;       \- Querying single collections by exact path (e.g., 'org/repo/builds-v2')\
> &#x20;       \- Wildcard patterns to match multiple collections (e.g., 'repo\_\*/metadata')\
> &#x20;       \- Cross-collection queries for impact analysis and health checks\
> &#x20;       \- All standard query features (filtering, sorting, pagination)\
> &#x20;       \- Properly handles nested collection names with slashes\
> &#x20;       \- Use store=changelog to query the dedicated changelog table\
> \
> &#x20;       \*\*This is the recommended endpoint for all collection queries\*\*, as it correctly handles nested collection paths.\
> \
> &#x20;       Common use cases:\
> &#x20;       \- Query specific collections with nested names (e.g., 'flxbl-io/sf-core/builds-v2')\
> &#x20;       \- Find all metadata across repositories\
> &#x20;       \- Search for specific configurations across environments\
> &#x20;       \- Aggregate data from multiple sources

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}},"schemas":{"PathQueryOptionsDto":{"type":"object","properties":{"filters":{"description":"Array of filters to apply","type":"array","items":{"$ref":"#/components/schemas/QueryFilterDto"}},"orderBy":{"description":"Array of sort orders to apply","type":"array","items":{"$ref":"#/components/schemas/OrderByDto"}},"limit":{"type":"number","description":"Maximum number of results to return"},"offset":{"type":"number","description":"Number of results to skip"},"pathPattern":{"type":"string","description":"Collection path pattern to match"},"recursive":{"type":"boolean","description":"Include sub-collections in search","default":false}}},"QueryFilterDto":{"type":"object","properties":{"field":{"type":"string","description":"Field to filter on"},"operator":{"type":"string","enum":["eq","neq","contains","hasKey","in","gt","gte","lt","lte","like","nlike","isNull"],"description":"Operator to use for filtering"},"value":{"type":"object","description":"Value to filter by (can be null for hasKey operator)"}},"required":["field","operator"]},"OrderByDto":{"type":"object","properties":{"field":{"type":"string","description":"Field to order by"},"ascending":{"type":"boolean","description":"Sort order direction","default":true}},"required":["field"]},"QueryResultDto":{"type":"object","properties":{"collection":{"type":"string","description":"Collection name"},"key":{"type":"string","description":"Document key"},"value":{"type":"object","description":"Document value"},"version":{"type":"number","description":"Document version"}},"required":["collection","key","value","version"]}}},"paths":{"/sfp/api/doc-store/collections/query":{"post":{"operationId":"DocStoreCollectionsController_queryCrossCollections","summary":"Query documents across collections (RECOMMENDED)","description":"Executes queries across multiple collections using path patterns. This powerful endpoint allows:\n        - Querying single collections by exact path (e.g., 'org/repo/builds-v2')\n        - Wildcard patterns to match multiple collections (e.g., 'repo_*/metadata')\n        - Cross-collection queries for impact analysis and health checks\n        - All standard query features (filtering, sorting, pagination)\n        - Properly handles nested collection names with slashes\n        - Use store=changelog to query the dedicated changelog table\n\n        **This is the recommended endpoint for all collection queries**, as it correctly handles nested collection paths.\n\n        Common use cases:\n        - Query specific collections with nested names (e.g., 'flxbl-io/sf-core/builds-v2')\n        - Find all metadata across repositories\n        - Search for specific configurations across environments\n        - Aggregate data from multiple sources","parameters":[{"name":"store","required":false,"in":"query","description":"Target store for the query. Defaults to \"doc\" for backward compatibility.","schema":{"enum":["doc","changelog","packages","builds"],"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PathQueryOptionsDto"}}}},"responses":{"200":{"description":"Query executed successfully.","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QueryResultDto"}}}}},"403":{"description":"Forbidden - Requires role: member, application"}},"tags":["Doc Store / Collections"]}}}}
```

## Get a specific document from a collection

> Retrieves a single document by its key from the specified collection. Returns:\
> &#x20;       \- The document value as stored\
> &#x20;       \- The current version number for optimistic concurrency control\
> &#x20;       \- Use store=changelog to retrieve from the dedicated changelog table\
> \
> &#x20;       Use this endpoint when you know the exact document key. For searching or filtering, use the query endpoints instead.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}}},"paths":{"/sfp/api/doc-store/collections/{collectionName}/docs/{key}":{"get":{"operationId":"DocStoreCollectionsController_getDocumentFromCollection","summary":"Get a specific document from a collection","description":"Retrieves a single document by its key from the specified collection. Returns:\n        - The document value as stored\n        - The current version number for optimistic concurrency control\n        - Use store=changelog to retrieve from the dedicated changelog table\n\n        Use this endpoint when you know the exact document key. For searching or filtering, use the query endpoints instead.","parameters":[{"name":"key","required":true,"in":"path","schema":{"type":"string"}},{"name":"store","required":false,"in":"query","description":"Target store for the document. Defaults to \"doc\" for backward compatibility.","schema":{"enum":["doc","changelog","packages","builds"],"type":"string"}},{"name":"collectionName","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The document has been successfully retrieved."},"403":{"description":"Forbidden - Requires role: member, application"},"404":{"description":"The collection or document was not found."}},"tags":["Doc Store / Collections"]}}}}
```

## Create or update a document in a collection

> Creates a new document or updates an existing one in the specified collection. Implements optimistic concurrency control:\
> &#x20;       \- For new documents: Do not provide a version number\
> &#x20;       \- For updates: Must provide the current version number to prevent concurrent modification conflicts\
> &#x20;       \- Version numbers are automatically incremented on successful updates\
> &#x20;       \- Use store=changelog to store in the dedicated changelog table (optimized for write-heavy operations)\
> \
> &#x20;       The document value can be any valid JSON structure. Collections are created automatically if they don't exist. Returns the document with its new version number.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}}},"paths":{"/sfp/api/doc-store/collections/{collectionName}/docs/{key}":{"post":{"operationId":"DocStoreCollectionsController_upsertDocumentInCollection","summary":"Create or update a document in a collection","description":"Creates a new document or updates an existing one in the specified collection. Implements optimistic concurrency control:\n        - For new documents: Do not provide a version number\n        - For updates: Must provide the current version number to prevent concurrent modification conflicts\n        - Version numbers are automatically incremented on successful updates\n        - Use store=changelog to store in the dedicated changelog table (optimized for write-heavy operations)\n\n        The document value can be any valid JSON structure. Collections are created automatically if they don't exist. Returns the document with its new version number.","parameters":[{"name":"key","required":true,"in":"path","schema":{"type":"string"}},{"name":"store","required":false,"in":"query","description":"Target store for the document. Defaults to \"doc\" for backward compatibility.","schema":{"enum":["doc","changelog","packages","builds"],"type":"string"}},{"name":"collectionName","required":true,"in":"path","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["value"],"properties":{"value":{"type":"object"},"version":{"type":"number","description":"Required for updates, must not be provided for new documents"}}}}}},"responses":{"201":{"description":"The document has been successfully created or updated in the collection."},"403":{"description":"Forbidden - Requires role: member, application"},"404":{"description":"The collection was not found."},"409":{"description":"Version conflict or invalid version usage."}},"tags":["Doc Store / Collections"]}}}}
```

## Delete a document from a collection

> Permanently deletes a specific document from a collection. This operation:\
> &#x20;       \- Removes the document immediately and permanently\
> &#x20;       \- Cannot be undone - ensure you have backups if needed\
> &#x20;       \- Does not affect other documents in the collection\
> &#x20;       \- Use store=changelog to delete from the dedicated changelog table\
> \
> &#x20;       Requires owner or application role for security. The collection itself remains even if it becomes empty.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}}},"paths":{"/sfp/api/doc-store/collections/{collectionName}/docs/{key}":{"delete":{"operationId":"DocStoreCollectionsController_deleteDocumentFromCollection","summary":"Delete a document from a collection","description":"Permanently deletes a specific document from a collection. This operation:\n        - Removes the document immediately and permanently\n        - Cannot be undone - ensure you have backups if needed\n        - Does not affect other documents in the collection\n        - Use store=changelog to delete from the dedicated changelog table\n\n        Requires owner or application role for security. The collection itself remains even if it becomes empty.","parameters":[{"name":"key","required":true,"in":"path","schema":{"type":"string"}},{"name":"store","required":false,"in":"query","description":"Target store for the document. Defaults to \"doc\" for backward compatibility.","schema":{"enum":["doc","changelog","packages","builds"],"type":"string"}},{"name":"collectionName","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"204":{"description":"The document has been successfully deleted."},"403":{"description":"Forbidden - Requires role: owner, application"},"404":{"description":"The collection or document was not found."}},"tags":["Doc Store / Collections"]}}}}
```

## Get the version of a specific document from a collection

> Retrieves only the version number of a document without its content. This lightweight endpoint is useful for:\
> &#x20;       \- Checking if a document has been modified before fetching\
> &#x20;       \- Verifying version before updates to prevent conflicts\
> &#x20;       \- Monitoring document changes\
> &#x20;       \- Use store=changelog to check version in the dedicated changelog table\
> \
> &#x20;       Returns only the version number, making it efficient for version checks.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}}},"paths":{"/sfp/api/doc-store/collections/{collectionName}/docs/{key}/version":{"get":{"operationId":"DocStoreCollectionsController_getDocumentVersionFromCollection","summary":"Get the version of a specific document from a collection","description":"Retrieves only the version number of a document without its content. This lightweight endpoint is useful for:\n        - Checking if a document has been modified before fetching\n        - Verifying version before updates to prevent conflicts\n        - Monitoring document changes\n        - Use store=changelog to check version in the dedicated changelog table\n\n        Returns only the version number, making it efficient for version checks.","parameters":[{"name":"key","required":true,"in":"path","schema":{"type":"string"}},{"name":"store","required":false,"in":"query","description":"Target store for the document. Defaults to \"doc\" for backward compatibility.","schema":{"enum":["doc","changelog","packages","builds"],"type":"string"}},{"name":"collectionName","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The document version has been successfully retrieved."},"403":{"description":"Forbidden - Requires role: member, application"},"404":{"description":"The collection or document was not found."}},"tags":["Doc Store / Collections"]}}}}
```

## List all documents in a collection

> Retrieves a list of all document keys and versions in a collection without their content. This endpoint:\
> &#x20;       \- Returns only keys and version numbers, not document values\
> &#x20;       \- Useful for discovering available documents\
> &#x20;       \- Efficient for large collections as it doesn't transfer document content\
> \
> &#x20;       For retrieving actual document content, use the query endpoint or get individual documents by key.

```json
{"openapi":"3.0.0","info":{"title":"sfp server","version":"51.3.0"},"security":[{"access-token":[]}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http","in":"header"}}},"paths":{"/sfp/api/doc-store/collections/{collectionName}/docs":{"get":{"operationId":"DocStoreCollectionsController_listDocumentsInCollection","summary":"List all documents in a collection","description":"Retrieves a list of all document keys and versions in a collection without their content. This endpoint:\n        - Returns only keys and version numbers, not document values\n        - Useful for discovering available documents\n        - Efficient for large collections as it doesn't transfer document content\n\n        For retrieving actual document content, use the query endpoint or get individual documents by key.","parameters":[{"name":"collectionName","required":true,"in":"path","schema":{"type":"string"}}],"responses":{"200":{"description":"The list of documents has been successfully retrieved."},"403":{"description":"Forbidden - Requires role: member, application"},"404":{"description":"The collection was not found."}},"tags":["Doc Store / Collections"]}}}}
```
