DEVELOPER DOCUMENTATION

Nemtix Scheduler API

REST + JSON scheduling for NEMT applications. API version 1.0.

Quick start

Every customer receives a tenant-scoped API key and one or more provider IDs. Send the key in the X-Nemtix-Api-Key header.

curl -X POST https://api.nemtix.com/api/v1/schedules/optimize \
  -H "X-Nemtix-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @schedule.json

Authentication

Do not put API keys in URLs. Keep production credentials on your server. Requests are authorized against both the API key's tenant and the submitted providerId.

X-Nemtix-Api-Key: nemtix_...

Endpoints

POST /api/v1/schedules/validateValidate the request contract without optimization.POST /api/v1/schedules/analyzeCompatibility and routing diagnostics.POST /api/v1/schedules/feasibilityHard-constraint insertion feasibility.POST /api/v1/schedules/optimizeCreate an optimized schedule synchronously.POST /api/v1/schedule-jobsSubmit an asynchronous schedule job.GET /api/v1/schedule-jobs/{jobId}Read job status.GET /api/v1/schedule-jobs/{jobId}/resultRetrieve the completed result.

Schedule request

The top-level request includes API version, request ID, provider, service date, IANA time zone, optimization profile, drivers and trips. The scheduling contract does not require patient name, DOB, phone, SSN, member ID, diagnosis or clinical information.

{
  "apiVersion": "1.0",
  "requestId": "sample-20260915-001",
  "providerId": "5332",
  "serviceDate": "2026-09-15",
  "timeZone": "America/Indiana/Indianapolis",
  "optimizationProfile": "balanced",
  "drivers": [{
    "driverId": "D-1",
    "active": true,
    "vehicleType": "AMB",
    "capacity": { "ambulatory": 4, "wheelchair": 0 },
    "skills": ["TX3"],
    "vehicleCapabilities": [],
    "territories": ["INDIANAPOLIS"],
    "shift": { "start": "2026-09-15T06:30:00-04:00", "end": "2026-09-15T15:00:00-04:00" },
    "breaks": [],
    "startLocation": { "latitude": 39.7743, "longitude": -86.0977 },
    "endLocation": { "latitude": 39.7743, "longitude": -86.0977 },
    "returnToEndLocation": true,
    "labels": []
  }],
  "trips": [{
    "tripId": "T-1",
    "legType": "standalone",
    "serviceType": "AMB",
    "priority": 10,
    "territory": "INDIANAPOLIS",
    "areaClassification": "urban",
    "pickup": { "latitude": 39.7684, "longitude": -86.1581 },
    "dropoff": { "latitude": 39.8404, "longitude": -86.1434 },
    "pickupWindow": { "earliest": "2026-09-15T07:05:00-04:00", "latest": "2026-09-15T07:20:00-04:00" },
    "hasToPickupByDateTime": "2026-09-15T07:20:00-04:00",
    "maxRideMinutes": 75,
    "passengerLoad": { "ambulatory": 1, "wheelchair": 0 },
    "wheelchair": { "required": false, "widthInches": null },
    "requiredDriverSkills": ["TX3"],
    "requiredVehicleCapabilities": [],
    "mustRideAlone": false,
    "allowMultiLoad": true,
    "excludedDriverIds": [],
    "isWillCall": false,
    "labels": []
  }]
}

Optimize response

A successful optimize response includes run/version identifiers, effective optimization settings, summary metrics, driver routes, flattened assignments, unassigned trips with structured reason codes, warnings and optional diagnostics. Response headers include X-Nemtix-Request-Id, X-Nemtix-Run-Id, X-Nemtix-Engine-Version and commercial plan information.

Async jobs

For larger runs, submit the same scheduling payload to POST /api/v1/schedule-jobs. Use your caller-supplied requestId for idempotent lookup and poll status until the job is completed or failed.

POST /api/v1/schedule-jobs
GET  /api/v1/schedule-jobs/by-request?requestId=sample-20260915-001
GET  /api/v1/schedule-jobs/{jobId}
GET  /api/v1/schedule-jobs/{jobId}/result
DELETE /api/v1/schedule-jobs/{jobId}

Error handling

Integrations should key off stable machine-readable code values rather than human-readable messages.

INVALID_SCHEDULE_REQUESTRequest/model validation failed.RATE_LIMIT_EXCEEDEDRequest-rate ceiling exceeded.TRIAL_TRIP_LIMIT_EXCEEDEDThe total Free Trial trip allowance is exhausted.MONTHLY_TRIP_LIMIT_EXCEEDEDThe paid plan's monthly trip allowance is exhausted.TRIAL_EXPIREDThe trial period ended.ROUTING_PROVIDER_UNAVAILABLEThe routing dependency could not complete the request.

Plan limits

Billable usage is based primarily on trips processed by optimize and new async job submissions. Read-only polling, validation and documentation requests do not consume trip allowance.

PlanTripsProvidersKeysConcurrent jobs
Free Trial500 total / 14 days112
Starter10,000/mo222
Growth50,000/mo554
Professional150,000/mo15108
EnterpriseUnlimited / contract502520

Time handling

Use offset-aware ISO 8601 timestamps and supply the provider operational IANA timeZone. Nemtix distinguishes target pickup/appointment values from explicit pickup/dropoff windows and hard hasToPickupByDateTime deadlines.

Language examples

C#

using var http = new HttpClient();
http.DefaultRequestHeaders.Add("X-Nemtix-Api-Key", apiKey);
using var response = await http.PostAsJsonAsync(
    "https://api.nemtix.com/api/v1/schedules/optimize", request);
response.EnsureSuccessStatusCode();

Python

response = requests.post(
    "https://api.nemtix.com/api/v1/schedules/optimize",
    headers={"X-Nemtix-Api-Key": api_key},
    json=schedule,
    timeout=600,
)
response.raise_for_status()

JavaScript

const response = await fetch(
  "https://api.nemtix.com/api/v1/schedules/optimize",
  { method: "POST", headers: {
      "Content-Type": "application/json",
      "X-Nemtix-Api-Key": apiKey
    }, body: JSON.stringify(schedule) });