API Reference
The Catalog API provides endpoints for managing products, categories, attributes, and taxonomies.
Scope: Workspace-scoped — requires authenticated organization context and valid credentials for that workspace.
All requests require authentication. Include your API key in the Authorization header:
1Authorization: Bearer YOUR_API_KEYSee Authentication for details.
1https://app.betterdata.co/apiAll requests must include:
1Content-Type: application/json2Authorization: Bearer YOUR_API_KEY| Method | Path | Summary | Auth | Stability | Permissions |
| ------ | ---- | ------- | ---- | --------- | ----------- |
| GET | /api/products | List products | session | stable | products.read |
| POST | /api/products | Create a product | session | stable | products.write |
| GET | /api/products/[id] | Get a specific product | session | stable | products.read |
| PATCH | /api/products/[id] | Update a product | session | stable | products.write |
| DELETE | /api/products/[id] | Delete a product | session | stable | products.write |
| GET | /api/products/[id]/attributes | Get product attributes | session | stable | products.read |
| POST | /api/products/[id]/attributes | Create product attributes | session | stable | products.write |
| POST | /api/products/[id]/attributes/apply | Apply product attributes | session | stable | products.write |
| GET | /api/products/[id]/categories | Get product categories | session | stable | products.read |
| POST | /api/products/[id]/categories | Assign product categories | session | stable | products.write |
| POST | /api/products/[id]/categories/apply | Apply product categories | session | stable | products.write |
| POST | /api/products/[id]/categories/suggest | Suggest product categories | session | beta ⚠️ | products.read |
| GET | /api/products/[id]/history | Get product history | session | stable | products.read |
| GET | /api/products/[id]/inventory-levels | Get product inventory levels | session | stable | products.read, inventory.read |
| GET | /api/products/[id]/links | Get product links | session | stable | products.read |
| POST | /api/products/[id]/links | Create product link | session | stable | products.write |
| GET | /api/products/[id]/variants | List product variants | session | stable | products.read |
| POST | /api/products/[id]/variants | Create product variant | session | stable | products.write |
| GET | /api/products/[id]/variants/[variantId] | Get product variant | session | stable | products.read |
| PATCH | /api/products/[id]/variants/[variantId] | Update product variant | session | stable | products.write |
| DELETE | /api/products/[id]/variants/[variantId] | Delete product variant | session | stable | products.write |
| GET | /api/products/[id]/versions | Get product versions | session | stable | products.read |
| GET | /api/stock-requests/products/search | Search products for stock requests | session | stable | stockrequests.read, products.read |
| GET | /api/taxonomies | List taxonomies | session | stable | taxonomies.read |
| GET | /api/taxonomies/[id]/nodes/search | Search taxonomy nodes | session | stable | taxonomies.read |
| GET | /api/taxonomies/[id]/tree | Get taxonomy tree | session | stable | taxonomies.read |
1curl -X GET "https://app.betterdata.co/api/products?categoryId=cat_123&page=1&limit=50" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json"Response:
1{2 "products": [3 {4 "id": "prod_123",5 "productName": "Product Name",6 "globalSku": "SKU-123",7 "description": "Product description",8 "categoryId": "cat_123",9 "categoryName": "Category Name",10 "status": "ACTIVE",11 "createdAt": "2024-01-01T00:00:00Z",12 "updatedAt": "2024-01-15T00:00:00Z"13 }14 ],15 "pagination": {16 "page": 1,17 "pageSize": 50,18 "total": 150,19 "totalPages": 320 }21}1curl -X POST "https://app.betterdata.co/api/products" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json" \4 -d '{5 "productName": "New Product",6 "globalSku": "SKU-456",7 "description": "Product description",8 "categoryId": "cat_123",9 "identifiers": [10 {11 "type": "UPC",12 "value": "123456789012"13 }14 ],15 "attributes": {16 "color": "Blue",17 "size": "Large"18 }19 }'Response:
1{2 "product": {3 "id": "prod_456",4 "productName": "New Product",5 "globalSku": "SKU-456",6 "description": "Product description",7 "categoryId": "cat_123",8 "status": "ACTIVE",9 "createdAt": "2024-03-01T00:00:00Z"10 }11}1curl -X GET "https://app.betterdata.co/api/taxonomies/tax_123/tree" \2 -H "Authorization: Bearer YOUR_API_KEY" \3 -H "Content-Type: application/json"Response:
1{2 "taxonomy": {3 "id": "tax_123",4 "name": "Product Taxonomy",5 "rootNodes": [6 {7 "id": "node_1",8 "name": "Category 1",9 "code": "CAT1",10 "children": [11 {12 "id": "node_2",13 "name": "Subcategory 1.1",14 "code": "CAT1.1",15 "children": []16 }17 ]18 }19 ]20 }21}1{2 "error": "Unauthorized"3}Cause: Missing or invalid API key.
Solution: Include a valid API key in the Authorization header.
1{2 "error": "Validation error",3 "details": {4 "productName": ["Required"],5 "globalSku": ["Must be unique"]6 }7}Cause: Invalid request parameters or validation errors.
Solution: Review the request body and ensure all required fields are provided with valid values.
1{2 "error": "Forbidden"3}Cause: Insufficient permissions. Product creation requires products.write permission.
Solution: Ensure your API key has the required permissions.
1{2 "error": "Product not found"3}Cause: The requested product doesn't exist or isn't accessible.
Solution: Verify the product ID and ensure you have access to it.
1{2 "error": "Product with SKU already exists"3}Cause: Product with the same SKU already exists.
Solution: Use a unique SKU or update the existing product.
categoryId: Filter by categorysearch: Search by product name or SKUstatus: Filter by status (ACTIVE, PENDING, REVOKED)page: Page number (default: 1)limit: Page size (default: 20, max: 100)sortBy: Sort field (default: createdAt)sortOrder: Sort order (asc, desc)parentId: Filter by parent categorysearch: Search by category namepage: Page number (default: 1)limit: Page size (default: 20, max: 100)query: Search queryparentId: Filter by parent nodelimit: Result limit (default: 20, max: 100)1{2 id: string;3 productName: string;4 globalSku: string;5 description?: string;6 categoryId?: string;7 categoryName?: string;8 status: "ACTIVE" | "PENDING" | "REVOKED";9 identifiers?: Array<{10 type: string;11 value: string;12 }>;13 attributes?: Record<string, unknown>;14 createdAt: string; "cmt">// ISO datetime15 updatedAt: string; "cmt">// ISO datetime16}1{2 productName: string;3 globalSku: string;4 description?: string;5 categoryId?: string;6 identifiers?: Array<{7 type: string;8 value: string;9 }>;10 attributes?: Record<string, unknown>;11}1{2 id: string;3 name: string;4 code?: string;5 description?: string;6 parentId?: string;7 createdAt: string; "cmt">// ISO datetime8}1{2 id: string;3 name: string;4 code?: string;5 parentId?: string;6 children?: TaxonomyNode[];7}Catalog API access requires appropriate permissions:
products.read, categories.read, attributes.readproducts.write, categories.write, attributes.write