Skip to content

Products & Services API

The Products & Services API allows you to manage your product catalog and service offerings. This is essential for communication integrations that need to reference available products/services when creating quotes, invoices, or sending communications to clients.

Base Endpoint

/v1/products

Authentication

All requests require the products:read scope for GET operations and products:write scope for POST/PUT operations.

List Products/Services

Retrieve a paginated list of products and services.

Endpoint

GET /v1/products

Query Parameters

ParameterTypeDescription
typestringFilter by type: product or service
limitintegerNumber of results per page (default: 50, max: 100)
offsetintegerNumber of results to skip (default: 0)
order_bystringField to sort by: created_at, updated_at, name, price (default: created_at)
orderstringSort order: asc or desc (default: desc)

Example Request

bash
curl -X GET \
  'https://your-instance.supabase.co/functions/v1/crm-api/v1/products?type=service&limit=20' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

json
{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "type": "service",
      "name": "Website Design",
      "description": "Custom website design and development",
      "pricing_model": "fixed",
      "price": 2500.00,
      "sku": null,
      "tenant_id": "123e4567-e89b-12d3-a456-426614174000",
      "created_at": "2024-01-15T10:30:00Z",
      "updated_at": "2024-01-15T10:30:00Z",
      "created_by": "789e0123-e45b-67c8-d901-234567890abc"
    },
    {
      "id": "660e8400-e29b-41d4-a716-446655440001",
      "type": "product",
      "name": "Premium Widget",
      "description": "High-quality widget with lifetime warranty",
      "pricing_model": "fixed",
      "price": 99.99,
      "sku": "WIDGET-PREM-001",
      "tenant_id": "123e4567-e89b-12d3-a456-426614174000",
      "created_at": "2024-01-14T09:15:00Z",
      "updated_at": "2024-01-14T09:15:00Z",
      "created_by": "789e0123-e45b-67c8-d901-234567890abc"
    }
  ],
  "count": 2,
  "has_more": false
}

Get Product/Service

Retrieve a specific product or service by ID.

Endpoint

GET /v1/products/:id

Path Parameters

ParameterTypeDescription
iduuidProduct/service ID

Example Request

bash
curl -X GET \
  'https://your-instance.supabase.co/functions/v1/crm-api/v1/products/550e8400-e29b-41d4-a716-446655440000' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Example Response

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "service",
    "name": "Website Design",
    "description": "Custom website design and development",
    "pricing_model": "fixed",
    "price": 2500.00,
    "sku": null,
    "tenant_id": "123e4567-e89b-12d3-a456-426614174000",
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-15T10:30:00Z",
    "created_by": "789e0123-e45b-67c8-d901-234567890abc"
  }
}

Create Product/Service

Create a new product or service.

Endpoint

POST /v1/products

Request Body

FieldTypeRequiredDescription
typestringYesEither product or service
namestringYesProduct/service name (max 255 characters)
descriptionstringNoDetailed description
pricing_modelstringYesEither fixed or hourly
pricenumberYesUnit price (must be >= 0)
skustringNoStock keeping unit (for products)

Example Request

bash
curl -X POST \
  'https://your-instance.supabase.co/functions/v1/crm-api/v1/products' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: unique-key-123' \
  -d '{
    "type": "service",
    "name": "Consulting Services",
    "description": "Expert consulting and advisory services",
    "pricing_model": "hourly",
    "price": 150.00
  }'

Example Response

json
{
  "data": {
    "id": "770e8400-e29b-41d4-a716-446655440002",
    "type": "service",
    "name": "Consulting Services",
    "description": "Expert consulting and advisory services",
    "pricing_model": "hourly",
    "price": 150.00,
    "sku": null,
    "tenant_id": "123e4567-e89b-12d3-a456-426614174000",
    "created_at": "2024-01-16T14:20:00Z",
    "updated_at": "2024-01-16T14:20:00Z",
    "created_by": "789e0123-e45b-67c8-d901-234567890abc"
  }
}

Update Product/Service

Update an existing product or service.

Endpoint

PUT /v1/products/:id

Path Parameters

ParameterTypeDescription
iduuidProduct/service ID

Request Body

All fields are optional. Only include fields you want to update.

FieldTypeDescription
typestringEither product or service
namestringProduct/service name (max 255 characters)
descriptionstringDetailed description
pricing_modelstringEither fixed or hourly
pricenumberUnit price (must be >= 0)
skustringStock keeping unit (for products)

Example Request

bash
curl -X PUT \
  'https://your-instance.supabase.co/functions/v1/crm-api/v1/products/550e8400-e29b-41d4-a716-446655440000' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "price": 2750.00,
    "description": "Updated: Custom website design and development with responsive design"
  }'

Example Response

json
{
  "data": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "type": "service",
    "name": "Website Design",
    "description": "Updated: Custom website design and development with responsive design",
    "pricing_model": "fixed",
    "price": 2750.00,
    "sku": null,
    "tenant_id": "123e4567-e89b-12d3-a456-426614174000",
    "created_at": "2024-01-15T10:30:00Z",
    "updated_at": "2024-01-16T15:45:00Z",
    "created_by": "789e0123-e45b-67c8-d901-234567890abc"
  }
}

Data Model

Product/Service Object

FieldTypeDescription
iduuidUnique identifier
typestringEither product or service
namestringProduct/service name
descriptionstring | nullDetailed description
pricing_modelstringEither fixed or hourly
pricenumberUnit price
skustring | nullStock keeping unit (typically for products)
tenant_iduuidTenant identifier (automatically set)
created_attimestampCreation timestamp
updated_attimestampLast update timestamp
created_byuuidUser who created the product/service

Use Cases for Communication Integrations

1. Populate Product Dropdowns

When creating quotes or invoices through integrations, query available products/services to populate selection lists:

bash
# Get all services for a dropdown
curl -X GET \
  'https://your-instance.supabase.co/functions/v1/crm-api/v1/products?type=service' \
  -H 'Authorization: Bearer YOUR_API_KEY'

2. Validate Product References

Before creating invoice/quote line items, verify that referenced products exist:

bash
# Check if product exists
curl -X GET \
  'https://your-instance.supabase.co/functions/v1/crm-api/v1/products/PRODUCT_ID' \
  -H 'Authorization: Bearer YOUR_API_KEY'

3. Display Product Information

Include product details in communications sent to clients:

bash
# Get product details for email template
curl -X GET \
  'https://your-instance.supabase.co/functions/v1/crm-api/v1/products/PRODUCT_ID' \
  -H 'Authorization: Bearer YOUR_API_KEY'

Error Responses

404 Not Found

json
{
  "error": {
    "message": "Product not found",
    "code": "NOT_FOUND"
  }
}

400 Bad Request

json
{
  "error": {
    "message": "Validation failed",
    "code": "VALIDATION_ERROR",
    "details": {
      "field": "price",
      "issue": "Price must be a positive number"
    }
  }
}

403 Forbidden

json
{
  "error": {
    "message": "Missing required scope: products:read",
    "code": "INSUFFICIENT_SCOPE",
    "required": "products:read",
    "granted": ["clients:read"]
  }
}

409 Conflict

json
{
  "error": {
    "message": "Product with this SKU already exists",
    "code": "DUPLICATE"
  }
}

Notes

  • All products/services are tenant-scoped automatically
  • SKU values should be unique within a tenant
  • Products with pricing_model: "hourly" are typically used with timesheets
  • Products with pricing_model: "fixed" have a one-time price per unit
  • The type field distinguishes between physical products (with inventory) and services (no inventory)

autoch.at Documentation