{"openapi":"3.1.0","info":{"title":"AtlasCare Transportation API","version":"1.0.0","summary":"Check availability, get pricing, and submit trip requests for AtlasCare Transport’s private, non-emergency medical transportation service.","description":"Plain JSON over HTTPS for AI agents, facility systems, and other integrations that need to check availability, get pricing, or submit a trip request on a person’s behalf. Vendor-neutral by design — no proprietary agent-framework or plugin format required. Human-readable documentation with worked examples: https://www.atlascaretransport.com/developers/transportation-api. Service area: McMinnville, Oregon and Yamhill County, with regional trips to the greater Portland and Salem areas — requests outside this area are still accepted and routed to manual review rather than rejected. Important: REQUEST_TRIP never creates a confirmed, paid reservation by itself — it enters AtlasCare’s normal staff review workflow. There is no public, unauthenticated CONFIRM_BOOKING action.","contact":{"email":"support@atlascaretransport.com","url":"https://www.atlascaretransport.com/developers/transportation-api"}},"servers":[{"url":"https://www.atlascaretransport.com","description":"Production"}],"tags":[{"name":"Availability","description":"CHECK_AVAILABILITY"},{"name":"Pricing","description":"GET_PRICE"},{"name":"Trip Requests","description":"REQUEST_TRIP and status"},{"name":"Configuration","description":"Public, read-only pricing configuration."}],"paths":{"/api/v1/availability":{"post":{"operationId":"checkAvailability","summary":"CHECK_AVAILABILITY — does AtlasCare appear able to serve this pickup window?","description":"Checks the requested pickup_datetime against AtlasCare's published ride-fulfillment service hours (rules.service_hours in GET /api/v1/config — Monday–Saturday 4:00 AM to 8:00 PM Pacific, deliberately wider than the hours staff answer the phone) and any staff-entered calendar overrides for that date (most-restrictive override wins; an override can also open a time the standard hours would refuse). Availability and pricing are deliberately separate so either can be checked independently (e.g. a phone agent confirming a window is possible before quoting). Does not calculate a price. Send trip_type: \"round_trip\" (with return_type and, where relevant, scheduled_return_time / scheduled_return_datetime / requested_wait_minutes) to have the RETURN leg checked as well; the verdict comes back in return_leg. Because no price is calculated here there is no routed drive time to work from, so a Wait & Return or Will Call return is estimated from the trip's own timings and reported with basis \"assumed\" — use /api/v1/trip-options when you want the return judged against real drive times. Known limitation: this is not a live booking ledger. Staff mark a window available only when a vehicle and driver can cover it, but submitting a request does not consume that capacity, and dates past the maintained calendar horizon fall back to standard service hours. An available result is AtlasCare's expectation that it can serve the trip, not a held vehicle. If the check itself fails internally (e.g. a transient error), the response is a 200 with status: \"manual_review\" — never unavailable or a 5xx — so a technical failure is never presented as a confirmed lack of availability.","tags":["Availability"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["pickup_datetime"],"properties":{"pickup_datetime":{"type":"string","format":"date-time","description":"ISO 8601 date-time with an explicit UTC offset. AtlasCare's service area and service hours are defined in the America/Los_Angeles time zone (-07:00 during Pacific Daylight Time, -08:00 during Pacific Standard Time) — send that offset rather than assuming UTC. Must be in the future. Rides run Monday–Saturday, 4:00 AM to 8:00 PM Pacific (the latest pickup, not the latest drop-off); the close of AtlasCare's office at 4:00 PM does not limit when a trip can be scheduled. See rules.service_hours in GET /api/v1/config for the authoritative values.","example":"2026-09-15T08:00:00-07:00"}}}}}},"responses":{"200":{"description":"Availability result. Always 200 — a status of manual_review or unavailable is a valid, expected outcome, not a failure.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["available","limited","manual_review","unavailable"]},"label":{"type":"string"},"message":{"type":"string"},"requested_datetime":{"type":"string","format":"date-time"},"return_leg":{"type":"object","nullable":true,"description":"The return leg of a round trip, judged against AtlasCare's service hours and staff calendar windows. Null for a one-way trip, and null when no round-trip details were sent. The overall availability status already folds this in (most restrictive wins), so a caller that only needs a yes/no can ignore this object — it exists to explain WHY, and how much the answer can be trusted.","properties":{"status":{"type":"string","enum":["available","limited","manual_review","unavailable","unknown"],"description":"\"unknown\" means the return could not be checked — most often a Scheduled Return with no time given. An unknown return never downgrades the overall status; it is reported so a caller can ask for the missing detail rather than being told the trip needs review over an optional field. A return that falls outside service hours resolves to manual_review rather than unavailable, because AtlasCare would usually take that trip after a quick conversation; only a staff calendar window explicitly marked unavailable produces \"unavailable\"."},"reason_code":{"type":"string","nullable":true,"description":"RETURN_OUTSIDE_SERVICE_HOURS, RETURN_ON_CLOSED_DAY, RETURN_WINDOW_STAFF_OVERRIDE (the vehicle would be committed across a period staff blocked out), RETURN_STAFF_OVERRIDE, or RETURN_TIME_UNKNOWN. Null when the return leg is fine."},"message":{"type":"string","description":"Customer-safe explanation. Never names drivers, other passengers or internal calendar detail."},"estimated_return_datetime":{"type":"string","format":"date-time","nullable":true,"description":"When AtlasCare expects the vehicle to be free again. Null when the return time is unknown."},"basis":{"type":"string","enum":["stated","computed","assumed","unknown"],"description":"How that time was arrived at, and the field to check before repeating it to anyone. \"stated\" = the requester's own return time. \"computed\" = derived from an appointment length they gave. \"assumed\" = AtlasCare's planning assumption, used for Will Call (which has no committed end time) and for a Wait & Return with no stated appointment length. \"unknown\" = not established. Never present \"assumed\" or \"unknown\" to a passenger as a confirmed return time."}}}}}}}},"400":{"description":"One or more required fields are missing or invalid, or the request body could not be read. The error string always spells out exactly which fields (e.g. \"pickup_address is required. mobility_type must be one of: wheelchair, ambulatory, not_sure.\") — an agent should surface those specific fields back to the requester rather than a generic failure. reason_code is one of VALIDATION_FAILED (one or more fields), MISSING_FIELD (a single required field), INVALID_DATETIME, PAST_DATETIME, or INVALID_JSON.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}},"413":{"description":"Request body exceeded the size limit.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}},"429":{"description":"Rate limit exceeded for this endpoint's bucket (response body reason_code: \"RATE_LIMITED\"). Back off for Retry-After seconds before retrying — see /developers/transportation-api \"Rate Limiting & Fair Use\", or read the current numbers live from GET /api/v1/config (rate_limits).","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}}}}},"/api/v1/quote":{"post":{"operationId":"getPrice","summary":"GET_PRICE — calculate pricing only, no availability check","description":"Calculates an ESTIMATE from AtlasCare's standard posted pricing tiers (by one-way driving mileage), plus Wait & Return time included in that tier and its per-additional-block overage rate, plus any equipment charges (see equipment_charges) — not a confirmed price until AtlasCare staff reviews the request. Returns a signed, time-limited (72-hour) quote token. Pass it to REQUEST_TRIP so the estimate a customer saw is the one AtlasCare reviews, instead of being silently recalculated from a since-changed rate.","tags":["Pricing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["pickup_address","destination_address","pickup_datetime","mobility_type","trip_type"],"properties":{"pickup_address":{"type":"object","description":"A street address. A formatted string alone is enough — AtlasCare will geocode it — but lat/lng (e.g. already resolved via Google Places) skips that step.","properties":{"formatted":{"type":"string","description":"Full, human-readable address.","example":"2700 NW Stewart Pkwy, McMinnville, OR"},"lat":{"type":"number"},"lng":{"type":"number"},"place_id":{"type":"string","description":"Google Places place_id, if this address was resolved via Places Autocomplete."},"place_name":{"type":"string","description":"Facility/POI name, if the address represents a named place (e.g. a hospital) rather than a bare street address."},"source":{"type":"string","enum":["google","manual"],"description":"How this address was captured — informational only, never consulted by routing or pricing."}},"required":["formatted"]},"destination_address":{"type":"object","description":"A street address. A formatted string alone is enough — AtlasCare will geocode it — but lat/lng (e.g. already resolved via Google Places) skips that step.","properties":{"formatted":{"type":"string","description":"Full, human-readable address.","example":"2700 NW Stewart Pkwy, McMinnville, OR"},"lat":{"type":"number"},"lng":{"type":"number"},"place_id":{"type":"string","description":"Google Places place_id, if this address was resolved via Places Autocomplete."},"place_name":{"type":"string","description":"Facility/POI name, if the address represents a named place (e.g. a hospital) rather than a bare street address."},"source":{"type":"string","enum":["google","manual"],"description":"How this address was captured — informational only, never consulted by routing or pricing."}},"required":["formatted"]},"pickup_datetime":{"type":"string","format":"date-time","description":"ISO 8601 date-time with an explicit UTC offset. AtlasCare's service area and service hours are defined in the America/Los_Angeles time zone (-07:00 during Pacific Daylight Time, -08:00 during Pacific Standard Time) — send that offset rather than assuming UTC. Must be in the future. Rides run Monday–Saturday, 4:00 AM to 8:00 PM Pacific (the latest pickup, not the latest drop-off); the close of AtlasCare's office at 4:00 PM does not limit when a trip can be scheduled. See rules.service_hours in GET /api/v1/config for the authoritative values.","example":"2026-09-15T08:00:00-07:00"},"mobility_type":{"type":"string","enum":["wheelchair","ambulatory","not_sure"]},"trip_type":{"type":"string","enum":["one_way","round_trip"]},"return_type":{"type":"string","enum":["wait_and_return","scheduled_return","will_call"],"description":"Only meaningful when trip_type is round_trip. wait_and_return = vehicle/driver wait at the appointment; scheduled_return = a separate pickup at a specific later time (send it in scheduled_return_time); will_call = passenger calls when ready, return timing unknown in advance. Omitting it on a round trip does not fail the request — it is flagged for manual review instead. The return leg is checked against AtlasCare's service hours and staff calendar windows, and the verdict comes back as availability.return_leg; how confident that verdict is depends on its `basis` (see that object). Both ends are judged against the same staff-maintained calendar, in which a window is marked available only when a vehicle and driver can cover it — but nothing consumes capacity when a request is submitted, so an available result is an expectation, not a held vehicle.","nullable":true},"scheduled_return_time":{"type":"string","description":"Requested return pickup time as 24-hour HH:MM, when return_type is scheduled_return. It carries no date: AtlasCare resolves it against the pickup's date in America/Los_Angeles. A time EARLIER than the pickup is read as the following day, since on a same-day round trip that is the only thing it can mean — send scheduled_return_datetime instead when the date should be explicit. Ignored for any other return_type.","example":"15:30","nullable":true},"scheduled_return_datetime":{"type":"string","format":"date-time","description":"Full ISO 8601 return pickup instant with an explicit UTC offset — the unambiguous alternative to scheduled_return_time, and the way to express a return on a different calendar day (an overnight transfer, a next-day discharge). Takes precedence when both are sent. Must be after pickup_datetime; unlike the time-only field there is nothing to infer, so an earlier value is rejected rather than shifted.","example":"2026-09-15T09:00:00-07:00","nullable":true},"wait_location":{"type":"string","enum":["vehicle","facility_waiting_area","other_agreed_location","not_sure"],"description":"Where the driver waits during a Wait & Return trip. Only stored when return_type is wait_and_return.","nullable":true},"wait_location_notes":{"type":"string","description":"Optional free-text detail for the wait location (e.g. \"Main lobby near reception\"). Max 200 characters, stored only with wait_and_return.","nullable":true},"requested_wait_minutes":{"type":"integer","minimum":0,"description":"Expected appointment length in minutes on a Wait & Return trip — how long the vehicle and driver stay committed. Each pricing tier includes a waiting window (30 or 60 minutes, see included_wait_minutes in GET /api/v1/config); time beyond it is charged in fixed increments at the posted rate, and a quote reflects that automatically. Omit it when the length is genuinely unknown: the quote is then the plain round-trip fare with no waiting charge, which is also what a customer sees who answers \"not sure\". Ignored for any other return_type.","example":90,"nullable":true},"broda_required":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["yes","no","unsure"]}],"description":"Whether an Advanced Positioning Chair (BRODA Traversa) is needed. Accepts true/false or yes/no/unsure."}}}}}},"responses":{"200":{"description":"Quote result. Returns 200 with status: manual_review (not an error) when a price cannot be calculated automatically — e.g. routing failed.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","nullable":true,"description":"Quote ID, e.g. ATQ-260915-A7K4. Null only when pricing could not be calculated at all."},"token":{"type":"string","nullable":true,"description":"Opaque signed token. Pass this to REQUEST_TRIP as quote_token so the price a customer saw is the price AtlasCare reviews, instead of being recalculated (possibly against a since-changed rate)."},"status":{"type":"string","enum":["estimated","manual_review","confirmed","expired"],"description":"estimated = calculated from AtlasCare's standard posted pricing rules — not yet confirmed by staff. manual_review = one or more trip details need a human to confirm pricing (special equipment, unusual mileage, an incomplete return arrangement) — not a failure. confirmed = reserved for a future state once AtlasCare has explicitly confirmed a price with the customer; GET_PRICE and the combined lookup never return this today. expired = the quote token's validity window has passed."},"serviceable":{"type":"boolean"},"currency":{"type":"string","example":"USD"},"pricing_tier":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"label":{"type":"string"},"minMiles":{"type":"number"},"maxMiles":{"type":"number"}}},"one_way_miles":{"type":"number","nullable":true},"duration_minutes":{"type":"number","nullable":true},"one_way_price":{"type":"number","nullable":true},"round_trip_price":{"type":"number","nullable":true},"included_wait_minutes":{"type":"integer","nullable":true},"additional_wait_rate":{"type":"object","nullable":true,"properties":{"amount":{"type":"number"},"minutes":{"type":"integer"}},"description":"e.g. { amount: 20, minutes: 15 } = $20 per additional 15 minutes."},"equipment_charges":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"amount":{"type":"number"}}}},"total":{"type":"number","nullable":true},"reasons":{"type":"array","items":{"type":"string","enum":["ROUTE_LOOKUP_FAILED","OUTSIDE_SERVICE_AREA","MILEAGE_BEYOND_POSTED_TIERS","SPECIAL_EQUIPMENT","UNSUPPORTED_RETURN_TYPE","NONSTANDARD_TRIP","INCOMPLETE_TRIP_DETAILS"]},"description":"Machine-readable reason code(s) behind a manual_review status or an unserviceable trip."},"disclosures":{"type":"array","items":{"type":"string"},"description":"Human-readable notes worth surfacing to whoever this quote is for."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"}}}}}},"400":{"description":"One or more required fields are missing or invalid, or the request body could not be read. The error string always spells out exactly which fields (e.g. \"pickup_address is required. mobility_type must be one of: wheelchair, ambulatory, not_sure.\") — an agent should surface those specific fields back to the requester rather than a generic failure. reason_code is one of VALIDATION_FAILED (one or more fields), MISSING_FIELD (a single required field), INVALID_DATETIME, PAST_DATETIME, or INVALID_JSON.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}},"413":{"description":"Request body exceeded the size limit.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}},"429":{"description":"Rate limit exceeded for this endpoint's bucket (response body reason_code: \"RATE_LIMITED\"). Back off for Retry-After seconds before retrying — see /developers/transportation-api \"Rate Limiting & Fair Use\", or read the current numbers live from GET /api/v1/config (rate_limits).","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}}}}},"/api/v1/trip-options":{"post":{"operationId":"checkAvailabilityAndPrice","summary":"Combined lookup (recommended for most integrations) — availability + pricing in one call","description":"Calls availability and pricing together and returns one customer-facing result — the same endpoint AtlasCare’s own Check Availability & Pricing page uses. Same request shape as GET_PRICE.","tags":["Availability","Pricing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["pickup_address","destination_address","pickup_datetime","mobility_type","trip_type"],"properties":{"pickup_address":{"type":"object","description":"A street address. A formatted string alone is enough — AtlasCare will geocode it — but lat/lng (e.g. already resolved via Google Places) skips that step.","properties":{"formatted":{"type":"string","description":"Full, human-readable address.","example":"2700 NW Stewart Pkwy, McMinnville, OR"},"lat":{"type":"number"},"lng":{"type":"number"},"place_id":{"type":"string","description":"Google Places place_id, if this address was resolved via Places Autocomplete."},"place_name":{"type":"string","description":"Facility/POI name, if the address represents a named place (e.g. a hospital) rather than a bare street address."},"source":{"type":"string","enum":["google","manual"],"description":"How this address was captured — informational only, never consulted by routing or pricing."}},"required":["formatted"]},"destination_address":{"type":"object","description":"A street address. A formatted string alone is enough — AtlasCare will geocode it — but lat/lng (e.g. already resolved via Google Places) skips that step.","properties":{"formatted":{"type":"string","description":"Full, human-readable address.","example":"2700 NW Stewart Pkwy, McMinnville, OR"},"lat":{"type":"number"},"lng":{"type":"number"},"place_id":{"type":"string","description":"Google Places place_id, if this address was resolved via Places Autocomplete."},"place_name":{"type":"string","description":"Facility/POI name, if the address represents a named place (e.g. a hospital) rather than a bare street address."},"source":{"type":"string","enum":["google","manual"],"description":"How this address was captured — informational only, never consulted by routing or pricing."}},"required":["formatted"]},"pickup_datetime":{"type":"string","format":"date-time","description":"ISO 8601 date-time with an explicit UTC offset. AtlasCare's service area and service hours are defined in the America/Los_Angeles time zone (-07:00 during Pacific Daylight Time, -08:00 during Pacific Standard Time) — send that offset rather than assuming UTC. Must be in the future. Rides run Monday–Saturday, 4:00 AM to 8:00 PM Pacific (the latest pickup, not the latest drop-off); the close of AtlasCare's office at 4:00 PM does not limit when a trip can be scheduled. See rules.service_hours in GET /api/v1/config for the authoritative values.","example":"2026-09-15T08:00:00-07:00"},"mobility_type":{"type":"string","enum":["wheelchair","ambulatory","not_sure"]},"trip_type":{"type":"string","enum":["one_way","round_trip"]},"return_type":{"type":"string","enum":["wait_and_return","scheduled_return","will_call"],"description":"Only meaningful when trip_type is round_trip. wait_and_return = vehicle/driver wait at the appointment; scheduled_return = a separate pickup at a specific later time (send it in scheduled_return_time); will_call = passenger calls when ready, return timing unknown in advance. Omitting it on a round trip does not fail the request — it is flagged for manual review instead. The return leg is checked against AtlasCare's service hours and staff calendar windows, and the verdict comes back as availability.return_leg; how confident that verdict is depends on its `basis` (see that object). Both ends are judged against the same staff-maintained calendar, in which a window is marked available only when a vehicle and driver can cover it — but nothing consumes capacity when a request is submitted, so an available result is an expectation, not a held vehicle.","nullable":true},"scheduled_return_time":{"type":"string","description":"Requested return pickup time as 24-hour HH:MM, when return_type is scheduled_return. It carries no date: AtlasCare resolves it against the pickup's date in America/Los_Angeles. A time EARLIER than the pickup is read as the following day, since on a same-day round trip that is the only thing it can mean — send scheduled_return_datetime instead when the date should be explicit. Ignored for any other return_type.","example":"15:30","nullable":true},"scheduled_return_datetime":{"type":"string","format":"date-time","description":"Full ISO 8601 return pickup instant with an explicit UTC offset — the unambiguous alternative to scheduled_return_time, and the way to express a return on a different calendar day (an overnight transfer, a next-day discharge). Takes precedence when both are sent. Must be after pickup_datetime; unlike the time-only field there is nothing to infer, so an earlier value is rejected rather than shifted.","example":"2026-09-15T09:00:00-07:00","nullable":true},"wait_location":{"type":"string","enum":["vehicle","facility_waiting_area","other_agreed_location","not_sure"],"description":"Where the driver waits during a Wait & Return trip. Only stored when return_type is wait_and_return.","nullable":true},"wait_location_notes":{"type":"string","description":"Optional free-text detail for the wait location (e.g. \"Main lobby near reception\"). Max 200 characters, stored only with wait_and_return.","nullable":true},"requested_wait_minutes":{"type":"integer","minimum":0,"description":"Expected appointment length in minutes on a Wait & Return trip — how long the vehicle and driver stay committed. Each pricing tier includes a waiting window (30 or 60 minutes, see included_wait_minutes in GET /api/v1/config); time beyond it is charged in fixed increments at the posted rate, and a quote reflects that automatically. Omit it when the length is genuinely unknown: the quote is then the plain round-trip fare with no waiting charge, which is also what a customer sees who answers \"not sure\". Ignored for any other return_type.","example":90,"nullable":true},"broda_required":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["yes","no","unsure"]}],"description":"Whether an Advanced Positioning Chair (BRODA Traversa) is needed. Accepts true/false or yes/no/unsure."}}}}}},"responses":{"200":{"description":"Combined result.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"serviceable":{"type":"boolean"},"availability":{"type":"object","properties":{"status":{"type":"string","enum":["available","limited","manual_review","unavailable"]},"label":{"type":"string"},"message":{"type":"string"},"requested_datetime":{"type":"string","format":"date-time"},"return_leg":{"type":"object","nullable":true,"description":"The return leg of a round trip, judged against AtlasCare's service hours and staff calendar windows. Null for a one-way trip, and null when no round-trip details were sent. The overall availability status already folds this in (most restrictive wins), so a caller that only needs a yes/no can ignore this object — it exists to explain WHY, and how much the answer can be trusted.","properties":{"status":{"type":"string","enum":["available","limited","manual_review","unavailable","unknown"],"description":"\"unknown\" means the return could not be checked — most often a Scheduled Return with no time given. An unknown return never downgrades the overall status; it is reported so a caller can ask for the missing detail rather than being told the trip needs review over an optional field. A return that falls outside service hours resolves to manual_review rather than unavailable, because AtlasCare would usually take that trip after a quick conversation; only a staff calendar window explicitly marked unavailable produces \"unavailable\"."},"reason_code":{"type":"string","nullable":true,"description":"RETURN_OUTSIDE_SERVICE_HOURS, RETURN_ON_CLOSED_DAY, RETURN_WINDOW_STAFF_OVERRIDE (the vehicle would be committed across a period staff blocked out), RETURN_STAFF_OVERRIDE, or RETURN_TIME_UNKNOWN. Null when the return leg is fine."},"message":{"type":"string","description":"Customer-safe explanation. Never names drivers, other passengers or internal calendar detail."},"estimated_return_datetime":{"type":"string","format":"date-time","nullable":true,"description":"When AtlasCare expects the vehicle to be free again. Null when the return time is unknown."},"basis":{"type":"string","enum":["stated","computed","assumed","unknown"],"description":"How that time was arrived at, and the field to check before repeating it to anyone. \"stated\" = the requester's own return time. \"computed\" = derived from an appointment length they gave. \"assumed\" = AtlasCare's planning assumption, used for Will Call (which has no committed end time) and for a Wait & Return with no stated appointment length. \"unknown\" = not established. Never present \"assumed\" or \"unknown\" to a passenger as a confirmed return time."}}}}},"quote":{"type":"object","properties":{"id":{"type":"string","nullable":true,"description":"Quote ID, e.g. ATQ-260915-A7K4. Null only when pricing could not be calculated at all."},"token":{"type":"string","nullable":true,"description":"Opaque signed token. Pass this to REQUEST_TRIP as quote_token so the price a customer saw is the price AtlasCare reviews, instead of being recalculated (possibly against a since-changed rate)."},"status":{"type":"string","enum":["estimated","manual_review","confirmed","expired"],"description":"estimated = calculated from AtlasCare's standard posted pricing rules — not yet confirmed by staff. manual_review = one or more trip details need a human to confirm pricing (special equipment, unusual mileage, an incomplete return arrangement) — not a failure. confirmed = reserved for a future state once AtlasCare has explicitly confirmed a price with the customer; GET_PRICE and the combined lookup never return this today. expired = the quote token's validity window has passed."},"serviceable":{"type":"boolean"},"currency":{"type":"string","example":"USD"},"pricing_tier":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"label":{"type":"string"},"minMiles":{"type":"number"},"maxMiles":{"type":"number"}}},"one_way_miles":{"type":"number","nullable":true},"duration_minutes":{"type":"number","nullable":true},"one_way_price":{"type":"number","nullable":true},"round_trip_price":{"type":"number","nullable":true},"included_wait_minutes":{"type":"integer","nullable":true},"additional_wait_rate":{"type":"object","nullable":true,"properties":{"amount":{"type":"number"},"minutes":{"type":"integer"}},"description":"e.g. { amount: 20, minutes: 15 } = $20 per additional 15 minutes."},"equipment_charges":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"amount":{"type":"number"}}}},"total":{"type":"number","nullable":true},"reasons":{"type":"array","items":{"type":"string","enum":["ROUTE_LOOKUP_FAILED","OUTSIDE_SERVICE_AREA","MILEAGE_BEYOND_POSTED_TIERS","SPECIAL_EQUIPMENT","UNSUPPORTED_RETURN_TYPE","NONSTANDARD_TRIP","INCOMPLETE_TRIP_DETAILS"]},"description":"Machine-readable reason code(s) behind a manual_review status or an unserviceable trip."},"disclosures":{"type":"array","items":{"type":"string"},"description":"Human-readable notes worth surfacing to whoever this quote is for."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"}}},"request_trip_url":{"type":"string","description":"A link to AtlasCare’s Check Availability & Pricing page, prefilled with every field from this request plus the quote id/token — a person handed this link lands on a wizard with their trip already filled in instead of retyping it. An integration that already has the quote token from this same response can also submit REQUEST_TRIP directly instead of sending a person through this link."}}}}}},"400":{"description":"One or more required fields are missing or invalid, or the request body could not be read. The error string always spells out exactly which fields (e.g. \"pickup_address is required. mobility_type must be one of: wheelchair, ambulatory, not_sure.\") — an agent should surface those specific fields back to the requester rather than a generic failure. reason_code is one of VALIDATION_FAILED (one or more fields), MISSING_FIELD (a single required field), INVALID_DATETIME, PAST_DATETIME, or INVALID_JSON.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}},"413":{"description":"Request body exceeded the size limit.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}},"429":{"description":"Rate limit exceeded for this endpoint's bucket (response body reason_code: \"RATE_LIMITED\"). Back off for Retry-After seconds before retrying — see /developers/transportation-api \"Rate Limiting & Fair Use\", or read the current numbers live from GET /api/v1/config (rate_limits).","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}}}}},"/api/v1/trip-requests":{"post":{"operationId":"requestTrip","summary":"REQUEST_TRIP — submit a trip request into AtlasCare’s staff review workflow","description":"Creates a trip request for AtlasCare staff to review — never a confirmed, paid reservation by itself. Include the quote_token from GET_PRICE or the combined lookup so the price shown to your user is the price AtlasCare reviews. Quote tokens are valid for 72 hours from issuance (see expires_at); a missing, expired, or otherwise invalid token does not cause a 4xx here — the trip is silently priced fresh, server-side, at submission time instead (quote_source: \"recalculated\" in the response, vs. \"verified_token\"). Supports an Idempotency-Key header (or idempotency_key body field) to safely retry — a repeated key returns { ok: true, duplicate: true } instead of creating a second request or re-sending notifications. Authorization: standard requests are not gated behind an explicit authorization check — source and requester identify who is submitting, and staff review every request before confirming; the one exception is a recurring-transportation request (see recurring.attestation), which requires an explicit confirmation that the requester is authorized to submit on the passenger’s behalf. Review outcomes: quote_status/availability_status of manual_review mean a person needs to confirm a detail (equipment, mileage, return arrangement, or a safety-answer flag) before scheduling — this is an expected, non-error outcome that should be explained to the requester as \"AtlasCare will follow up to confirm,\" not as a failure or rejection.","tags":["Trip Requests"],"parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string"},"description":"Safely retry a submission without creating a duplicate trip request. Equivalent to the idempotency_key body field."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["source","contact","pickup_address","destination_address","pickup_datetime","mobility_type","trip_type"],"properties":{"source":{"type":"string","enum":["web_wizard","ai_agent","api_partner","facility_portal","phone_agent","staff"],"description":"Required. Identifies what submitted this request — lets AtlasCare staff see, in the same notification email they already read, whether a request came from a person typing into the website’s own wizard or from something acting on a person’s behalf, and gives AtlasCare visibility into how much agent traffic is arriving. Use ai_agent for a general AI agent submitting on a person’s behalf, or api_partner for another kind of third-party integration."},"idempotency_key":{"type":"string","description":"Alternative to the Idempotency-Key header."},"contact":{"type":"object","required":["first_name","last_name"],"properties":{"first_name":{"type":"string"},"last_name":{"type":"string"},"phone":{"type":"string","description":"Required if email is omitted."},"email":{"type":"string","format":"email","description":"Required if phone is omitted."}},"description":"At least one of phone or email is required."},"pickup_address":{"type":"object","description":"A street address. A formatted string alone is enough — AtlasCare will geocode it — but lat/lng (e.g. already resolved via Google Places) skips that step.","properties":{"formatted":{"type":"string","description":"Full, human-readable address.","example":"2700 NW Stewart Pkwy, McMinnville, OR"},"lat":{"type":"number"},"lng":{"type":"number"},"place_id":{"type":"string","description":"Google Places place_id, if this address was resolved via Places Autocomplete."},"place_name":{"type":"string","description":"Facility/POI name, if the address represents a named place (e.g. a hospital) rather than a bare street address."},"source":{"type":"string","enum":["google","manual"],"description":"How this address was captured — informational only, never consulted by routing or pricing."}},"required":["formatted"]},"destination_address":{"type":"object","description":"A street address. A formatted string alone is enough — AtlasCare will geocode it — but lat/lng (e.g. already resolved via Google Places) skips that step.","properties":{"formatted":{"type":"string","description":"Full, human-readable address.","example":"2700 NW Stewart Pkwy, McMinnville, OR"},"lat":{"type":"number"},"lng":{"type":"number"},"place_id":{"type":"string","description":"Google Places place_id, if this address was resolved via Places Autocomplete."},"place_name":{"type":"string","description":"Facility/POI name, if the address represents a named place (e.g. a hospital) rather than a bare street address."},"source":{"type":"string","enum":["google","manual"],"description":"How this address was captured — informational only, never consulted by routing or pricing."}},"required":["formatted"]},"pickup_datetime":{"type":"string","format":"date-time","description":"ISO 8601 date-time with an explicit UTC offset. AtlasCare's service area and service hours are defined in the America/Los_Angeles time zone (-07:00 during Pacific Daylight Time, -08:00 during Pacific Standard Time) — send that offset rather than assuming UTC. Must be in the future. Rides run Monday–Saturday, 4:00 AM to 8:00 PM Pacific (the latest pickup, not the latest drop-off); the close of AtlasCare's office at 4:00 PM does not limit when a trip can be scheduled. See rules.service_hours in GET /api/v1/config for the authoritative values.","example":"2026-09-15T08:00:00-07:00"},"mobility_type":{"type":"string","enum":["wheelchair","ambulatory","not_sure"]},"trip_type":{"type":"string","enum":["one_way","round_trip"]},"return_type":{"type":"string","enum":["wait_and_return","scheduled_return","will_call"],"description":"Only meaningful when trip_type is round_trip. wait_and_return = vehicle/driver wait at the appointment; scheduled_return = a separate pickup at a specific later time (send it in scheduled_return_time); will_call = passenger calls when ready, return timing unknown in advance. Omitting it on a round trip does not fail the request — it is flagged for manual review instead. The return leg is checked against AtlasCare's service hours and staff calendar windows, and the verdict comes back as availability.return_leg; how confident that verdict is depends on its `basis` (see that object). Both ends are judged against the same staff-maintained calendar, in which a window is marked available only when a vehicle and driver can cover it — but nothing consumes capacity when a request is submitted, so an available result is an expectation, not a held vehicle.","nullable":true},"scheduled_return_time":{"type":"string","description":"Requested return pickup time as 24-hour HH:MM, when return_type is scheduled_return. It carries no date: AtlasCare resolves it against the pickup's date in America/Los_Angeles. A time EARLIER than the pickup is read as the following day, since on a same-day round trip that is the only thing it can mean — send scheduled_return_datetime instead when the date should be explicit. Ignored for any other return_type.","example":"15:30","nullable":true},"scheduled_return_datetime":{"type":"string","format":"date-time","description":"Full ISO 8601 return pickup instant with an explicit UTC offset — the unambiguous alternative to scheduled_return_time, and the way to express a return on a different calendar day (an overnight transfer, a next-day discharge). Takes precedence when both are sent. Must be after pickup_datetime; unlike the time-only field there is nothing to infer, so an earlier value is rejected rather than shifted.","example":"2026-09-15T09:00:00-07:00","nullable":true},"wait_location":{"type":"string","enum":["vehicle","facility_waiting_area","other_agreed_location","not_sure"],"description":"Where the driver waits during a Wait & Return trip. Only stored when return_type is wait_and_return.","nullable":true},"wait_location_notes":{"type":"string","description":"Optional free-text detail for the wait location (e.g. \"Main lobby near reception\"). Max 200 characters, stored only with wait_and_return.","nullable":true},"requested_wait_minutes":{"type":"integer","minimum":0,"description":"Expected appointment length in minutes on a Wait & Return trip — how long the vehicle and driver stay committed. Each pricing tier includes a waiting window (30 or 60 minutes, see included_wait_minutes in GET /api/v1/config); time beyond it is charged in fixed increments at the posted rate, and a quote reflects that automatically. Omit it when the length is genuinely unknown: the quote is then the plain round-trip fare with no waiting charge, which is also what a customer sees who answers \"not sure\". Ignored for any other return_type.","example":90,"nullable":true},"broda_required":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["yes","no","unsure"]}],"description":"Whether an Advanced Positioning Chair (BRODA Traversa) is needed. Accepts true/false or yes/no/unsure."},"quote_token":{"type":"string","description":"Token from GET_PRICE or the combined lookup. Strongly recommended — without it, price is recalculated from scratch at submission time."},"requester":{"type":"string","enum":["self","supporter","facility"],"description":"Who the requester is arranging this trip for."},"requester_type":{"type":"string","description":"Normalized buyer persona: individual, family_caregiver or facility. Distinct from requester (which uses self|supporter|facility). Set by the Availability & Pricing wizard and by persona-targeted deep links; carried through to AtlasCare reporting."},"seated_safely":{"type":"string","enum":["yes","unsure","no"],"description":"Whether the passenger can safely remain seated during transport. A \"no\" or \"unsure\" answer never blocks submission — it flags the request for a human to review before scheduling."},"assistance":{"type":"array","items":{"type":"string"},"description":"Free-text checklist of assistance needed (a single string is also accepted)."},"access_concerns":{"type":"array","items":{"type":"string"},"description":"Free-text checklist of access conditions between the vehicle and an accessible entrance."},"companion":{"type":"string","description":"Whether a caregiver/family member is riding along."},"preferred_contact":{"type":"string","enum":["text","email","call"]},"supporter":{"type":"object","nullable":true,"properties":{"passenger_name":{"type":"string"},"relationship":{"type":"string"},"trip_updates":{"type":"string","enum":["yes","no"],"description":"Whether a requester who is not riding along asked to be kept updated on the trip."}},"description":"Set when requester is supporter."},"facility":{"type":"object","nullable":true,"properties":{"name":{"type":"string"},"type":{"type":"string"},"role":{"type":"string"},"department":{"type":"string"},"onsite_contact":{"type":"string"},"patient_ready":{"type":"string"},"discharge_time":{"type":"string"},"payer":{"type":"string"},"patient_name":{"type":"string"},"pickup_room":{"type":"string"}},"description":"Set when requester is facility."},"recurring":{"type":"object","nullable":true,"description":"Set when this is a recurring-transportation request. Day-to-day schedule details (holidays, exceptions) are reconciled by staff, not validated here.","properties":{"start_date":{"type":"string"},"days_of_week":{"type":"array","items":{"type":"string"}},"pickup_time":{"type":"string"},"return_arrangement":{"type":"string"},"return_pickup_time":{"type":"string"},"will_call_expectations":{"type":"string"},"end_type":{"type":"string"},"end_date":{"type":"string"},"expected_quantity":{"type":"string"},"expected_quantity_unit":{"type":"string"},"variations_notes":{"type":"string"},"attestation":{"type":"boolean"}}},"notes":{"type":"string"}}},"example":{"source":"ai_agent","contact":{"first_name":"Jordan","last_name":"Lee","phone":"+15035551234","email":"jordan@example.com"},"pickup_address":{"formatted":"2700 NW Stewart Pkwy, McMinnville, OR"},"destination_address":{"formatted":"3181 SW Sam Jackson Park Rd, Portland, OR"},"pickup_datetime":"2026-09-15T08:00:00-07:00","mobility_type":"wheelchair","trip_type":"round_trip","return_type":"wait_and_return","quote_token":"<token from /api/v1/quote or /api/v1/trip-options>","requester_type":"individual"}}}},"responses":{"200":{"description":"Trip request received.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[true]},"request_id":{"type":"string","example":"ATR-2026-482913"},"status":{"type":"string","example":"received"},"quote_id":{"type":"string","nullable":true},"quote_status":{"type":"string","enum":["estimated","manual_review","confirmed","expired"]},"availability_status":{"type":"string","enum":["available","limited","manual_review","unavailable"]},"return_leg":{"type":"object","nullable":true,"description":"The return leg of a round trip, judged against AtlasCare's service hours and staff calendar windows. Null for a one-way trip, and null when no round-trip details were sent. The overall availability status already folds this in (most restrictive wins), so a caller that only needs a yes/no can ignore this object — it exists to explain WHY, and how much the answer can be trusted.","properties":{"status":{"type":"string","enum":["available","limited","manual_review","unavailable","unknown"],"description":"\"unknown\" means the return could not be checked — most often a Scheduled Return with no time given. An unknown return never downgrades the overall status; it is reported so a caller can ask for the missing detail rather than being told the trip needs review over an optional field. A return that falls outside service hours resolves to manual_review rather than unavailable, because AtlasCare would usually take that trip after a quick conversation; only a staff calendar window explicitly marked unavailable produces \"unavailable\"."},"reason_code":{"type":"string","nullable":true,"description":"RETURN_OUTSIDE_SERVICE_HOURS, RETURN_ON_CLOSED_DAY, RETURN_WINDOW_STAFF_OVERRIDE (the vehicle would be committed across a period staff blocked out), RETURN_STAFF_OVERRIDE, or RETURN_TIME_UNKNOWN. Null when the return leg is fine."},"message":{"type":"string","description":"Customer-safe explanation. Never names drivers, other passengers or internal calendar detail."},"estimated_return_datetime":{"type":"string","format":"date-time","nullable":true,"description":"When AtlasCare expects the vehicle to be free again. Null when the return time is unknown."},"basis":{"type":"string","enum":["stated","computed","assumed","unknown"],"description":"How that time was arrived at, and the field to check before repeating it to anyone. \"stated\" = the requester's own return time. \"computed\" = derived from an appointment length they gave. \"assumed\" = AtlasCare's planning assumption, used for Will Call (which has no committed end time) and for a Wait & Return with no stated appointment length. \"unknown\" = not established. Never present \"assumed\" or \"unknown\" to a passenger as a confirmed return time."}}},"quote_source":{"type":"string","enum":["verified_token","recalculated"]},"message":{"type":"string"},"status_url":{"type":"string","description":"Relative path to the status endpoint below."}}}}}},"400":{"description":"One or more required fields are missing or invalid, or the request body could not be read. The error string always spells out exactly which fields (e.g. \"pickup_address is required. mobility_type must be one of: wheelchair, ambulatory, not_sure.\") — an agent should surface those specific fields back to the requester rather than a generic failure. reason_code is one of VALIDATION_FAILED (one or more fields), MISSING_FIELD (a single required field), INVALID_DATETIME, PAST_DATETIME, or INVALID_JSON.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}},"413":{"description":"Request body exceeded the size limit.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}},"429":{"description":"Rate limit exceeded for this endpoint's bucket (response body reason_code: \"RATE_LIMITED\"). Back off for Retry-After seconds before retrying — see /developers/transportation-api \"Rate Limiting & Fair Use\", or read the current numbers live from GET /api/v1/config (rate_limits).","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}}}}},"/api/v1/trip-requests/{request_id}/status":{"get":{"operationId":"getTripRequestStatus","summary":"Trip request status","description":"Best-effort in V1 — most requests are still followed up on by phone or email. Returns a helpful 200 (status: unknown) rather than a 404 when a request ID isn’t found, since a legitimate request may have come in before status tracking was enabled.","tags":["Trip Requests"],"parameters":[{"name":"request_id","in":"path","required":true,"schema":{"type":"string"},"example":"ATR-2026-482913"}],"responses":{"200":{"description":"Status snapshot (or status: unknown if nothing is on record for this ID).","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"request_id":{"type":"string"},"status":{"type":"string"},"quote_id":{"type":"string","nullable":true},"quote_status":{"type":"string","nullable":true},"availability_status":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","nullable":true},"message":{"type":"string","nullable":true}}}}}},"429":{"description":"Rate limit exceeded for this endpoint's bucket (response body reason_code: \"RATE_LIMITED\"). Back off for Retry-After seconds before retrying — see /developers/transportation-api \"Rate Limiting & Fair Use\", or read the current numbers live from GET /api/v1/config (rate_limits).","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}}}}},"/api/v1/config":{"get":{"operationId":"getPublicPricingConfig","summary":"Public pricing configuration","description":"The same posted pricing tiers, Wait & Return rates, and equipment charges shown on the website — safe to read directly instead of hard-coding AtlasCare’s rates into your own system. Changes rarely; cacheable.","tags":["Configuration"],"responses":{"200":{"description":"Public pricing configuration, including the live rate_limits object.","headers":{"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","description":"See /api/v1/config for the current live shape."}}}},"429":{"description":"Rate limit exceeded for this endpoint's bucket (response body reason_code: \"RATE_LIMITED\"). Back off for Retry-After seconds before retrying — see /developers/transportation-api \"Rate Limiting & Fair Use\", or read the current numbers live from GET /api/v1/config (rate_limits).","headers":{"Retry-After":{"description":"Seconds to wait before retrying.","schema":{"type":"integer"}},"X-RateLimit-Limit":{"description":"Requests allowed per window for this endpoint's rate-limit bucket.","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Seconds until the current window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}}}}}},"components":{"schemas":{"Address":{"type":"object","description":"A street address. A formatted string alone is enough — AtlasCare will geocode it — but lat/lng (e.g. already resolved via Google Places) skips that step.","properties":{"formatted":{"type":"string","description":"Full, human-readable address.","example":"2700 NW Stewart Pkwy, McMinnville, OR"},"lat":{"type":"number"},"lng":{"type":"number"},"place_id":{"type":"string","description":"Google Places place_id, if this address was resolved via Places Autocomplete."},"place_name":{"type":"string","description":"Facility/POI name, if the address represents a named place (e.g. a hospital) rather than a bare street address."},"source":{"type":"string","enum":["google","manual"],"description":"How this address was captured — informational only, never consulted by routing or pricing."}},"required":["formatted"]},"AvailabilityResult":{"type":"object","properties":{"status":{"type":"string","enum":["available","limited","manual_review","unavailable"]},"label":{"type":"string"},"message":{"type":"string"},"requested_datetime":{"type":"string","format":"date-time"},"return_leg":{"type":"object","nullable":true,"description":"The return leg of a round trip, judged against AtlasCare's service hours and staff calendar windows. Null for a one-way trip, and null when no round-trip details were sent. The overall availability status already folds this in (most restrictive wins), so a caller that only needs a yes/no can ignore this object — it exists to explain WHY, and how much the answer can be trusted.","properties":{"status":{"type":"string","enum":["available","limited","manual_review","unavailable","unknown"],"description":"\"unknown\" means the return could not be checked — most often a Scheduled Return with no time given. An unknown return never downgrades the overall status; it is reported so a caller can ask for the missing detail rather than being told the trip needs review over an optional field. A return that falls outside service hours resolves to manual_review rather than unavailable, because AtlasCare would usually take that trip after a quick conversation; only a staff calendar window explicitly marked unavailable produces \"unavailable\"."},"reason_code":{"type":"string","nullable":true,"description":"RETURN_OUTSIDE_SERVICE_HOURS, RETURN_ON_CLOSED_DAY, RETURN_WINDOW_STAFF_OVERRIDE (the vehicle would be committed across a period staff blocked out), RETURN_STAFF_OVERRIDE, or RETURN_TIME_UNKNOWN. Null when the return leg is fine."},"message":{"type":"string","description":"Customer-safe explanation. Never names drivers, other passengers or internal calendar detail."},"estimated_return_datetime":{"type":"string","format":"date-time","nullable":true,"description":"When AtlasCare expects the vehicle to be free again. Null when the return time is unknown."},"basis":{"type":"string","enum":["stated","computed","assumed","unknown"],"description":"How that time was arrived at, and the field to check before repeating it to anyone. \"stated\" = the requester's own return time. \"computed\" = derived from an appointment length they gave. \"assumed\" = AtlasCare's planning assumption, used for Will Call (which has no committed end time) and for a Wait & Return with no stated appointment length. \"unknown\" = not established. Never present \"assumed\" or \"unknown\" to a passenger as a confirmed return time."}}}}},"QuoteResult":{"type":"object","properties":{"id":{"type":"string","nullable":true,"description":"Quote ID, e.g. ATQ-260915-A7K4. Null only when pricing could not be calculated at all."},"token":{"type":"string","nullable":true,"description":"Opaque signed token. Pass this to REQUEST_TRIP as quote_token so the price a customer saw is the price AtlasCare reviews, instead of being recalculated (possibly against a since-changed rate)."},"status":{"type":"string","enum":["estimated","manual_review","confirmed","expired"],"description":"estimated = calculated from AtlasCare's standard posted pricing rules — not yet confirmed by staff. manual_review = one or more trip details need a human to confirm pricing (special equipment, unusual mileage, an incomplete return arrangement) — not a failure. confirmed = reserved for a future state once AtlasCare has explicitly confirmed a price with the customer; GET_PRICE and the combined lookup never return this today. expired = the quote token's validity window has passed."},"serviceable":{"type":"boolean"},"currency":{"type":"string","example":"USD"},"pricing_tier":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"label":{"type":"string"},"minMiles":{"type":"number"},"maxMiles":{"type":"number"}}},"one_way_miles":{"type":"number","nullable":true},"duration_minutes":{"type":"number","nullable":true},"one_way_price":{"type":"number","nullable":true},"round_trip_price":{"type":"number","nullable":true},"included_wait_minutes":{"type":"integer","nullable":true},"additional_wait_rate":{"type":"object","nullable":true,"properties":{"amount":{"type":"number"},"minutes":{"type":"integer"}},"description":"e.g. { amount: 20, minutes: 15 } = $20 per additional 15 minutes."},"equipment_charges":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"amount":{"type":"number"}}}},"total":{"type":"number","nullable":true},"reasons":{"type":"array","items":{"type":"string","enum":["ROUTE_LOOKUP_FAILED","OUTSIDE_SERVICE_AREA","MILEAGE_BEYOND_POSTED_TIERS","SPECIAL_EQUIPMENT","UNSUPPORTED_RETURN_TYPE","NONSTANDARD_TRIP","INCOMPLETE_TRIP_DETAILS"]},"description":"Machine-readable reason code(s) behind a manual_review status or an unserviceable trip."},"disclosures":{"type":"array","items":{"type":"string"},"description":"Human-readable notes worth surfacing to whoever this quote is for."},"created_at":{"type":"string","format":"date-time"},"expires_at":{"type":"string","format":"date-time"}}},"ErrorResponse":{"type":"object","properties":{"ok":{"type":"boolean","enum":[false]},"error":{"type":"string","description":"Safe, human-readable message. Never a raw stack trace or internal error."},"reason_code":{"type":"string","nullable":true}},"required":["ok","error"]}}}}