{"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. Start with checkAvailabilityAndPrice (POST /api/v1/trip-options): it is the default quote path — the one AtlasCare’s own website uses — and returns serviceability, availability for both legs of a round trip, pricing, a signed quote token and a prefilled request URL in one call. Then submit with requestTrip. checkAvailability and getPrice are narrower single-purpose lookups. 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"}],"security":[{},{"apiKey":[]}],"tags":[{"name":"Trip Options","description":"Default quote path — availability and pricing together"},{"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 (narrow lookup) — does AtlasCare appear able to serve this trip time? Prefer checkAvailabilityAndPrice.","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, but a pickup less than minimum_notice_hours away is always manual_review unless the slot is unavailable). 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"},"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},"requested_wait_minutes":{"type":"integer","minimum":0,"maximum":240,"description":"Expected appointment length in minutes on a Wait & Return trip (at most 240 — for a longer appointment omit it and describe the length in notes; a larger value is refused with 400 VALIDATION_FAILED) — 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}}}}}},"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","unknown"],"description":"unknown (label \"Time needed\") = time_basis not_sure: no time yet, so availability was not checked."},"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"]}}}},"401":{"description":"An Authorization header was sent but the API key is not recognized (reason_code INVALID_API_KEY), or a trusted source (api_partner, phone_agent, facility_portal, staff) was used without an API key (reason_code UNAUTHENTICATED). Public sources (web_wizard, ai_agent) need no key.","headers":{"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string"}},"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 (narrow lookup) — pricing only, no availability check. Prefer checkAvailabilityAndPrice.","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","mobility_type","trip_type"],"description":"Also requires pickup_datetime or appointment_datetime (or both) — or time_basis not_sure with trip_date.","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."},"place_types":{"type":"array","items":{"type":"string"},"description":"Google Places types for the address, if resolved via Places. Used only as a hint for the location type (e.g. hospital → facility, premise → residence) when pickup_location_type / destination_location_type is not sent."},"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."},"place_types":{"type":"array","items":{"type":"string"},"description":"Google Places types for the address, if resolved via Places. Used only as a hint for the location type (e.g. hospital → facility, premise → residence) when pickup_location_type / destination_location_type is not sent."},"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,"maximum":240,"description":"Expected appointment length in minutes on a Wait & Return trip (at most 240 — for a longer appointment omit it and describe the length in notes; a larger value is refused with 400 VALIDATION_FAILED) — 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 the BRODA® positioning chair is requested for positioning. Accepts true/false or yes/no/unsure. Ignored when transportation_wheelchair is sent (it is derived from that instead). A transfer at either end (transfer_at_pickup / transfer_at_destination = yes) requires the BRODA Traversa regardless of this answer, unless transportation_wheelchair is atlascare_standard and stand_pivot is sent."},"transportation_wheelchair":{"type":"string","enum":["own","atlascare_standard","atlascare_broda","unsure"],"nullable":true,"description":"The wheelchair the passenger will use DURING transportation (wheelchair trips only): own = the passenger's own chair; atlascare_standard = AtlasCare standard wheelchair, no rental fee; atlascare_broda = BRODA® positioning chair (tilt, recline and elevated-leg positioning), +$95 per trip; unsure = not sure yet (priced without the chair, reviewed). When sent, own_wheelchair and broda_required are derived from it. Optional: callers that send only own_wheelchair / broda_required behave exactly as before."},"stand_pivot":{"type":"string","enum":["yes","no","unsure"],"nullable":true,"description":"Only with transportation_wheelchair = atlascare_standard: can the passenger stand and pivot into a wheelchair with help from facility staff or a caregiver? yes = transfers into the standard chair need no BRODA and no transfer board ($0); no = the BRODA Traversa is required (+$95) for a no-lift transfer; unsure = priced with the standard chair, the BRODA may be needed, reviewed (TRANSFER_METHOD_REVIEW). AtlasCare drivers never lift or physically transfer passengers. Omitted: a transfer requires the BRODA Traversa, as before."},"appointment_datetime":{"type":"string","format":"date-time","description":"Appointment start, ISO 8601 with an explicit offset. Either pickup_datetime or appointment_datetime is required. With only an appointment, AtlasCare suggests a pickup: appointment − routed drive time − an arrival buffer − a transfer allowance for each end with a transfer, rounded down to 5 minutes (see schedule in the response and rules.appointment_* in GET /api/v1/config). With both, pickup_datetime must be earlier, and schedule.pickup_may_be_late reports a pickup that leaves too little time.","example":"2026-09-15T10:00:00-07:00","nullable":true},"transfer_at_pickup":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["yes","no","unsure"]}],"description":"Whether the passenger must be transferred onto AtlasCare’s BRODA Traversa at pickup (for example from a bed or facility chair). Transfers are completed by facility staff; AtlasCare adjusts the chair’s height, tilt, recline and leg elevation for a no-lift transfer. \"yes\" at either end requires mobility_type wheelchair and makes the BRODA Traversa and a transfer board required (see equipment in the response). \"unsure\" routes pricing to manual review. Default no."},"transfer_at_destination":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["yes","no","unsure"]}],"description":"Whether the passenger must be transferred off the BRODA Traversa at the destination. Same rules as transfer_at_pickup."},"pickup_location_type":{"type":"string","enum":["facility","residence","other"],"description":"facility (hospital, clinic, care facility), residence (a home) or other. Decides who completes a transfer at pickup when transfer_assist_at_pickup is not sent: facility → facility_staff, residence → in_home_caregiver."},"destination_location_type":{"type":"string","enum":["facility","residence","other"],"description":"Same as pickup_location_type, for the destination."},"time_basis":{"type":"string","enum":["appointment","pickup","not_sure"],"description":"How the time question was answered. not_sure = only the date is known: send trip_date and no pickup_datetime/appointment_datetime. The trip is then priced normally (from a planning pickup at 12:00 Pacific on that date), availability is not checked and comes back as status unknown / \"Time needed\", the pickup is reported with pickup_basis time_needed, and quote.reasons includes TIME_NEEDED. A pickup or appointment time sent alongside always wins."},"trip_date":{"type":"string","format":"date","description":"YYYY-MM-DD (America/Los_Angeles). Required with time_basis not_sure; ignored otherwise. A past date is refused (400 PAST_DATETIME)."},"positioning_need":{"type":"string","enum":["yes","no","unsure"],"description":"Wheelchair trips: does the passenger need to tilt, recline, or keep their legs raised while riding? unsure adds POSITIONING_REVIEW."},"broda_positioning":{"type":"array","items":{"type":"string","enum":["tilt_in_space","recline","elevated_legs","platform_height","not_sure"]},"description":"Only with transportation_wheelchair atlascare_broda (dropped otherwise): the positioning needed during transportation. not_sure is exclusive — sent with others, only not_sure is kept."},"handoff":{"type":"string","enum":["no","pickup","destination","both","unsure"],"description":"Does AtlasCare need to coordinate a handoff with a specific person? Door-to-Door assistance is included on every trip; pickup / destination / both makes that end Person-to-Person (Door-to-Door plus a coordinated handoff with a designated person). unsure plans Door-to-Door and adds PERSON_TO_PERSON_HANDOFF_REVIEW. Omitted: Door-to-Door at both ends. Service level never changes the price."},"prefers_meet_at_vehicle":{"type":"boolean","description":"The passenger prefers to meet the driver at the vehicle: every end that is not Person-to-Person is planned curb_to_curb (an internal level)."},"handoff_contact_at_pickup":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"phone":{"type":"string","maxLength":40}},"description":"The designated person at pickup. Kept only when pickup is Person-to-Person."},"handoff_contact_at_destination":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"phone":{"type":"string","maxLength":40}},"description":"The designated person at the destination. Kept only when the destination is Person-to-Person."},"planning":{"type":"object","description":"\"Is there anything else we need to know to plan a safe, comfortable, and reliable trip?\" None of it changes the price. other_medical_equipment adds MEDICAL_EQUIPMENT_REVIEW; caregiver_count over 1 adds VEHICLE_CAPACITY_REVIEW; stairs at any end (or unsure) on a wheelchair or not_sure trip, or any access_notes, adds ACCESS_REVIEW. When companion is not sent, caregiver_riding sets it (yes/no). nothing_else and not_sure are ignored when anything else is selected.","properties":{"portable_oxygen":{"type":"boolean","description":"Passenger-supplied portable oxygen. AtlasCare does not provide oxygen or set, adjust or monitor oxygen settings. No charge."},"other_medical_equipment":{"type":"boolean"},"medical_equipment_notes":{"type":"string","maxLength":300,"description":"What equipment (only with other_medical_equipment). No medical information beyond the equipment itself."},"caregiver_riding":{"type":"boolean","description":"One caregiver rides at no charge."},"caregiver_count":{"type":"integer","minimum":1,"maximum":3},"stairs":{"type":"string","enum":["none","pickup","destination","both","unsure"]},"access_notes":{"type":"string","maxLength":300},"other_notes":{"type":"string","maxLength":300,"description":"Staff-only; never shared or shown to anyone else."},"nothing_else":{"type":"boolean"},"not_sure":{"type":"boolean"}}},"return_needed":{"type":"string","enum":["yes","no","unsure"],"description":"Will the passenger need AtlasCare for the return? unsure: send trip_type one_way — priced one way (round_trip_price is in the response) with RETURN_TYPE_REVIEW."},"mobility_aid":{"type":"string","enum":["none","cane","walker","rollator","other","not_sure"],"description":"Ambulatory passengers only; informational."},"destination_details":{"type":"object","description":"Where the passenger needs to be at a recognized hospital or campus (see destination_profile in the checkAvailabilityAndPrice response). Kept when the destination is a recognized campus, or when building is sent. Never changes the price. At a recognized campus, no building adds DESTINATION_DETAILS_REVIEW.","properties":{"building":{"type":"string","maxLength":80,"description":"One of destination_profile.buildings, or the building or clinic name."},"department":{"type":"string","maxLength":80},"floor":{"type":"string","maxLength":20},"suite":{"type":"string","maxLength":20},"room":{"type":"string","maxLength":20}}},"companion":{"type":"string","enum":["yes","no","unsure"],"description":"Will a caregiver or family member ride along? One rides at no charge. unsure adds COMPANION_REVIEW. Omitted: derived from planning.caregiver_riding (older callers)."},"companion_legs":{"type":"string","enum":["both","to_appointment","return_only"],"description":"Round trip with companion yes: which legs the caregiver rides."},"companion_contact":{"type":"object","description":"Optional name and phone of the person riding along.","properties":{"name":{"type":"string","maxLength":80},"phone":{"type":"string","maxLength":40}}},"destination_building_unknown":{"type":"boolean","description":"\"I don't know\" the building at a recognized campus. Never blocks price or availability; adds DESTINATION_DETAILS_REVIEW."}}}}}},"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","nullable":true,"description":"Null for the over-60-mile long-distance formula (id long_distance_over_60)."}}},"one_way_miles":{"type":"number","nullable":true,"description":"Routed one-way miles (static route, two decimals)."},"billing_miles":{"type":"integer","nullable":true,"description":"one_way_miles rounded UP to a whole mile — what the price is based on. Up to 60, the posted tier for this distance applies; over 60, the fare is $195 + $3.25 × (billing_miles − 60) one way, round trip twice that. See long_distance in GET /api/v1/config."},"pricing_distance_basis":{"type":"string","nullable":true,"enum":["static_route","traffic_route",null],"description":"static_route = priced from the traffic-unaware route between the two points, so the same trip costs the same at any departure time. traffic_route appears only if the static lookup failed and a traffic-aware distance was used instead."},"duration_minutes":{"type":"number","nullable":true,"description":"One-way drive time predicted by Google for this trip’s own departure date and time, allowing for traffic. Drives the suggested pickup time and the return-leg check — never the price, which is mileage-based."},"duration_without_traffic_minutes":{"type":"number","nullable":true,"description":"The same drive ignoring traffic. Null when the estimate is not traffic-aware."},"traffic_delay_minutes":{"type":"number","nullable":true,"description":"duration_minutes − duration_without_traffic_minutes."},"traffic_aware":{"type":"boolean","description":"True when the drive time was predicted for a specific departure time."},"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"},"amountCents":{"type":"integer"}}}},"additional_wait_charge":{"type":"number","description":"Charge for Wait & Return time beyond the included window (0 when none)."},"line_items":{"type":"array","description":"The estimate itemized, one row per charge, summing to total. Empty when there is no price. Use these rows to show a breakdown rather than re-deriving it.","items":{"type":"object","properties":{"id":{"type":"string","enum":["base_fare","included_wait","additional_wait","broda_traversa"]},"label":{"type":"string"},"amount":{"type":"number"},"amountCents":{"type":"integer","description":"The same amount in integer cents."}}}},"total":{"type":"number","nullable":true},"total_cents":{"type":"integer","nullable":true,"description":"total in integer cents. Every amount is calculated in cents, so the dollar fields are exact."},"reasons":{"type":"array","items":{"type":"string","enum":["ROUTE_LOOKUP_FAILED","OUTSIDE_SERVICE_AREA","SPECIAL_EQUIPMENT","UNSUPPORTED_RETURN_TYPE","NONSTANDARD_TRIP","INCOMPLETE_TRIP_DETAILS","VERY_LONG_DISTANCE_REVIEW","LONG_DISTANCE_RETURN_REVIEW","CROSS_STATE_TRANSPORTATION_REVIEW","STATE_BORDER_ROUTE_REVIEW","TRANSFER_METHOD_REVIEW","TIME_NEEDED","MOBILITY_REVIEW","POSITIONING_REVIEW","WEIGHT_CAPACITY_REVIEW","TRANSFER_ASSISTANCE_UNAVAILABLE","TRANSFER_ASSISTANCE_REVIEW","PERSON_TO_PERSON_HANDOFF_REVIEW","MEDICAL_EQUIPMENT_REVIEW","VEHICLE_CAPACITY_REVIEW","ACCESS_REVIEW","SEATED_TRAVEL_REVIEW","SEATED_TRAVEL_OUT_OF_SCOPE","RETURN_TYPE_REVIEW","DESTINATION_DETAILS_REVIEW","COMPANION_REVIEW"]},"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"]}}}},"401":{"description":"An Authorization header was sent but the API key is not recognized (reason_code INVALID_API_KEY), or a trusted source (api_partner, phone_agent, facility_portal, staff) was used without an API key (reason_code UNAUTHENTICATED). Public sources (web_wizard, ai_agent) need no key.","headers":{"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string"}},"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":"Default quote path — serviceability, availability (both legs), pricing, signed quote and prefilled request URL in one call","description":"The default way to quote a trip, and the only quote call AtlasCare’s own website estimate and Request a Trip page make. Returns: serviceable (false when the trip appears out of area, could not be routed automatically, or the time is unavailable — a request can still be submitted for review); availability, including availability.return_leg for a round trip judged against the routed drive time; the full quote with a signed 72-hour token to pass to requestTrip; and request_trip_url, a prefilled link to the website wizard. Trip submission without a still-valid token for the same trip runs this exact evaluation, so a quote from here and a submission priced at request time cannot disagree. Same request shape as getPrice.","tags":["Trip Options","Availability","Pricing"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["pickup_address","destination_address","mobility_type","trip_type"],"description":"Also requires pickup_datetime or appointment_datetime (or both) — or time_basis not_sure with trip_date.","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."},"place_types":{"type":"array","items":{"type":"string"},"description":"Google Places types for the address, if resolved via Places. Used only as a hint for the location type (e.g. hospital → facility, premise → residence) when pickup_location_type / destination_location_type is not sent."},"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."},"place_types":{"type":"array","items":{"type":"string"},"description":"Google Places types for the address, if resolved via Places. Used only as a hint for the location type (e.g. hospital → facility, premise → residence) when pickup_location_type / destination_location_type is not sent."},"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,"maximum":240,"description":"Expected appointment length in minutes on a Wait & Return trip (at most 240 — for a longer appointment omit it and describe the length in notes; a larger value is refused with 400 VALIDATION_FAILED) — 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 the BRODA® positioning chair is requested for positioning. Accepts true/false or yes/no/unsure. Ignored when transportation_wheelchair is sent (it is derived from that instead). A transfer at either end (transfer_at_pickup / transfer_at_destination = yes) requires the BRODA Traversa regardless of this answer, unless transportation_wheelchair is atlascare_standard and stand_pivot is sent."},"transportation_wheelchair":{"type":"string","enum":["own","atlascare_standard","atlascare_broda","unsure"],"nullable":true,"description":"The wheelchair the passenger will use DURING transportation (wheelchair trips only): own = the passenger's own chair; atlascare_standard = AtlasCare standard wheelchair, no rental fee; atlascare_broda = BRODA® positioning chair (tilt, recline and elevated-leg positioning), +$95 per trip; unsure = not sure yet (priced without the chair, reviewed). When sent, own_wheelchair and broda_required are derived from it. Optional: callers that send only own_wheelchair / broda_required behave exactly as before."},"stand_pivot":{"type":"string","enum":["yes","no","unsure"],"nullable":true,"description":"Only with transportation_wheelchair = atlascare_standard: can the passenger stand and pivot into a wheelchair with help from facility staff or a caregiver? yes = transfers into the standard chair need no BRODA and no transfer board ($0); no = the BRODA Traversa is required (+$95) for a no-lift transfer; unsure = priced with the standard chair, the BRODA may be needed, reviewed (TRANSFER_METHOD_REVIEW). AtlasCare drivers never lift or physically transfer passengers. Omitted: a transfer requires the BRODA Traversa, as before."},"appointment_datetime":{"type":"string","format":"date-time","description":"Appointment start, ISO 8601 with an explicit offset. Either pickup_datetime or appointment_datetime is required. With only an appointment, AtlasCare suggests a pickup: appointment − routed drive time − an arrival buffer − a transfer allowance for each end with a transfer, rounded down to 5 minutes (see schedule in the response and rules.appointment_* in GET /api/v1/config). With both, pickup_datetime must be earlier, and schedule.pickup_may_be_late reports a pickup that leaves too little time.","example":"2026-09-15T10:00:00-07:00","nullable":true},"transfer_at_pickup":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["yes","no","unsure"]}],"description":"Whether the passenger must be transferred onto AtlasCare’s BRODA Traversa at pickup (for example from a bed or facility chair). Transfers are completed by facility staff; AtlasCare adjusts the chair’s height, tilt, recline and leg elevation for a no-lift transfer. \"yes\" at either end requires mobility_type wheelchair and makes the BRODA Traversa and a transfer board required (see equipment in the response). \"unsure\" routes pricing to manual review. Default no."},"transfer_at_destination":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["yes","no","unsure"]}],"description":"Whether the passenger must be transferred off the BRODA Traversa at the destination. Same rules as transfer_at_pickup."},"pickup_location_type":{"type":"string","enum":["facility","residence","other"],"description":"facility (hospital, clinic, care facility), residence (a home) or other. Decides who completes a transfer at pickup when transfer_assist_at_pickup is not sent: facility → facility_staff, residence → in_home_caregiver."},"destination_location_type":{"type":"string","enum":["facility","residence","other"],"description":"Same as pickup_location_type, for the destination."},"time_basis":{"type":"string","enum":["appointment","pickup","not_sure"],"description":"How the time question was answered. not_sure = only the date is known: send trip_date and no pickup_datetime/appointment_datetime. The trip is then priced normally (from a planning pickup at 12:00 Pacific on that date), availability is not checked and comes back as status unknown / \"Time needed\", the pickup is reported with pickup_basis time_needed, and quote.reasons includes TIME_NEEDED. A pickup or appointment time sent alongside always wins."},"trip_date":{"type":"string","format":"date","description":"YYYY-MM-DD (America/Los_Angeles). Required with time_basis not_sure; ignored otherwise. A past date is refused (400 PAST_DATETIME)."},"positioning_need":{"type":"string","enum":["yes","no","unsure"],"description":"Wheelchair trips: does the passenger need to tilt, recline, or keep their legs raised while riding? unsure adds POSITIONING_REVIEW."},"broda_positioning":{"type":"array","items":{"type":"string","enum":["tilt_in_space","recline","elevated_legs","platform_height","not_sure"]},"description":"Only with transportation_wheelchair atlascare_broda (dropped otherwise): the positioning needed during transportation. not_sure is exclusive — sent with others, only not_sure is kept."},"handoff":{"type":"string","enum":["no","pickup","destination","both","unsure"],"description":"Does AtlasCare need to coordinate a handoff with a specific person? Door-to-Door assistance is included on every trip; pickup / destination / both makes that end Person-to-Person (Door-to-Door plus a coordinated handoff with a designated person). unsure plans Door-to-Door and adds PERSON_TO_PERSON_HANDOFF_REVIEW. Omitted: Door-to-Door at both ends. Service level never changes the price."},"prefers_meet_at_vehicle":{"type":"boolean","description":"The passenger prefers to meet the driver at the vehicle: every end that is not Person-to-Person is planned curb_to_curb (an internal level)."},"handoff_contact_at_pickup":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"phone":{"type":"string","maxLength":40}},"description":"The designated person at pickup. Kept only when pickup is Person-to-Person."},"handoff_contact_at_destination":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"phone":{"type":"string","maxLength":40}},"description":"The designated person at the destination. Kept only when the destination is Person-to-Person."},"planning":{"type":"object","description":"\"Is there anything else we need to know to plan a safe, comfortable, and reliable trip?\" None of it changes the price. other_medical_equipment adds MEDICAL_EQUIPMENT_REVIEW; caregiver_count over 1 adds VEHICLE_CAPACITY_REVIEW; stairs at any end (or unsure) on a wheelchair or not_sure trip, or any access_notes, adds ACCESS_REVIEW. When companion is not sent, caregiver_riding sets it (yes/no). nothing_else and not_sure are ignored when anything else is selected.","properties":{"portable_oxygen":{"type":"boolean","description":"Passenger-supplied portable oxygen. AtlasCare does not provide oxygen or set, adjust or monitor oxygen settings. No charge."},"other_medical_equipment":{"type":"boolean"},"medical_equipment_notes":{"type":"string","maxLength":300,"description":"What equipment (only with other_medical_equipment). No medical information beyond the equipment itself."},"caregiver_riding":{"type":"boolean","description":"One caregiver rides at no charge."},"caregiver_count":{"type":"integer","minimum":1,"maximum":3},"stairs":{"type":"string","enum":["none","pickup","destination","both","unsure"]},"access_notes":{"type":"string","maxLength":300},"other_notes":{"type":"string","maxLength":300,"description":"Staff-only; never shared or shown to anyone else."},"nothing_else":{"type":"boolean"},"not_sure":{"type":"boolean"}}},"return_needed":{"type":"string","enum":["yes","no","unsure"],"description":"Will the passenger need AtlasCare for the return? unsure: send trip_type one_way — priced one way (round_trip_price is in the response) with RETURN_TYPE_REVIEW."},"mobility_aid":{"type":"string","enum":["none","cane","walker","rollator","other","not_sure"],"description":"Ambulatory passengers only; informational."},"destination_details":{"type":"object","description":"Where the passenger needs to be at a recognized hospital or campus (see destination_profile in the checkAvailabilityAndPrice response). Kept when the destination is a recognized campus, or when building is sent. Never changes the price. At a recognized campus, no building adds DESTINATION_DETAILS_REVIEW.","properties":{"building":{"type":"string","maxLength":80,"description":"One of destination_profile.buildings, or the building or clinic name."},"department":{"type":"string","maxLength":80},"floor":{"type":"string","maxLength":20},"suite":{"type":"string","maxLength":20},"room":{"type":"string","maxLength":20}}},"companion":{"type":"string","enum":["yes","no","unsure"],"description":"Will a caregiver or family member ride along? One rides at no charge. unsure adds COMPANION_REVIEW. Omitted: derived from planning.caregiver_riding (older callers)."},"companion_legs":{"type":"string","enum":["both","to_appointment","return_only"],"description":"Round trip with companion yes: which legs the caregiver rides."},"companion_contact":{"type":"object","description":"Optional name and phone of the person riding along.","properties":{"name":{"type":"string","maxLength":80},"phone":{"type":"string","maxLength":40}}},"destination_building_unknown":{"type":"boolean","description":"\"I don't know\" the building at a recognized campus. Never blocks price or availability; adds DESTINATION_DETAILS_REVIEW."},"plan_token":{"type":"string","description":"The plan.token from an earlier response for this same trip. The new estimate is saved as the next version of that Transportation Plan, so request_trip_url keeps working as the trip is adjusted. Omit to start a new plan. Unknown, revoked or expired tokens are ignored (a new plan is started)."},"prefill_hints":{"type":"object","description":"Never priced. Saved with the plan for the Request a Trip page: chair = the wheelchair the person picked (own | atlascare_standard | atlascare_broda | unsure); return_type_chosen: false when a round trip is being priced with a return arrangement the person has not actually chosen, so the page asks.","properties":{"chair":{"type":"string","enum":["own","atlascare_standard","atlascare_broda","unsure"]},"return_type_chosen":{"type":"boolean"}}},"save_plan":{"type":"boolean","description":"false: price the trip without saving a Transportation Plan (no plan, no request_trip_url). For previews and internal price checks. Default true."}}}}}},"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","unknown"],"description":"unknown (label \"Time needed\") = time_basis not_sure: no time yet, so availability was not checked."},"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","nullable":true,"description":"Null for the over-60-mile long-distance formula (id long_distance_over_60)."}}},"one_way_miles":{"type":"number","nullable":true,"description":"Routed one-way miles (static route, two decimals)."},"billing_miles":{"type":"integer","nullable":true,"description":"one_way_miles rounded UP to a whole mile — what the price is based on. Up to 60, the posted tier for this distance applies; over 60, the fare is $195 + $3.25 × (billing_miles − 60) one way, round trip twice that. See long_distance in GET /api/v1/config."},"pricing_distance_basis":{"type":"string","nullable":true,"enum":["static_route","traffic_route",null],"description":"static_route = priced from the traffic-unaware route between the two points, so the same trip costs the same at any departure time. traffic_route appears only if the static lookup failed and a traffic-aware distance was used instead."},"duration_minutes":{"type":"number","nullable":true,"description":"One-way drive time predicted by Google for this trip’s own departure date and time, allowing for traffic. Drives the suggested pickup time and the return-leg check — never the price, which is mileage-based."},"duration_without_traffic_minutes":{"type":"number","nullable":true,"description":"The same drive ignoring traffic. Null when the estimate is not traffic-aware."},"traffic_delay_minutes":{"type":"number","nullable":true,"description":"duration_minutes − duration_without_traffic_minutes."},"traffic_aware":{"type":"boolean","description":"True when the drive time was predicted for a specific departure time."},"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"},"amountCents":{"type":"integer"}}}},"additional_wait_charge":{"type":"number","description":"Charge for Wait & Return time beyond the included window (0 when none)."},"line_items":{"type":"array","description":"The estimate itemized, one row per charge, summing to total. Empty when there is no price. Use these rows to show a breakdown rather than re-deriving it.","items":{"type":"object","properties":{"id":{"type":"string","enum":["base_fare","included_wait","additional_wait","broda_traversa"]},"label":{"type":"string"},"amount":{"type":"number"},"amountCents":{"type":"integer","description":"The same amount in integer cents."}}}},"total":{"type":"number","nullable":true},"total_cents":{"type":"integer","nullable":true,"description":"total in integer cents. Every amount is calculated in cents, so the dollar fields are exact."},"reasons":{"type":"array","items":{"type":"string","enum":["ROUTE_LOOKUP_FAILED","OUTSIDE_SERVICE_AREA","SPECIAL_EQUIPMENT","UNSUPPORTED_RETURN_TYPE","NONSTANDARD_TRIP","INCOMPLETE_TRIP_DETAILS","VERY_LONG_DISTANCE_REVIEW","LONG_DISTANCE_RETURN_REVIEW","CROSS_STATE_TRANSPORTATION_REVIEW","STATE_BORDER_ROUTE_REVIEW","TRANSFER_METHOD_REVIEW","TIME_NEEDED","MOBILITY_REVIEW","POSITIONING_REVIEW","WEIGHT_CAPACITY_REVIEW","TRANSFER_ASSISTANCE_UNAVAILABLE","TRANSFER_ASSISTANCE_REVIEW","PERSON_TO_PERSON_HANDOFF_REVIEW","MEDICAL_EQUIPMENT_REVIEW","VEHICLE_CAPACITY_REVIEW","ACCESS_REVIEW","SEATED_TRAVEL_REVIEW","SEATED_TRAVEL_OUT_OF_SCOPE","RETURN_TYPE_REVIEW","DESTINATION_DETAILS_REVIEW","COMPANION_REVIEW"]},"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"}}},"schedule":{"type":"object","description":"When the pickup is, and how that time was arrived at.","properties":{"pickup_datetime":{"type":"string","format":"date-time"},"pickup_basis":{"type":"string","enum":["stated","suggested","assumed","time_needed"],"description":"stated = the requester’s pickup time; suggested = worked back from appointment_datetime using the routed drive; assumed = no drive time was available, so a default lead time was used. Confirm suggested and assumed pickups with the passenger."},"appointment_datetime":{"type":"string","format":"date-time","nullable":true},"suggested_pickup_datetime":{"type":"string","format":"date-time","nullable":true},"suggestion_breakdown":{"type":"object","nullable":true,"properties":{"drive_minutes":{"type":"integer","nullable":true},"arrival_buffer_minutes":{"type":"integer","nullable":true},"loading_minutes":{"type":"integer","description":"Vehicle loading at pickup plus unloading at the destination: 10 minutes walking, 15 wheelchair (or not sure)."},"transfer_minutes":{"type":"integer"},"lead_minutes":{"type":"integer"}}},"pickup_may_be_late":{"type":"boolean","description":"A stated pickup later than the suggested pickup — the passenger would probably arrive after the appointment."},"trip_date":{"type":"string","format":"date","nullable":true,"description":"Set with pickup_basis time_needed (time_basis not_sure): the trip date. pickup_datetime is then only a planning placeholder (12:00 Pacific), not a pickup time."}}},"equipment":{"type":"object","description":"Equipment the trip needs, derived from positioning and transfer answers.","properties":{"broda_traversa":{"type":"string","enum":["yes","no","unsure"]},"transfer_board":{"type":"string","enum":["yes","no","unsure"]},"transfer_at_pickup":{"type":"string","enum":["yes","no","unsure"]},"transfer_at_destination":{"type":"string","enum":["yes","no","unsure"]},"transfer_assist_at_pickup":{"type":"string","enum":["facility_staff","in_home_caregiver","none_available","unsure"],"nullable":true},"transfer_assist_at_destination":{"type":"string","enum":["facility_staff","in_home_caregiver","none_available","unsure"],"nullable":true},"pickup_location_type":{"type":"string","enum":["facility","residence","other"],"nullable":true},"destination_location_type":{"type":"string","enum":["facility","residence","other"],"nullable":true},"reasons":{"type":"array","items":{"type":"string","enum":["transfer_at_pickup","transfer_at_destination","positioning_requested"]}},"transfer_note":{"type":"string","nullable":true}}},"service":{"type":"object","description":"Service level at each end (curb_to_curb is internal: the passenger prefers to meet the driver at the vehicle). door_to_door at both ends unless handoff or prefers_meet_at_vehicle was sent. level is the most comprehensive of the two. Never changes the price.","properties":{"pickup_level":{"type":"string","enum":["curb_to_curb","door_to_door","person_to_person"]},"destination_level":{"type":"string","enum":["curb_to_curb","door_to_door","person_to_person"]},"level":{"type":"string","enum":["curb_to_curb","door_to_door","person_to_person"]}}},"destination_profile":{"type":"object","nullable":true,"description":"The recognized hospital or campus at the destination (e.g. OHSU Marquam Hill), or null for an ordinary address. When present, ask for the building or clinic (destination_details.building, or destination_building_unknown).","properties":{"id":{"type":"string","example":"ohsu_marquam_hill"},"facility":{"type":"string"},"campus":{"type":"string"},"buildings":{"type":"array","items":{"type":"string"}}}},"destination_status":{"type":"string","nullable":true,"enum":["complete","incomplete",null],"description":"complete = a building was given at a recognized campus; incomplete = not yet (DESTINATION_DETAILS_REVIEW); null = no campus recognized."},"jurisdiction":{"type":"object","nullable":true,"description":"Oregon state-border decision. Every trip that starts, ends or travels outside Oregon is priced but reviewed by AtlasCare (reason CROSS_STATE_TRANSPORTATION_REVIEW; availability manual_review, label \"AtlasCare Review Required\"). STATE_BORDER_ROUTE_REVIEW means the route could not be confirmed to stay in Oregon near the state line. Null on a quote re-served from a token issued before this existed.","properties":{"pickup_in_oregon":{"type":"boolean","nullable":true},"destination_in_oregon":{"type":"boolean","nullable":true},"route_crosses_state_border":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["unknown"]}]},"cross_state_trip":{"type":"boolean"},"basis":{"type":"string","enum":["endpoint","route","endpoints_far_from_border","endpoints_near_border","no_coordinates"]}}},"plan":{"type":"object","nullable":true,"description":"The Transportation Plan this estimate was saved as. plan_number (ATP-YYYY-NNNNNN) is a reference to show people — it opens nothing. token is the credential behind request_trip_url: anyone holding it can open the plan, so share it only with the person the trip is for. Send it back as plan_token to save a changed estimate as the next version of the same plan. Null when save_plan was false or plans are unavailable.","properties":{"plan_number":{"type":"string"},"version":{"type":"integer"},"status":{"type":"string","enum":["draft","review_required","submitted","superseded","expired"]},"token":{"type":"string"}}},"request_trip_url":{"type":"string","nullable":true,"description":"A link to AtlasCare’s Request a Trip page that opens this Transportation Plan: /request-trip?plan=<token>. It carries no trip details — the page loads them from the plan — so it is safe in a text or email. A person handed this link lands on the page with their trip already filled in. Add &from=estimate to open it as \"finish your request\". An integration can also submit REQUEST_TRIP directly with the quote token and plan_token instead of sending a person through this link. Null when no plan was saved."},"plan_url":{"type":"string","nullable":true,"description":"Your Transportation Plan: /plan/<token>. The page to view, share, download (PDF) or print the plan, with current availability and Request This Trip. Carries only the token. plan.plan_url is the same link as an absolute URL, and plan.share_message is a ready-to-send message containing it. Null when no plan was saved."}}}}}},"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"]}}}},"401":{"description":"An Authorization header was sent but the API key is not recognized (reason_code INVALID_API_KEY), or a trusted source (api_partner, phone_agent, facility_portal, staff) was used without an API key (reason_code UNAUTHENTICATED). Public sources (web_wizard, ai_agent) need no key.","headers":{"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string"}},"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. Every channel (AtlasCare’s website, AI agents, API partners and AtlasCare’s phone agent) submits through the same service, which records one trip and sends every notification from it. Include the quote_token from checkAvailabilityAndPrice so the price shown to your user is the price AtlasCare reviews. A token is honored only when it verifies AND was issued for the same price-relevant trip details (addresses, trip type, return type, requested_wait_minutes, mobility_type, broda_required); tokens are valid for 72 hours (see expires_at). A missing, expired, invalid or mismatched token does not cause a 4xx — the trip is priced at submission by the same evaluation checkAvailabilityAndPrice performs (quote_source: \"recalculated\", with quote_token_issue explaining why a supplied token was not used). Availability, including the return leg, is always re-evaluated at submission. A pickup_datetime in the past is rejected (PAST_DATETIME). Supports an Idempotency-Key header (or idempotency_key body field) to safely retry — a repeated key returns { ok: true, duplicate: true } with the same request_id 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","mobility_type","trip_type"],"description":"Also requires pickup_datetime or appointment_datetime (or both) — or time_basis not_sure with trip_date.","properties":{"source":{"type":"string","enum":["web_wizard","ai_agent","api_partner","facility_portal","phone_agent","staff"],"description":"Required. Trusted sources (api_partner, phone_agent, facility_portal, staff) require an API key issued by AtlasCare (Authorization: Bearer <key>) and are recorded as verified; web_wizard and ai_agent need no key and are recorded as self-declared. 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."},"source_reference":{"type":"string","maxLength":120,"description":"Optional identifier from the submitting channel for the conversation or call that produced this request (for example a phone-agent call id). Stored with the trip so staff can trace it back."},"idempotency_key":{"type":"string","description":"Alternative to the Idempotency-Key header. Ignored when plan_token is sent: a plan submission is identified by its plan and version."},"plan_token":{"type":"string","description":"The plan.token of the Transportation Plan being requested (from checkAvailabilityAndPrice, or the plan link). Ties the request to the plan: the same plan version submitted twice is one request (duplicate: true, same request_id), and a NEWER version of a plan that was already submitted amends that request (amended: true, same request_id) instead of creating a second one. An unknown, revoked or expired token is ignored."},"plan_version":{"type":"integer","minimum":1,"description":"The plan version the person saw. Defaults to the plan’s current version."},"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."},"place_types":{"type":"array","items":{"type":"string"},"description":"Google Places types for the address, if resolved via Places. Used only as a hint for the location type (e.g. hospital → facility, premise → residence) when pickup_location_type / destination_location_type is not sent."},"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."},"place_types":{"type":"array","items":{"type":"string"},"description":"Google Places types for the address, if resolved via Places. Used only as a hint for the location type (e.g. hospital → facility, premise → residence) when pickup_location_type / destination_location_type is not sent."},"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,"maximum":240,"description":"Expected appointment length in minutes on a Wait & Return trip (at most 240 — for a longer appointment omit it and describe the length in notes; a larger value is refused with 400 VALIDATION_FAILED) — 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 the BRODA® positioning chair is requested for positioning. Accepts true/false or yes/no/unsure. Ignored when transportation_wheelchair is sent (it is derived from that instead). A transfer at either end (transfer_at_pickup / transfer_at_destination = yes) requires the BRODA Traversa regardless of this answer, unless transportation_wheelchair is atlascare_standard and stand_pivot is sent."},"transportation_wheelchair":{"type":"string","enum":["own","atlascare_standard","atlascare_broda","unsure"],"nullable":true,"description":"The wheelchair the passenger will use DURING transportation (wheelchair trips only): own = the passenger's own chair; atlascare_standard = AtlasCare standard wheelchair, no rental fee; atlascare_broda = BRODA® positioning chair (tilt, recline and elevated-leg positioning), +$95 per trip; unsure = not sure yet (priced without the chair, reviewed). When sent, own_wheelchair and broda_required are derived from it. Optional: callers that send only own_wheelchair / broda_required behave exactly as before."},"stand_pivot":{"type":"string","enum":["yes","no","unsure"],"nullable":true,"description":"Only with transportation_wheelchair = atlascare_standard: can the passenger stand and pivot into a wheelchair with help from facility staff or a caregiver? yes = transfers into the standard chair need no BRODA and no transfer board ($0); no = the BRODA Traversa is required (+$95) for a no-lift transfer; unsure = priced with the standard chair, the BRODA may be needed, reviewed (TRANSFER_METHOD_REVIEW). AtlasCare drivers never lift or physically transfer passengers. Omitted: a transfer requires the BRODA Traversa, as before."},"appointment_datetime":{"type":"string","format":"date-time","description":"Appointment start, ISO 8601 with an explicit offset. Either pickup_datetime or appointment_datetime is required. With only an appointment, AtlasCare suggests a pickup: appointment − routed drive time − an arrival buffer − a transfer allowance for each end with a transfer, rounded down to 5 minutes (see schedule in the response and rules.appointment_* in GET /api/v1/config). With both, pickup_datetime must be earlier, and schedule.pickup_may_be_late reports a pickup that leaves too little time.","example":"2026-09-15T10:00:00-07:00","nullable":true},"transfer_at_pickup":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["yes","no","unsure"]}],"description":"Whether the passenger must be transferred onto AtlasCare’s BRODA Traversa at pickup (for example from a bed or facility chair). Transfers are completed by facility staff; AtlasCare adjusts the chair’s height, tilt, recline and leg elevation for a no-lift transfer. \"yes\" at either end requires mobility_type wheelchair and makes the BRODA Traversa and a transfer board required (see equipment in the response). \"unsure\" routes pricing to manual review. Default no."},"transfer_at_destination":{"oneOf":[{"type":"boolean"},{"type":"string","enum":["yes","no","unsure"]}],"description":"Whether the passenger must be transferred off the BRODA Traversa at the destination. Same rules as transfer_at_pickup."},"pickup_location_type":{"type":"string","enum":["facility","residence","other"],"description":"facility (hospital, clinic, care facility), residence (a home) or other. Decides who completes a transfer at pickup when transfer_assist_at_pickup is not sent: facility → facility_staff, residence → in_home_caregiver."},"destination_location_type":{"type":"string","enum":["facility","residence","other"],"description":"Same as pickup_location_type, for the destination."},"time_basis":{"type":"string","enum":["appointment","pickup","not_sure"],"description":"How the time question was answered. not_sure = only the date is known: send trip_date and no pickup_datetime/appointment_datetime. The trip is then priced normally (from a planning pickup at 12:00 Pacific on that date), availability is not checked and comes back as status unknown / \"Time needed\", the pickup is reported with pickup_basis time_needed, and quote.reasons includes TIME_NEEDED. A pickup or appointment time sent alongside always wins."},"trip_date":{"type":"string","format":"date","description":"YYYY-MM-DD (America/Los_Angeles). Required with time_basis not_sure; ignored otherwise. A past date is refused (400 PAST_DATETIME)."},"positioning_need":{"type":"string","enum":["yes","no","unsure"],"description":"Wheelchair trips: does the passenger need to tilt, recline, or keep their legs raised while riding? unsure adds POSITIONING_REVIEW."},"broda_positioning":{"type":"array","items":{"type":"string","enum":["tilt_in_space","recline","elevated_legs","platform_height","not_sure"]},"description":"Only with transportation_wheelchair atlascare_broda (dropped otherwise): the positioning needed during transportation. not_sure is exclusive — sent with others, only not_sure is kept."},"handoff":{"type":"string","enum":["no","pickup","destination","both","unsure"],"description":"Does AtlasCare need to coordinate a handoff with a specific person? Door-to-Door assistance is included on every trip; pickup / destination / both makes that end Person-to-Person (Door-to-Door plus a coordinated handoff with a designated person). unsure plans Door-to-Door and adds PERSON_TO_PERSON_HANDOFF_REVIEW. Omitted: Door-to-Door at both ends. Service level never changes the price."},"prefers_meet_at_vehicle":{"type":"boolean","description":"The passenger prefers to meet the driver at the vehicle: every end that is not Person-to-Person is planned curb_to_curb (an internal level)."},"handoff_contact_at_pickup":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"phone":{"type":"string","maxLength":40}},"description":"The designated person at pickup. Kept only when pickup is Person-to-Person."},"handoff_contact_at_destination":{"type":"object","properties":{"name":{"type":"string","maxLength":80},"phone":{"type":"string","maxLength":40}},"description":"The designated person at the destination. Kept only when the destination is Person-to-Person."},"planning":{"type":"object","description":"\"Is there anything else we need to know to plan a safe, comfortable, and reliable trip?\" None of it changes the price. other_medical_equipment adds MEDICAL_EQUIPMENT_REVIEW; caregiver_count over 1 adds VEHICLE_CAPACITY_REVIEW; stairs at any end (or unsure) on a wheelchair or not_sure trip, or any access_notes, adds ACCESS_REVIEW. When companion is not sent, caregiver_riding sets it (yes/no). nothing_else and not_sure are ignored when anything else is selected.","properties":{"portable_oxygen":{"type":"boolean","description":"Passenger-supplied portable oxygen. AtlasCare does not provide oxygen or set, adjust or monitor oxygen settings. No charge."},"other_medical_equipment":{"type":"boolean"},"medical_equipment_notes":{"type":"string","maxLength":300,"description":"What equipment (only with other_medical_equipment). No medical information beyond the equipment itself."},"caregiver_riding":{"type":"boolean","description":"One caregiver rides at no charge."},"caregiver_count":{"type":"integer","minimum":1,"maximum":3},"stairs":{"type":"string","enum":["none","pickup","destination","both","unsure"]},"access_notes":{"type":"string","maxLength":300},"other_notes":{"type":"string","maxLength":300,"description":"Staff-only; never shared or shown to anyone else."},"nothing_else":{"type":"boolean"},"not_sure":{"type":"boolean"}}},"return_needed":{"type":"string","enum":["yes","no","unsure"],"description":"Will the passenger need AtlasCare for the return? unsure: send trip_type one_way — priced one way (round_trip_price is in the response) with RETURN_TYPE_REVIEW."},"mobility_aid":{"type":"string","enum":["none","cane","walker","rollator","other","not_sure"],"description":"Ambulatory passengers only; informational."},"destination_details":{"type":"object","description":"Where the passenger needs to be at a recognized hospital or campus (see destination_profile in the checkAvailabilityAndPrice response). Kept when the destination is a recognized campus, or when building is sent. Never changes the price. At a recognized campus, no building adds DESTINATION_DETAILS_REVIEW.","properties":{"building":{"type":"string","maxLength":80,"description":"One of destination_profile.buildings, or the building or clinic name."},"department":{"type":"string","maxLength":80},"floor":{"type":"string","maxLength":20},"suite":{"type":"string","maxLength":20},"room":{"type":"string","maxLength":20}}},"companion":{"type":"string","description":"Whether a caregiver/family member is riding along."},"companion_legs":{"type":"string","enum":["both","to_appointment","return_only"],"description":"Round trip with companion yes: which legs the caregiver rides."},"companion_contact":{"type":"object","description":"Optional name and phone of the person riding along.","properties":{"name":{"type":"string","maxLength":80},"phone":{"type":"string","maxLength":40}}},"destination_building_unknown":{"type":"boolean","description":"\"I don't know\" the building at a recognized campus. Never blocks price or availability; adds DESTINATION_DETAILS_REVIEW."},"quote_token":{"type":"string","description":"quote.token from checkAvailabilityAndPrice (or getPrice). Strongly recommended — honored only for the same price-relevant trip details; otherwise the trip is priced at submission."},"requester":{"type":"string","enum":["self","supporter","facility"],"description":"Who the requester is arranging this trip for."},"own_wheelchair":{"type":"string","enum":["yes","no"],"description":"Whether the passenger will ride in their own wheelchair."},"transfer_assist_at_pickup":{"type":"string","enum":["facility_staff","in_home_caregiver","none_available","unsure"],"description":"Who completes the transfer at pickup. AtlasCare staff do not lift. Defaults from pickup_location_type. in_home_caregiver without transfer_assist_confirmed_at_pickup is accepted but flagged for review; none_available is accepted but flagged high risk — AtlasCare will call before scheduling. On a round trip the same helper is needed again when the passenger is brought back."},"transfer_assistant_name_at_pickup":{"type":"string","maxLength":80,"description":"In-home caregiver’s name (in_home_caregiver only)."},"transfer_assistant_phone_at_pickup":{"type":"string","maxLength":30,"description":"In-home caregiver’s phone, so the driver can coordinate on arrival."},"transfer_assist_confirmed_at_pickup":{"type":"boolean","description":"The requester confirms the in-home caregiver will be there — including when the passenger returns on a round trip."},"transfer_assist_at_destination":{"type":"string","enum":["facility_staff","in_home_caregiver","none_available","unsure"],"description":"Who completes the transfer at the destination. Same rules as transfer_assist_at_pickup."},"transfer_assistant_name_at_destination":{"type":"string","maxLength":80},"transfer_assistant_phone_at_destination":{"type":"string","maxLength":30},"transfer_assist_confirmed_at_destination":{"type":"boolean"},"wheelchair_type":{"type":"string","enum":["manual","power","transport","other_not_sure"]},"weight_range":{"type":"string","enum":["under_250","over_250","not_sure"],"description":"Approximate passenger weight — used to confirm vehicle and equipment capacity. over_250 is bariatric: the trip is flagged BARIATRIC and held for staff review."},"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."},"preferred_contact":{"type":"string","enum":["text","email","call"],"description":"How the requester would like AtlasCare to reach them. \"text\" is a preference only: AtlasCare texts a number only if that number has itself opted in to the AtlasCare SMS program (on atlascaretransport.com or by phone with AtlasCare). Otherwise AtlasCare uses email or a call."},"sms_consent":{"type":"object","nullable":true,"description":"Accepted only from the AtlasCare website and signed-in AtlasCare staff. API callers (ai_agent, api_partner, facility_portal, phone_agent) cannot grant SMS consent on anyone’s behalf; the field is ignored and the response’s sms_updates.status is \"not_accepted_from_channel\".","properties":{"granted":{"type":"boolean"},"disclosure_version":{"type":"string"}}},"supporter":{"type":"object","nullable":true,"properties":{"passenger_name":{"type":"string","description":"Required when requester is \"supporter\" (or requester_type is \"family_caregiver\"): the name of the person riding."},"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":"<quote.token from /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]},"duplicate":{"type":"boolean","description":"Present and true when this Idempotency-Key was already used; request_id is the original request."},"request_id":{"type":"string","example":"ATR-2026-482913"},"status":{"type":"string","enum":["received","quote_sent","booked","cancelled"],"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","unknown"],"description":"unknown = submitted with time_basis not_sure: availability is checked once a time is given."},"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"]},"quote_token_issue":{"type":"string","nullable":true,"enum":["EXPIRED","INPUTS_CHANGED","BAD_SIGNATURE","MALFORMED","DECODE_ERROR",null],"description":"Why a supplied quote_token was not used. Null when no token was sent or it was honored."},"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"]}}}},"401":{"description":"An Authorization header was sent but the API key is not recognized (reason_code INVALID_API_KEY), or a trusted source (api_partner, phone_agent, facility_portal, staff) was used without an API key (reason_code UNAUTHENTICATED). Public sources (web_wizard, ai_agent) need no key.","headers":{"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string"}},"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"]}}}},"403":{"description":"The API key is valid but that client is not allowed to submit with this source (reason_code SOURCE_NOT_ALLOWED).","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/plans/{token}":{"get":{"operationId":"getTransportationPlan","summary":"A Transportation Plan, as its share link shows it","description":"The share-safe view of a Transportation Plan for whoever holds its link (the token in request_trip_url): the trip, the itemized estimate and the availability as last checked, with that timestamp — availability may change until AtlasCare confirms the trip. A link made for an earlier version opens the current one (updated_since_link: true). Never includes review codes, notes or safety answers. An unknown, revoked or expired link returns 404 PLAN_NOT_AVAILABLE and reveals nothing about the plan. Links expire 7 days after the trip date (30 days after creation with no date), and AtlasCare staff can revoke them.","tags":["Trip Options"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$"}}],"responses":{"200":{"description":"The plan. A plan whose 72-hour quote has expired is re-priced first under the current pricing version (repriced: true; plan.previous_estimate holds the earlier total when it changed).","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"plan":{"type":"object"},"repriced":{"type":"boolean"},"request_trip_url":{"type":"string"},"plan_url":{"type":"string"},"pdf_url":{"type":"string"},"share_message":{"type":"string"}}}}}},"404":{"description":"This plan link is no longer available.","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/plans/{token}/refresh":{"post":{"operationId":"refreshTransportationPlan","summary":"Check current availability and pricing for a plan","description":"Re-evaluates the plan’s trip — availability, and the price under the current pricing version — and saves it as the plan’s next version; the same link keeps working. When pricing can’t be reached the plan is left as it was (503 PRICING_UNAVAILABLE) and the call can simply be retried. A submitted plan, or one saved before this was available, returns 409.","tags":["Trip Options"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$"}}],"responses":{"200":{"description":"The refreshed plan (same shape as getTransportationPlan, with refreshed: true).","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"This plan link is no longer available.","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"]}}}},"409":{"description":"NOT_REFRESHABLE or TRIP_PASSED.","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"]}}}},"503":{"description":"PRICING_UNAVAILABLE — nothing changed; try again.","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/plans/{token}/pdf":{"get":{"operationId":"getTransportationPlanPdf","summary":"A Transportation Plan as a PDF","description":"The plan’s current version as a branded, printable PDF (one US Letter page for an ordinary trip): trip, wheelchair, service level, equipment, Destination Plan, return plan, availability with its timestamp, itemized estimate, disclaimers and contact information. Share-safe, like the plan view.","tags":["Trip Options"],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{43}$"}}],"responses":{"200":{"description":"The PDF.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"404":{"description":"This plan link is no longer available.","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":"The current status of the request’s trip record, without contact details or addresses: received (in review, not booked), quote_sent (AtlasCare sent a quote to the requester), booked (AtlasCare confirmed the trip), or cancelled. Returns a helpful 200 (status: unknown) rather than a 404 when a request ID isn’t found.","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","enum":["received","quote_sent","booked","cancelled","unknown"]},"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},"updated_at":{"type":"string","format":"date-time","nullable":true},"message":{"type":"string","nullable":true}}}}}},"401":{"description":"An Authorization header was sent but the API key is not recognized (reason_code INVALID_API_KEY), or a trusted source (api_partner, phone_agent, facility_portal, staff) was used without an API key (reason_code UNAUTHENTICATED). Public sources (web_wizard, ai_agent) need no key.","headers":{"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string"}},"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/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. Since pricing version 2026.10.1: trips over 60 miles are priced by long_distance (base_fare_cents + per_billing_mile_cents per mile over base_miles; round trip × round_trip_multiplier); mileage is rounded up to a whole mile (billing_mile_rounding); trips at or above very_long_distance_review_threshold_miles, Scheduled Return / Will Call over long_distance_return_threshold_miles, and trips crossing the Oregon state line are priced but reviewed; a straight-line distance over straight_line_sanity_limit_miles is outside the service area. The former max_quotable_miles field was removed.","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."}}}},"401":{"description":"An Authorization header was sent but the API key is not recognized (reason_code INVALID_API_KEY), or a trusted source (api_partner, phone_agent, facility_portal, staff) was used without an API key (reason_code UNAUTHENTICATED). Public sources (web_wizard, ai_agent) need no key.","headers":{"WWW-Authenticate":{"description":"Bearer","schema":{"type":"string"}},"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"]}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"http","scheme":"bearer","description":"Optional for public use. AtlasCare issues API keys to trusted integrations (partners, facility portals, its phone agent). A key identifies the client, gives it its own rate limits, and is required for the api_partner, phone_agent, facility_portal and staff sources. Send as Authorization: Bearer <key>."}},"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."},"place_types":{"type":"array","items":{"type":"string"},"description":"Google Places types for the address, if resolved via Places. Used only as a hint for the location type (e.g. hospital → facility, premise → residence) when pickup_location_type / destination_location_type is not sent."},"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","unknown"],"description":"unknown (label \"Time needed\") = time_basis not_sure: no time yet, so availability was not checked."},"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","nullable":true,"description":"Null for the over-60-mile long-distance formula (id long_distance_over_60)."}}},"one_way_miles":{"type":"number","nullable":true,"description":"Routed one-way miles (static route, two decimals)."},"billing_miles":{"type":"integer","nullable":true,"description":"one_way_miles rounded UP to a whole mile — what the price is based on. Up to 60, the posted tier for this distance applies; over 60, the fare is $195 + $3.25 × (billing_miles − 60) one way, round trip twice that. See long_distance in GET /api/v1/config."},"pricing_distance_basis":{"type":"string","nullable":true,"enum":["static_route","traffic_route",null],"description":"static_route = priced from the traffic-unaware route between the two points, so the same trip costs the same at any departure time. traffic_route appears only if the static lookup failed and a traffic-aware distance was used instead."},"duration_minutes":{"type":"number","nullable":true,"description":"One-way drive time predicted by Google for this trip’s own departure date and time, allowing for traffic. Drives the suggested pickup time and the return-leg check — never the price, which is mileage-based."},"duration_without_traffic_minutes":{"type":"number","nullable":true,"description":"The same drive ignoring traffic. Null when the estimate is not traffic-aware."},"traffic_delay_minutes":{"type":"number","nullable":true,"description":"duration_minutes − duration_without_traffic_minutes."},"traffic_aware":{"type":"boolean","description":"True when the drive time was predicted for a specific departure time."},"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"},"amountCents":{"type":"integer"}}}},"additional_wait_charge":{"type":"number","description":"Charge for Wait & Return time beyond the included window (0 when none)."},"line_items":{"type":"array","description":"The estimate itemized, one row per charge, summing to total. Empty when there is no price. Use these rows to show a breakdown rather than re-deriving it.","items":{"type":"object","properties":{"id":{"type":"string","enum":["base_fare","included_wait","additional_wait","broda_traversa"]},"label":{"type":"string"},"amount":{"type":"number"},"amountCents":{"type":"integer","description":"The same amount in integer cents."}}}},"total":{"type":"number","nullable":true},"total_cents":{"type":"integer","nullable":true,"description":"total in integer cents. Every amount is calculated in cents, so the dollar fields are exact."},"reasons":{"type":"array","items":{"type":"string","enum":["ROUTE_LOOKUP_FAILED","OUTSIDE_SERVICE_AREA","SPECIAL_EQUIPMENT","UNSUPPORTED_RETURN_TYPE","NONSTANDARD_TRIP","INCOMPLETE_TRIP_DETAILS","VERY_LONG_DISTANCE_REVIEW","LONG_DISTANCE_RETURN_REVIEW","CROSS_STATE_TRANSPORTATION_REVIEW","STATE_BORDER_ROUTE_REVIEW","TRANSFER_METHOD_REVIEW","TIME_NEEDED","MOBILITY_REVIEW","POSITIONING_REVIEW","WEIGHT_CAPACITY_REVIEW","TRANSFER_ASSISTANCE_UNAVAILABLE","TRANSFER_ASSISTANCE_REVIEW","PERSON_TO_PERSON_HANDOFF_REVIEW","MEDICAL_EQUIPMENT_REVIEW","VEHICLE_CAPACITY_REVIEW","ACCESS_REVIEW","SEATED_TRAVEL_REVIEW","SEATED_TRAVEL_OUT_OF_SCOPE","RETURN_TYPE_REVIEW","DESTINATION_DETAILS_REVIEW","COMPANION_REVIEW"]},"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"]}}}}