Developer reference
RoutrIQ API
REST, versioned, predictable. Bearer tokens. Every response is { ok, data, error }.
Authentication
Every request carries Authorization: Bearer ROUTRIQ_API_KEY. Keys are scoped to a single organization and issued from Dashboard → API Keys. Revoke and rotate via /api/v1/auth/apikeys.
Core endpoints
POST /api/v1/jobs — create or upsert a job GET /api/v1/jobs — list jobs for your org POST /api/v1/technicians — create or upsert a technician GET /api/v1/technicians — list active technicians POST /api/v1/dispatch/assign — AI-score and assign a job POST /api/v1/dispatch/emergency — emergency reroute (priority 1) GET /api/v1/dispatch/schedule — day-view route plan POST /api/v1/prediction/duration — estimate job completion time GET /api/v1/sla/at-risk — jobs at risk of missing window POST /api/v1/simulation/run — scenario modeler POST /api/v1/learning/run — trigger weight retrain
FSM Integration endpoints
Native connectors for ServiceTitan, Jobber, and Housecall Pro. Each provider exposes the same three sync routes — credentials are stored encrypted per org.
POST /api/v1/integrations/{provider}/sync — pull jobs
POST /api/v1/integrations/{provider}/sync-technicians — pull roster
POST /api/v1/integrations/{provider}/verify — test credentials
# Providers: servicetitan | jobber | housecallpro
# Inbound webhooks (ServiceTitan):
POST /api/v1/integrations/servicetitan/webhook — HMAC-verified eventsExplainable assignment response
Every assignment carries a scored breakdown of why that technician ranked #1. The weightsVersion pin means any decision can be replayed against the exact model that made it.
{
"assignments": [
{
"technicianId": "4a7c...",
"score": 87.4,
"rank": 1,
"reason": {
"skill_match": 1.0,
"distance_score": 0.88,
"priority_weight": 1.0,
"performance": 0.92,
"availability": 1.0,
"predicted_duration_minutes": 72,
"delay_risk": 0.08
},
"weightsVersion": 14
}
]
}Integrations — credential format
Store credentials via POST /api/v1/integrations, then verify with the provider-specific verify route. Credentials are AES-256-GCM encrypted at rest.
# ServiceTitan
{ "provider": "servicetitan", "label": "Primary",
"credentials": { "client_id": "...", "client_secret": "...",
"tenant_id": "...", "app_key": "..." } }
# Jobber
{ "provider": "jobber", "label": "Primary",
"credentials": { "access_token": "...", "refresh_token": "..." } }
# Housecall Pro
{ "provider": "housecallpro", "label": "Primary",
"credentials": { "api_token": "..." } }Rate limits & errors
Burst: 60 requests / minute per API key (Upstash sliding window). Exceeding the limit returns 429 with a Retry-After header. All errors follow { ok: false, error: "snake_case_code" }.