EcoService OS Booking API
A multi-tenant REST API any AI voice agent, chatbot or partner app can call to schedule field-service work. Every response carries a request_id, and every customer-facing response carries a voice_speak sentence your agent can read aloud verbatim.
Authentication
Send your tenant key as Authorization: Bearer esk_live_… (or X-API-Key). Keys are scoped per capability and optionally per brand, rate limited to 60 requests per minute, and issued from Workspace → Booking API keys. Base URL: https://ecoserviceos.ecopowerhub.ai/api/public/v1 (the shorthand /v1/… also works).
Endpoints
| Method | Path | Summary | Scope |
|---|---|---|---|
| GET | /v1/health | Liveness probe (no auth) | — |
| GET | /v1/me | Tenant profile, timezone, service ZIPs | any |
| GET | /v1/job-types | Bookable job types for a brand | availability:read |
| POST | /v1/customers/upsert | Match by phone, then email | customers:write |
| GET | /v1/availability | Up to 8 arrival windows | availability:read |
| POST | /v1/bookings | Create a booking or emergency request | bookings:write |
| GET | /v1/bookings | List bookings | bookings:read |
| GET | /v1/bookings/{id} | Fetch one booking | bookings:read |
| POST | /v1/bookings/{id}/cancel | Cancel a booking | bookings:write |
| POST | /v1/bookings/{id}/notify | Queue confirmation / reminder | bookings:write |
| POST | /v1/leads | Capture an out-of-area or non-truck lead | bookings:write |
Offer windows
curl -s https://ecoserviceos.ecopowerhub.ai/api/public/v1/availability \
-H "Authorization: Bearer esk_live_..." \
-G --data-urlencode "brand=ecoservice_os" \
--data-urlencode "job_type=appliance-repair" \
--data-urlencode "zip=21201"Book the window
Send an Idempotency-Key (the call id works well) so a retried request replays the same booking instead of creating a second truck roll.
curl -s -X POST https://ecoserviceos.ecopowerhub.ai/api/public/v1/bookings \
-H "Authorization: Bearer esk_live_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: call_8837" \
-d '{
"brand": "ecoservice_os",
"job_type": "appliance-repair",
"window_start": "2026-09-02T12:00:00Z",
"appliance": "refrigerator",
"symptom": "not cooling",
"consent_sms": true,
"source": "voice_agent",
"customer": {
"name": "Dana Reed",
"phone": "+14105550101",
"address_line1": "18 Charles St",
"city": "Baltimore",
"state": "MD",
"zip": "21201"
}
}'Voice contract
voice_speakis always a single spoken sentence — read it verbatim.OUT_OF_AREA→ offer to capture a lead viaPOST /v1/leads.SLOT_TAKEN→ re-call/v1/availabilityand offer the next two windows.MISSING_PHONE/MISSING_ADDRESS→ ask for exactly the missing field.- Emergencies never book a window; they return status
requestedand fire thebooking.emergencywebhook.
Agent tool template
Paste into Retell, Vapi, ElevenLabs or an OpenAI function-tool definition.
{
"name": "check_availability",
"description": "Get up to 8 arrival windows for a service brand, job type and ZIP code.",
"url": "https://ecoserviceos.ecopowerhub.ai/api/public/v1/availability",
"method": "GET",
"headers": { "Authorization": "Bearer {{ECOSERVICE_API_KEY}}" },
"parameters": {
"type": "object",
"required": ["brand", "job_type", "zip"],
"properties": {
"brand": { "type": "string", "enum": ["ecoservice_os","fixgrid","repair","academy","diy","sales"] },
"job_type": { "type": "string" },
"zip": { "type": "string" }
}
},
"speak_field": "voice_speak"
}Webhooks
Events: booking.created, booking.booked, booking.emergency, booking.canceled, lead.created. Each delivery is signed with HMAC-SHA256 over `${timestamp}.${rawBody}` and sent as x-ecoservice-signature: sha256=<hex>.