Services API
The Services API provides read-only access to service configurations, pricing, and availability. Use this to display service options in your application.
Base URL
https://api.otesse.com/v1/services
List Industries
GET /v1/services/industries
Returns all active service industries:
{
"data": [
{
"id": "ind_cleaning",
"name": "Residential Cleaning",
"slug": "cleaning",
"description": "Professional home cleaning services",
"icon": "SparklesIcon",
"configuration_type": "room_based",
"is_active": true
},
{
"id": "ind_junk_removal",
"name": "Junk Removal",
"slug": "junk-removal",
"description": "Furniture, appliance, and debris removal",
"icon": "TruckIcon",
"configuration_type": "item_based",
"is_active": true
},
{
"id": "ind_carpet_cleaning",
"name": "Carpet Cleaning",
"slug": "carpet-cleaning",
"description": "Professional carpet, rug, and upholstery cleaning",
"icon": "SwatchIcon",
"configuration_type": "section_based",
"is_active": true
}
]
}
Get Industry Products
GET /v1/services/industries/:slug/products
Returns products grouped by category:
{
"industry": "junk-removal",
"categories": [
{
"id": "pcat_jr_mattress",
"name": "Mattress",
"slug": "mattress",
"products": [
{
"id": "prod_jr_twin_mattress",
"name": "Twin Mattress",
"base_price": 7500,
"description": "Standard twin size mattress removal",
"in_catalog": true
},
{
"id": "prod_jr_full_mattress",
"name": "Full Mattress",
"base_price": 8500,
"description": "Full/double size mattress removal",
"in_catalog": true
}
]
}
]
}
Get Extras
GET /v1/services/industries/:slug/extras
Returns available extras for the industry:
{
"data": [
{
"id": "extra_stairs",
"name": "Stair Carry Fee",
"description": "Per flight of stairs beyond ground floor",
"price": 2500,
"price_type": "per_unit",
"unit_label": "flight"
}
]
}
Check Availability
GET /v1/services/availability
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
zip | string | Yes | Service address ZIP code |
industry | string | Yes | Industry slug |
date | string | Yes | Date to check (YYYY-MM-DD) |
duration | integer | No | Estimated duration in minutes (default: 120) |
Example
curl -X GET "https://api.otesse.com/v1/services/availability?zip=97401&industry=cleaning&date=2026-03-01" \
-H "Authorization: Bearer otesse_live_sk_..."
Response
{
"date": "2026-03-01",
"zone": {
"id": "zone_eugene_metro",
"name": "Eugene Metro"
},
"available_slots": [
{ "start": "08:00", "end": "10:00", "label": "Morning" },
{ "start": "10:00", "end": "12:00", "label": "Late Morning" },
{ "start": "13:00", "end": "15:00", "label": "Afternoon" },
{ "start": "15:00", "end": "17:00", "label": "Late Afternoon" }
],
"fully_booked": false
}
If the ZIP code is not in any active zone, the response returns zone: null with an empty available_slots array.
Get Pricing
POST /v1/services/pricing
Calculate pricing for a specific configuration:
{
"industry": "cleaning",
"zip": "97401",
"configuration": {
"bedrooms": 3,
"bathrooms": 2,
"frequency": "bi-weekly",
"extras": ["inside_oven"]
},
"coupon_code": "FIRST20"
}
Returns a detailed pricing breakdown including base price, zone adjustments, extras, discounts, and estimated tax.
On this page