Skip to main content

Catalog API

The Catalog API provides endpoints for managing products, categories, attributes, and taxonomies.
Scope: Tenant-scoped; requires authenticated org context
Availability: Not available in SuperAdmin

Authentication

All requests require authentication. Include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
See Authentication for details.

Base URL

https://app.betterdata.co/api

Headers

All requests must include:
Content-Type: application/json
Authorization: Bearer YOUR_API_KEY

Endpoints

MethodPathSummaryAuthStabilityPermissions
GET/api/productsList productssessionstableproducts.read
POST/api/productsCreate a productsessionstableproducts.write
GET/api/products/[id]Get a specific productsessionstableproducts.read
PATCH/api/products/[id]Update a productsessionstableproducts.write
DELETE/api/products/[id]Delete a productsessionstableproducts.write
GET/api/products/[id]/attributesGet product attributessessionstableproducts.read
POST/api/products/[id]/attributesCreate product attributessessionstableproducts.write
POST/api/products/[id]/attributes/applyApply product attributessessionstableproducts.write
GET/api/products/[id]/categoriesGet product categoriessessionstableproducts.read
POST/api/products/[id]/categoriesAssign product categoriessessionstableproducts.write
POST/api/products/[id]/categories/applyApply product categoriessessionstableproducts.write
POST/api/products/[id]/categories/suggestSuggest product categoriessessionbeta ⚠️products.read
GET/api/products/[id]/historyGet product historysessionstableproducts.read
GET/api/products/[id]/inventory-levelsGet product inventory levelssessionstableproducts.read, inventory.read
GET/api/products/[id]/linksGet product linkssessionstableproducts.read
POST/api/products/[id]/linksCreate product linksessionstableproducts.write
GET/api/products/[id]/variantsList product variantssessionstableproducts.read
POST/api/products/[id]/variantsCreate product variantsessionstableproducts.write
GET/api/products/[id]/variants/[variantId]Get product variantsessionstableproducts.read
PATCH/api/products/[id]/variants/[variantId]Update product variantsessionstableproducts.write
DELETE/api/products/[id]/variants/[variantId]Delete product variantsessionstableproducts.write
GET/api/products/[id]/versionsGet product versionssessionstableproducts.read
GET/api/stock-requests/products/searchSearch products for stock requestssessionstablestockrequests.read, products.read
GET/api/taxonomiesList taxonomiessessionstabletaxonomies.read
GET/api/taxonomies/[id]/nodes/searchSearch taxonomy nodessessionstabletaxonomies.read
GET/api/taxonomies/[id]/treeGet taxonomy treesessionstabletaxonomies.read

Example Requests

List Products

curl -X GET "https://app.betterdata.co/api/products?categoryId=cat_123&page=1&limit=50" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "products": [
    {
      "id": "prod_123",
      "productName": "Product Name",
      "globalSku": "SKU-123",
      "description": "Product description",
      "categoryId": "cat_123",
      "categoryName": "Category Name",
      "status": "ACTIVE",
      "createdAt": "2024-01-01T00:00:00Z",
      "updatedAt": "2024-01-15T00:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "pageSize": 50,
    "total": 150,
    "totalPages": 3
  }
}

Create Product

curl -X POST "https://app.betterdata.co/api/products" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "productName": "New Product",
    "globalSku": "SKU-456",
    "description": "Product description",
    "categoryId": "cat_123",
    "identifiers": [
      {
        "type": "UPC",
        "value": "123456789012"
      }
    ],
    "attributes": {
      "color": "Blue",
      "size": "Large"
    }
  }'
Response:
{
  "product": {
    "id": "prod_456",
    "productName": "New Product",
    "globalSku": "SKU-456",
    "description": "Product description",
    "categoryId": "cat_123",
    "status": "ACTIVE",
    "createdAt": "2024-03-01T00:00:00Z"
  }
}

Get Taxonomy Tree

curl -X GET "https://app.betterdata.co/api/taxonomies/tax_123/tree" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json"
Response:
{
  "taxonomy": {
    "id": "tax_123",
    "name": "Product Taxonomy",
    "rootNodes": [
      {
        "id": "node_1",
        "name": "Category 1",
        "code": "CAT1",
        "children": [
          {
            "id": "node_2",
            "name": "Subcategory 1.1",
            "code": "CAT1.1",
            "children": []
          }
        ]
      }
    ]
  }
}

Common Errors

401 Unauthorized

{
  "error": "Unauthorized"
}
Cause: Missing or invalid API key. Solution: Include a valid API key in the Authorization header.

400 Bad Request

{
  "error": "Validation error",
  "details": {
    "productName": ["Required"],
    "globalSku": ["Must be unique"]
  }
}
Cause: Invalid request parameters or validation errors. Solution: Review the request body and ensure all required fields are provided with valid values.

403 Forbidden

{
  "error": "Forbidden"
}
Cause: Insufficient permissions. Product creation requires products.write permission. Solution: Ensure your API key has the required permissions.

404 Not Found

{
  "error": "Product not found"
}
Cause: The requested product doesn’t exist or isn’t accessible. Solution: Verify the product ID and ensure you have access to it.

409 Conflict

{
  "error": "Product with SKU already exists"
}
Cause: Product with the same SKU already exists. Solution: Use a unique SKU or update the existing product.

Query Parameters

List Products

  • categoryId: Filter by category
  • search: Search by product name or SKU
  • status: 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)

List Categories

  • parentId: Filter by parent category
  • search: Search by category name
  • page: Page number (default: 1)
  • limit: Page size (default: 20, max: 100)

Search Taxonomy Nodes

  • query: Search query
  • parentId: Filter by parent node
  • limit: Result limit (default: 20, max: 100)

Request/Response Schemas

Product

{
  id: string;
  productName: string;
  globalSku: string;
  description?: string;
  categoryId?: string;
  categoryName?: string;
  status: "ACTIVE" | "PENDING" | "REVOKED";
  identifiers?: Array<{
    type: string;
    value: string;
  }>;
  attributes?: Record<string, unknown>;
  createdAt: string; // ISO datetime
  updatedAt: string; // ISO datetime
}

Create Product Request

{
  productName: string;
  globalSku: string;
  description?: string;
  categoryId?: string;
  identifiers?: Array<{
    type: string;
    value: string;
  }>;
  attributes?: Record<string, unknown>;
}

Category

{
  id: string;
  name: string;
  code?: string;
  description?: string;
  parentId?: string;
  createdAt: string; // ISO datetime
}

Taxonomy Node

{
  id: string;
  name: string;
  code?: string;
  parentId?: string;
  children?: TaxonomyNode[];
}


Permissions & Roles

Catalog API access requires appropriate permissions:
  • Read: products.read, categories.read, attributes.read
  • Write: products.write, categories.write, attributes.write