Service Management¶
Complete guide to managing service catalogs, categories, pricing, and availability in the Reserva platform.
Overview¶
The service management system provides comprehensive catalog management with support for:
- Service CRUD - Create, read, update, and delete services
- Category Organization - Template-based category management for consistent organization
- Multi-Portal Access - Staff (full management) and customer (read-only) access
- Outlet-Specific Pricing - Location-based pricing flexibility
- Advanced Filtering - Search by category, price range, duration, and outlet
- Status Management - Control service availability and lifecycle
Key Concepts:
- Category Templates = Tenant-specific category suggestions for consistency
- Outlet Pricing = Location-based price overrides with base price fallback
- Service Status = Active, inactive, or archived lifecycle management
- Dual Portal = Staff (management) and customer (browsing) access modes
Subscription Plan Limits¶
Service catalog features are restricted by subscription plan tier:
| Plan | Max Services | Outlet Pricing | Custom Categories |
|---|---|---|---|
| FREE | 10 services | ❌ No | ✅ Default templates |
| PRO | 50 services | ✅ Yes | ✅ Custom templates |
| ENTERPRISE | Unlimited | ✅ Yes | ✅ Custom templates |
Limit Enforcement:
- Creating a service on FREE plan will fail if tenant already has 10 services
- Check current usage:
GET /api/v1/subscriptions/usage - Upgrade required for unlimited services: See Subscription Management
Related Limits:
- See Subscription Management - Usage Tracking for monitoring service limits
- See Tenant Management for configuring category templates
Quick Navigation - Pricing¶
| Topic | Link |
|---|---|
| Pricing hierarchy (Promo → Outlet → Base) | Pricing Management - Pricing Hierarchy |
| Set promotional pricing | Pricing Management - Set Promotional Pricing |
| Promotional pricing scenarios | Pricing Management - Pricing Scenarios |
| Pricing best practices | Pricing Management - Best Practices |
| Test pricing logic | Pricing Management - Testing |
| Troubleshoot pricing issues | Pricing Management - Troubleshooting |
Available Endpoints¶
| Endpoint | Method | Purpose | Access |
|---|---|---|---|
/services |
GET | List services with filtering | Staff + Customers |
/services |
POST | Create new service | Staff only |
/services/categories |
GET | List categories with counts | Staff + Customers |
/services/categories/templates |
GET | Get category templates | Staff + Customers |
/services/{service_id} |
GET | Get service details | Staff + Customers |
/services/{service_id} |
PUT | Update service | Staff only |
/services/{service_id} |
DELETE | Delete service (soft) | TENANT_ADMIN only |
/services/{service_id}/pricing |
POST | Set outlet-specific pricing | Staff only |
List Services¶
Retrieve a paginated list of services with advanced filtering options.
Endpoint¶
Authentication: Required (JWT token - Staff or Customer)
Query Parameters¶
page(optional) - Page number (default: 1)size(optional) - Page size (default: 20, max: 100)category(optional) - Filter by service categorysearch(optional) - Search in name, description, or tagsoutlet_id(optional) - Filter by outlet availabilitymin_price(optional) - Minimum price filter (≥ 0)max_price(optional) - Maximum price filter (≥ 0)min_duration(optional) - Minimum duration in minutes (≥ 5)max_duration(optional) - Maximum duration in minutes (≤ 480)status(optional) - Filter by status (staff only):active,inactive,archived
Response¶
{
"items": [
{
"id": "68e63f26241da4ebe30521c8",
"tenant_id": "68e4cfe3886b6f295471fd4c",
"name": "Premium Facial Treatment",
"slug": "premium-facial",
"description": "Luxurious 90-minute facial with premium products",
"category": "facial",
"duration_minutes": 90,
"preparation_minutes": 15,
"cleanup_minutes": 10,
"max_advance_booking_days": 30,
"min_advance_booking_hours": 2,
"requires_staff": true,
"required_staff_count": 1,
"allow_parallel_bookings": false,
"max_parallel_bookings": 1,
"pricing": {
"base_price": "75.00",
"currency": "USD",
"outlet_prices": {
"68e4f07e1245f30b04760bd5": "85.00"
},
"promotional_price": null,
"promotional_valid_until": null
},
"tags": ["luxury", "facial", "skincare"],
"image_url": "https://example.com/images/premium-facial.jpg",
"is_active": true,
"status": "active",
"average_rating": 4.8,
"rating_count": 24,
"created_at": "2025-10-08T10:38:30.619000",
"updated_at": "2025-10-08T10:44:55.679000"
}
],
"total": 45,
"page": 1,
"size": 20,
"pages": 3
}
Access Control¶
Staff Users:
- See all services regardless of status
- Can filter by status parameter
- View complete service details including pricing
Customer Users:
- See only active services (status:
active, is_active:true) - Status filter is ignored
- View public service information
Business Rules¶
- Search is case-insensitive across name, description, and tags
- Price filtering applies to
base_price(not outlet-specific prices) - Outlet filtering shows services available at all outlets OR specific outlet
- Results are sorted alphabetically by name
- Empty search returns all services (with filters applied)
Create Service¶
Create a new service in the catalog with comprehensive configuration.
Endpoint¶
Authentication: Required (TENANT_ADMIN or OUTLET_MANAGER)
Request Body¶
{
"name": "Premium Facial Treatment",
"slug": "premium-facial",
"description": "Luxurious 90-minute facial with premium products",
"category": "facial",
"duration_minutes": 90,
"preparation_minutes": 15,
"cleanup_minutes": 10,
"max_advance_booking_days": 30,
"min_advance_booking_hours": 2,
"requires_staff": true,
"required_staff_count": 1,
"allow_parallel_bookings": false,
"max_parallel_bookings": 1,
"pricing": {
"base_price": 75.00,
"currency": "USD"
},
"tags": ["luxury", "facial", "skincare"],
"image_url": "https://example.com/images/premium-facial.jpg",
"is_active": true,
"status": "active"
}
Parameters¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | ✅ Yes | Service name (max 200 chars) |
slug |
string | ✅ Yes | URL-friendly identifier (unique per tenant) |
description |
string | ❌ No | Detailed service description |
category |
string | ✅ Yes | Service category (use templates) |
duration_minutes |
integer | ✅ Yes | Service duration (5-480 minutes) |
preparation_minutes |
integer | ❌ No | Setup time before service (default: 0) |
cleanup_minutes |
integer | ❌ No | Cleanup time after service (default: 0) |
max_advance_booking_days |
integer | ❌ No | Max days in advance for booking (default: 90) |
min_advance_booking_hours |
integer | ❌ No | Min hours notice required (default: 1) |
requires_staff |
boolean | ❌ No | Whether staff is required (default: true) |
required_staff_count |
integer | ❌ No | Number of staff needed (default: 1) |
allow_parallel_bookings |
boolean | ❌ No | Allow multiple bookings simultaneously (default: false) - See Parallel Booking |
max_parallel_bookings |
integer | ❌ No | Max parallel bookings if allowed (default: 1) - See Parallel Booking |
pricing.base_price |
decimal | ✅ Yes | Base price for service - See Pricing Management |
pricing.currency |
string | ✅ Yes | Currency code (e.g., USD, IDR) |
pricing.promotional_price |
decimal | ❌ No | Time-limited promotional price - See Promotional Pricing |
pricing.promotional_valid_until |
datetime | ❌ No | Promotion expiration date (UTC) - See Promotional Pricing |
tags |
array[string] | ❌ No | Searchable tags for service |
image_url |
string | ❌ No | Service image URL |
is_active |
boolean | ❌ No | Service availability (default: true) |
status |
string | ❌ No | Status: active, inactive, archived (default: active) |
Response¶
{
"id": "68e63f26241da4ebe30521c8",
"tenant_id": "68e4cfe3886b6f295471fd4c",
"name": "Premium Facial Treatment",
"slug": "premium-facial",
"description": "Luxurious 90-minute facial with premium products",
"category": "facial",
"duration_minutes": 90,
"pricing": {
"base_price": "75.00",
"currency": "USD",
"outlet_prices": {},
"promotional_price": null,
"promotional_valid_until": null
},
"is_active": true,
"status": "active",
"average_rating": null,
"rating_count": 0,
"created_at": "2025-10-08T10:38:30.619000",
"updated_at": "2025-10-08T10:38:30.619000"
}
Service Category Configuration¶
Category Templates:
The category field accepts any string, but tenants can configure templates for consistency.
Get available templates:
Common Templates by Business Type:
- Salon:
hair_cut,hair_color,hair_treatment,hair_styling,makeup,manicure,pedicure - Spa:
massage,body_treatment,facial,spa,therapy,waxing,consultation - Fitness:
personal_training,yoga,pilates,cardio,strength_training - Clinic:
consultation,therapy,physiotherapy,assessment,treatment
Category Format:
- Lowercase with underscores (e.g.,
hair_cut,body_treatment) - Configurable via tenant settings:
settings.service_category_templates - See Tenant Management for template configuration
Business Rules¶
- Service slug must be unique within tenant
- Category is required for proper classification
- Duration should be in 5-minute increments for scheduling efficiency
- Created services are active by default and immediately available for booking
- Base price is required; outlet-specific pricing can be added later
- Tenant isolation is automatically enforced
Subscription Limits¶
⚠️ FREE Plan Restriction: Maximum 10 services per tenant
Check before creating:
curl -X GET https://api.example.com/api/v1/subscriptions/usage \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
Error Response (Limit Exceeded):
Upgrade Required: See Subscription Management - Upgrade
Get Service Categories¶
Retrieve all service categories with service counts and descriptions.
Endpoint¶
Authentication: Required (JWT token - Staff or Customer)
Query Parameters¶
active_only(optional) - Count only active services (default: true)
Response¶
[
{
"category": "facial",
"display_name": "Facial",
"count": 12,
"description": "Facial treatments and skincare"
},
{
"category": "massage",
"display_name": "Massage",
"count": 8,
"description": "Relaxation and therapeutic massage"
},
{
"category": "hair_cut",
"display_name": "Hair Cut",
"count": 15,
"description": "Professional hair cutting and trimming services"
}
]
Access Control¶
Staff Users:
- See all categories regardless of service count
- Can include inactive services in counts
Customer Users:
- See only categories with active services (count > 0)
- Empty categories are hidden
Business Rules¶
- Categories are sourced from tenant's
service_category_templates - Service counts respect tenant isolation
- Categories are sorted alphabetically
- Descriptions provide context for service selection
Get Service Category Templates¶
Retrieve tenant-specific category templates for consistent service organization.
Endpoint¶
Authentication: Required (JWT token - Staff or Customer)
Response¶
[
"hair_cut",
"hair_color",
"hair_treatment",
"hair_styling",
"facial",
"makeup",
"eyebrows",
"eyelashes",
"manicure",
"pedicure",
"nail_art",
"massage",
"body_treatment",
"waxing",
"spa",
"therapy",
"consultation",
"other"
]
Business Value¶
- Consistency - Standardized category naming across organization
- UI Integration - Used for autocomplete/dropdown in forms
- Customizable - Configured per business type and services offered
- Filtering - Enables better reporting and service discovery
Configuration¶
Customize Templates:
Update tenant settings via Tenant Management API:
curl -X PUT https://api.example.com/api/v1/tenants/{tenant_id} \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"settings": {
"service_category_templates": [
"massage",
"body_treatment",
"facial",
"spa",
"therapy",
"waxing",
"consultation"
]
}
}'
Default Templates:
If not configured, system returns default salon/spa categories.
Note¶
Templates are suggestions - staff can create services with any category value if needed.
Get Service Details¶
Retrieve detailed information about a specific service.
Endpoint¶
Authentication: Required (JWT token - Staff or Customer)
Path Parameters¶
service_id(required) - Service ID (ObjectId format)
Response¶
{
"id": "68e63f26241da4ebe30521c8",
"tenant_id": "68e4cfe3886b6f295471fd4c",
"name": "Premium Facial Treatment",
"slug": "premium-facial",
"description": "Luxurious 90-minute facial with premium products",
"category": "facial",
"duration_minutes": 90,
"preparation_minutes": 15,
"cleanup_minutes": 10,
"max_advance_booking_days": 30,
"min_advance_booking_hours": 2,
"requires_staff": true,
"required_staff_count": 1,
"allow_parallel_bookings": false,
"max_parallel_bookings": 1,
"pricing": {
"base_price": "75.00",
"currency": "USD",
"outlet_prices": {
"68e4f07e1245f30b04760bd5": "85.00",
"68e4f07e1245f30b04760bd6": "80.00"
},
"promotional_price": "65.00",
"promotional_valid_until": "2025-12-31T23:59:59Z"
},
"tags": ["luxury", "facial", "skincare"],
"image_url": "https://example.com/images/premium-facial.jpg",
"is_active": true,
"status": "active",
"average_rating": 4.8,
"rating_count": 24,
"created_at": "2025-10-08T10:38:30.619000",
"updated_at": "2025-10-08T10:44:55.679000"
}
Pricing Information¶
The pricing object contains comprehensive pricing configuration:
- base_price - Default price across all outlets
- outlet_prices - Location-specific price overrides
- promotional_price - Time-limited promotional discount
- promotional_valid_until - Promotion expiration date
Pricing Hierarchy: Promotional → Outlet-Specific → Base
📖 See: Pricing Management for complete pricing hierarchy, promotional campaigns, and pricing strategies.
Access Control¶
Staff Users:
- View any service regardless of status
- See complete pricing information including outlet overrides
Customer Users:
- View only active services (status:
active, is_active:true) - Inactive services return 404 Not Found
Business Rules¶
- Service must belong to current tenant
- Service ID must be valid ObjectId format
- Pricing includes base price and all outlet-specific overrides
- Rating data includes average and count of reviews
Update Service¶
Update an existing service with partial or complete modifications.
Endpoint¶
Authentication: Required (TENANT_ADMIN or OUTLET_MANAGER)
Path Parameters¶
service_id(required) - Service ID (ObjectId format)
Request Body¶
Supports partial updates - only include fields to change:
{
"name": "Premium Luxury Facial Treatment",
"description": "Enhanced 90-minute facial with exclusive premium products",
"pricing": {
"base_price": 85.00,
"promotional_price": 70.00,
"promotional_valid_until": "2025-12-31T23:59:59Z"
},
"tags": ["luxury", "facial", "skincare", "premium"],
"is_active": true,
"status": "active"
}
Response¶
Returns complete updated service (same format as GET response).
Business Rules¶
- Service must exist and belong to current tenant
- Slug must remain unique within tenant if changed
- Status changes affect immediate service availability
- Pricing changes apply to new bookings only (existing bookings unaffected)
- Cannot update deleted services (status:
archived) - Changes take effect immediately
Important Notes¶
⚠️ Active Bookings: Changes to duration, pricing, or requirements do not affect existing appointments
⚠️ Slug Changes: Changing slug may break existing deep links or bookmarks
Recommendation: Create new service version instead of modifying heavily-booked services
Delete Service¶
Soft delete a service by marking it as archived and unavailable.
Endpoint¶
Authentication: Required (TENANT_ADMIN only)
Path Parameters¶
service_id(required) - Service ID (ObjectId format)
Response¶
Business Rules¶
- Soft Deletion: Service is marked as deleted, not removed from database
- Service becomes immediately unavailable for new bookings
- Existing appointments remain unaffected
- Historical booking data and revenue records preserved
- Service disappears from customer-facing lists immediately
- Only TENANT_ADMIN can delete services (higher permission than updates)
What Happens on Deletion¶
is_activeset tofalseis_deletedset totruestatuschanged toARCHIVEDdeleted_attimestamp recorded- Service removed from active listings
Data Preservation¶
✅ Preserved:
- All service configuration
- Historical appointments
- Revenue data
- Customer reviews
- Booking statistics
❌ Removed:
- Visibility in service catalog
- Availability for new bookings
- Customer-facing listings
Note¶
Restoration: Contact system administrator to restore deleted services (not exposed via API)
Permanent Deletion: Data retention policies apply after 90 days of soft deletion
Set Outlet-Specific Pricing¶
Configure location-based pricing for a service across different outlets.
📖 See: Pricing Management - Outlet-Specific Pricing for detailed pricing hierarchy and best practices.
Endpoint¶
Authentication: Required (TENANT_ADMIN or OUTLET_MANAGER)
Path Parameters¶
service_id(required) - Service ID (ObjectId format)
Request Body¶
{
"outlet_prices": {
"68e4f07e1245f30b04760bd5": 85.00,
"68e4f07e1245f30b04760bd6": 80.00,
"68e4f07e1245f30b04760bd7": 90.00
}
}
Parameters¶
outlet_prices(required) - Dictionary mapping outlet IDs to prices- Keys: Valid ObjectId strings for outlets
- Values: Positive decimal prices
Response¶
Returns complete updated service with new pricing structure (same format as GET response).
Example pricing in response:
{
"pricing": {
"base_price": "75.00",
"currency": "USD",
"outlet_prices": {
"68e4f07e1245f30b04760bd5": "85.00",
"68e4f07e1245f30b04760bd6": "80.00",
"68e4f07e1245f30b04760bd7": "90.00"
},
"promotional_price": null,
"promotional_valid_until": null
}
}
Access Control¶
TENANT_ADMIN:
- Can set prices for any outlet in tenant
- Full pricing management access
OUTLET_MANAGER:
- Can only set prices for outlets they manage
- Restricted by
outlet_idsin user profile - Returns 403 Forbidden if attempting to price unmanaged outlets
Business Rules¶
- Service must exist and belong to current tenant
- All outlet IDs must be valid ObjectId format
- All prices must be positive values
- Outlet IDs must belong to current tenant
- Base price remains unchanged (acts as fallback)
- New prices merge with existing outlet pricing (non-destructive)
- Changes affect new bookings immediately
Pricing Resolution¶
When booking at a specific outlet, the system follows this hierarchy:
- Promotional Price (if valid and not expired) - Highest priority
- Outlet-Specific Price (if outlet has custom price in
outlet_prices) - Base Price (final fallback)
📖 See: Pricing Management - Pricing Hierarchy for complete resolution logic and examples.
Subscription Requirements¶
⚠️ FREE Plan Restriction: Outlet-specific pricing not available
Plans with Outlet Pricing:
- ✅ PRO - Outlet pricing enabled
- ✅ ENTERPRISE - Outlet pricing enabled
Upgrade Required: See Subscription Management - Upgrade
Example Use Cases¶
Location-Based Pricing:
- Premium locations charge more
- Downtown outlets vs suburban outlets
- High-rent areas vs standard locations
Promotional Pricing:
- New outlet launch pricing
- Seasonal outlet-specific promotions
- Traffic-driving discounts for specific locations
Service Status Lifecycle¶
Services follow a defined lifecycle with status management:
Status Values¶
| Status | Description | Customer Visible | Bookable |
|---|---|---|---|
active |
Service is live and available | ✅ Yes | ✅ Yes |
inactive |
Temporarily unavailable | ❌ No | ❌ No |
archived |
Deleted or discontinued | ❌ No | ❌ No |
Status Transitions¶
graph LR
A[Create Service] --> B[active]
B --> C[inactive]
C --> B
B --> D[archived]
C --> D
D -.restore.-> B
Allowed Transitions:
active→inactive- Temporarily disable serviceinactive→active- Re-enable serviceactive→archived- Delete serviceinactive→archived- Delete inactive servicearchived→active- Restore deleted service (admin only)
is_active vs status¶
Two-Level Control:
is_active(boolean) - Quick availability togglestatus(enum) - Detailed lifecycle state
Relationship:
- Active service:
is_active=trueANDstatus=active - Customer visibility requires BOTH conditions
Use Cases:
is_active=false, status=active- Temporarily hiddenis_active=true, status=inactive- Invalid state (corrected on save)
Integration Examples¶
Complete Service Creation Flow¶
# 1. Get category templates
curl -X GET https://api.example.com/api/v1/services/categories/templates \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# 2. Check subscription limits
curl -X GET https://api.example.com/api/v1/subscriptions/usage \
-H "Authorization: Bearer YOUR_JWT_TOKEN"
# 3. Create service
curl -X POST https://api.example.com/api/v1/services \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Premium Facial Treatment",
"slug": "premium-facial",
"description": "Luxurious 90-minute facial",
"category": "facial",
"duration_minutes": 90,
"pricing": {
"base_price": 75.00,
"currency": "USD"
},
"is_active": true
}'
# 4. Set outlet pricing
curl -X POST https://api.example.com/api/v1/services/68e63f26241da4ebe30521c8/pricing \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"outlet_prices": {
"68e4f07e1245f30b04760bd5": 85.00
}
}'
Customer Service Discovery Flow¶
# 1. Browse categories
curl -X GET https://api.example.com/api/v1/services/categories \
-H "Authorization: Bearer CUSTOMER_JWT_TOKEN"
# 2. Search services in category
curl -X GET "https://api.example.com/api/v1/services?category=facial&min_price=50&max_price=100" \
-H "Authorization: Bearer CUSTOMER_JWT_TOKEN"
# 3. Get service details
curl -X GET https://api.example.com/api/v1/services/68e63f26241da4ebe30521c8 \
-H "Authorization: Bearer CUSTOMER_JWT_TOKEN"
Best Practices¶
Service Creation¶
✅ DO:
- Use category templates for consistency
- Set realistic duration with preparation/cleanup time
- Provide clear descriptions and tags
- Use high-quality images (recommended: 1200x800px)
- Set appropriate advance booking windows
- Check subscription limits before creation
❌ DON'T:
- Create duplicate services with different slugs
- Use ambiguous category names
- Skip description or image URLs
- Set unrealistic durations
- Create services without checking limits
Category Management¶
✅ DO:
- Configure tenant-specific category templates
- Use lowercase with underscores format
- Keep categories broad enough for grouping
- Provide category descriptions
- Review and update templates as business evolves
❌ DON'T:
- Use too many granular categories
- Mix different naming conventions
- Create categories for single services
- Change categories on heavily-booked services
Pricing Strategy¶
✅ DO:
- Set competitive base prices
- Use outlet pricing for location premiums
- Test promotional pricing before major campaigns
- Document pricing strategy in internal docs
- Review pricing regularly against competition
❌ DON'T:
- Set prices too high without market research
- Change prices frequently (confuses customers)
- Use outlet pricing on FREE plan (will fail)
- Forget to update promotional end dates
Service Lifecycle¶
✅ DO:
- Use
inactivestatus for temporary unavailability - Archive outdated or discontinued services
- Keep historical data for reporting
- Communicate status changes to staff
- Monitor service performance before archiving
❌ DON'T:
- Delete services with active bookings (use inactive)
- Archive popular services without replacement
- Change status without team notification
- Reactivate archived services without review
Error Handling¶
Common Errors¶
| Error Code | Cause | Solution |
|---|---|---|
| 400 Bad Request | Invalid input data | Check field formats and required fields |
| 401 Unauthorized | Missing/invalid token | Verify JWT token is valid |
| 403 Forbidden | Insufficient permissions | Check user role and outlet access |
| 404 Not Found | Service doesn't exist | Verify service ID is correct |
| 409 Conflict | Slug already exists | Use different slug or update existing service |
| 422 Unprocessable Entity | Validation failed | Review validation error details |
Subscription Limit Errors¶
FREE Plan Service Limit:
Solution: Upgrade to PRO or ENTERPRISE plan
Outlet Pricing on FREE Plan:
Solution: Upgrade to PRO or ENTERPRISE plan
Related Documentation¶
- Pricing Management - Comprehensive pricing guide: base pricing, promotional campaigns, outlet-specific pricing, and pricing hierarchy
- Subscription Management - Plan limits and upgrades
- Tenant Management - Category template configuration
- Outlet Management - Outlet-specific settings
- Staff Management - Service provider assignments
- Parallel Booking - Configure group services with capacity limits (e.g., yoga classes, workshops)
- Customer Management - Customer service preferences
API Reference Summary¶
| Endpoint | Method | Purpose | Access | Subscription Limit |
|---|---|---|---|---|
/services |
GET | List services | Staff + Customers | None |
/services |
POST | Create service | Staff | FREE: 10 max, PRO: 50 max |
/services/categories |
GET | List categories | Staff + Customers | None |
/services/categories/templates |
GET | Get templates | Staff + Customers | None |
/services/{id} |
GET | Get details | Staff + Customers | None |
/services/{id} |
PUT | Update service | Staff | None |
/services/{id} |
DELETE | Delete service | TENANT_ADMIN | None |
/services/{id}/pricing |
POST | Set outlet pricing | Staff | PRO+ required |
Next Steps:
- Get category templates:
GET /services/categories/templates - Check subscription limits:
GET /subscriptions/usage - Create your first service:
POST /services - Configure outlet pricing (PRO+):
POST /services/{id}/pricing - Test customer discovery:
GET /services?category=...
For complete API testing, see Swagger UI or ReDoc.