# BART

> Read the Bay Area's rail network through BART's free, keyless public API: live departure boards with delays and platforms, service advisories and elevator outages, how many trains are running right now, the station and route directories, published timetables for a station or a whole line, holidays and planned closures, and trip planning with fares in every class. No account or API key is required. Disclaimer: this is an independent integration built on BART's public API. It is not affiliated with, endorsed by, or sponsored by the San Francisco Bay Area Rapid Transit District; BART and its marks are the property of that district.

App · Travel & Places · 17 actions. Web page: https://docs.lodol.com/docs/integrations/bart

## Actions

### Get a route's timetable

Read the whole day's timetable for one route, train by train and stop by stop. This is the largest answer BART gives, so it is meant for building or checking a schedule rather than for asking when the next train is: Get real-time departures answers that in a single row. Stations a train passes without calling at are left out of its stop list.

**Inputs**

- Route (`route`, text, required): Which route to look up. Pick one, or reference a route number from a previous step. A route is one direction of one line, so the northbound and southbound halves are separate routes.
- Starting at (`starting_at`, date and time): Return the timetable from this moment onwards. Leave empty for the whole of today's service.
- Schedule number (`schedule`, text): Read a specific published timetable rather than the one in force today. The numbers come from the List published schedules action; leave empty for the current one.

**Outputs**

- `count` (number): How many trains that comes to.
- `date` (text): BART's own date, mm/dd/yyyy.
- `retrieved_at` (text): The same moment as an ISO 8601 instant.
- `route` (text): The route number that was read.
- `schedule_number` (text): Which published timetable this came from.
- `time` (text): BART's own Pacific clock time.
- `trains` (list): Every train on the route that day, in order.

**Example output**

```json
{
  "count": 1,
  "date": "08/27/2026",
  "retrieved_at": "2026-08-27T17:12:34-07:00",
  "route": "1",
  "schedule_number": "37",
  "time": "05:12:34 PM PDT",
  "trains": [
    {
      "index": "42",
      "stop_count": 2,
      "stops": [
        {
          "carries_bikes": true,
          "depart_time": "4:14 PM",
          "level": "",
          "load": "1",
          "station": "ANTC"
        },
        {
          "carries_bikes": true,
          "depart_time": "5:18 PM",
          "level": "",
          "load": "2",
          "station": "EMBR"
        }
      ]
    }
  ]
}
```

### Get a station's timetable

Read the published timetable for one station on one day: every scheduled train through it, where each one is headed and when it leaves. This is the plan rather than the live board, so it answers 'what runs from here on a Sunday?' where Get real-time departures answers 'what is coming now'. Leave the date empty for today.

**Inputs**

- Station (`station`, text, required): Which station to look up. Pick one, or reference a station abbreviation such as EMBR from a previous step.
- Date (`date`, date): Which day to read. Leave empty for today. BART only publishes timetables for the schedules it has released, so a date far in the future falls back to the current one.

**Outputs**

- `count` (number): How many trains that comes to.
- `date` (text): BART's own date, mm/dd/yyyy.
- `retrieved_at` (text): The same moment as an ISO 8601 instant.
- `schedule_number` (text): Which published timetable this came from.
- `station` (object)
- `time` (text): BART's own Pacific clock time.
- `trains` (list): Every scheduled train through the station that day.

**Example output**

```json
{
  "count": 1,
  "date": "08/27/2026",
  "retrieved_at": "2026-08-27T17:12:34-07:00",
  "schedule_number": "37",
  "station": {
    "abbreviation": "EMBR",
    "name": "Embarcadero"
  },
  "time": "05:12:34 PM PDT",
  "trains": [
    {
      "arrive_time": "6:02 PM",
      "carries_bikes": true,
      "depart_time": "5:18 PM",
      "head_station": "SFIA/MLBR",
      "line": "ROUTE 1",
      "load": "1",
      "train_id": "1234",
      "train_index": "42"
    }
  ]
}
```

### Get elevator status

List the station elevators currently out of service, which is what decides whether a step-free journey is possible today. BART reports these through the same shape as a service advisory, and as with those the 'nothing is wrong' placeholder is dropped, so an empty list means every lift is working and has_outages is the flag to branch on.

**Inputs**: None.

**Outputs**

- `advisories` (list): The lifts currently out of service, reported in the same shape as a service advisory. Empty when they are all working.
- `count` (number): How many outages are in force.
- `date` (text): BART's own date, mm/dd/yyyy.
- `has_outages` (true/false): True when at least one elevator is out of service.
- `retrieved_at` (text): The same moment as an ISO 8601 instant.
- `time` (text): BART's own Pacific clock time.

**Example output**

```json
{
  "advisories": [
    {
      "description": "The elevator to the platform at Powell St. is out of service.",
      "expires": null,
      "id": "2",
      "posted": "Thu Aug 27 2026 09:14:00 AM PDT",
      "sms_text": "Powell St. platform elevator out of service.",
      "station": "Powell St.",
      "type": "ELEVATOR"
    }
  ],
  "count": 1,
  "date": "08/27/2026",
  "has_outages": true,
  "retrieved_at": "2026-08-27T17:12:34-07:00",
  "time": "05:12:34 PM PDT"
}
```

### Get real-time departures

Read the live departure board for a station: every train due, how many minutes away it is, which platform and direction it leaves from, how many cars it has, whether it takes bikes and how late it is running. BART groups its estimates by destination, so they are flattened here into one row per train and sorted by how soon it goes, which makes departures[0] the next train out whatever line it is on. A train at the platform reports 0 minutes with leaving_now set, rather than the word BART sends. Filter by platform or direction to narrow the board, or pick 'Every station (ALL)' to read the whole system in one request. When there is nothing due, the departures list is empty and BART's own explanation is in warning.

**Inputs**

- Station (`station`, text, required): Which station's board to read. Pick one, pick 'Every station (ALL)' to read the whole system in a single request, or reference a station abbreviation from a previous step.
- Platform (`platform`, text): Only return trains leaving from this platform. Leave empty for the whole station. Platform numbers are the station's own, so which platform is which depends on the station. One of: `1` (Platform 1), `2` (Platform 2), `3` (Platform 3), `4` (Platform 4).
- Direction (`direction`, text): Only return trains heading this way. Leave empty for both directions. BART reports direction as north or south whatever the line actually does on a map. One of: `n` (Northbound), `s` (Southbound).

**Outputs**

- `count` (number): How many trains were returned.
- `date` (text): BART's own date, mm/dd/yyyy.
- `departures` (list): Every train that was returned, flattened out of BART's per-destination grouping and sorted by how soon it leaves, so departures[0] is the next train out.
- `retrieved_at` (text): The same moment as an ISO 8601 instant, so it can be compared with times from other steps.
- `station_count` (number): How many stations' boards were returned.
- `stations` (list): The same trains grouped by station, which is the shape a departure board needs. One entry when one station was asked for; every station when ALL was.
- `time` (text): BART's own Pacific clock time, e.g. '12:34:56 PM PDT'.
- `warning` (text): What BART said when it had nothing to report, e.g. 'No data matched your criteria.' Null when trains were returned.

**Example output**

```json
{
  "count": 2,
  "date": "08/27/2026",
  "departures": [
    {
      "carries_bikes": true,
      "cars": 10,
      "delay_minutes": 0,
      "delay_seconds": 0,
      "destination": "Antioch",
      "destination_abbreviation": "ANTC",
      "direction": "North",
      "is_cancelled": false,
      "is_delayed": false,
      "is_limited": false,
      "is_scheduled_estimate": true,
      "leaving_now": true,
      "line_color": "YELLOW",
      "line_hex_color": "#ffff33",
      "minutes_away": 0,
      "minutes_text": "Leaving",
      "platform": "2",
      "station": "Embarcadero",
      "station_abbreviation": "EMBR"
    },
    {
      "carries_bikes": true,
      "cars": 8,
      "delay_minutes": 2,
      "delay_seconds": 120,
      "destination": "SFO/Millbrae",
      "destination_abbreviation": "MLBR",
      "direction": "South",
      "is_cancelled": false,
      "is_delayed": true,
      "is_limited": false,
      "is_scheduled_estimate": true,
      "leaving_now": false,
      "line_color": "YELLOW",
      "line_hex_color": "#ffff33",
      "minutes_away": 6,
      "minutes_text": "6",
      "platform": "1",
      "station": "Embarcadero",
      "station_abbreviation": "EMBR"
    }
  ],
  "retrieved_at": "2026-08-27T17:12:34-07:00",
  "station_count": 1,
  "stations": [
    {
      "abbreviation": "EMBR",
      "count": 2,
      "departures": [
        {
          "carries_bikes": true,
          "cars": 10,
          "delay_minutes": 0,
          "delay_seconds": 0,
          "destination": "Antioch",
          "destination_abbreviation": "ANTC",
          "direction": "North",
          "is_cancelled": false,
          "is_delayed": false,
          "is_limited": false,
          "is_scheduled_estimate": true,
          "leaving_now": true,
          "line_color": "YELLOW",
          "line_hex_color": "#ffff33",
          "minutes_away": 0,
          "minutes_text": "Leaving",
          "platform": "2",
          "station": "Embarcadero",
          "station_abbreviation": "EMBR"
        },
        {
          "carries_bikes": true,
          "cars": 8,
          "delay_minutes": 2,
          "delay_seconds": 120,
          "destination": "SFO/Millbrae",
          "destination_abbreviation": "MLBR",
          "direction": "South",
          "is_cancelled": false,
          "is_delayed": true,
          "is_limited": false,
          "is_scheduled_estimate": true,
          "leaving_now": false,
          "line_color": "YELLOW",
          "line_hex_color": "#ffff33",
          "minutes_away": 6,
          "minutes_text": "6",
          "platform": "1",
          "station": "Embarcadero",
          "station_abbreviation": "EMBR"
        }
      ],
      "name": "Embarcadero",
      "warning": null
    }
  ],
  "time": "05:12:34 PM PDT",
  "warning": null
}
```

### Get route details

Get one route in full, including every station it calls at in travel order. The station list is the reason to call this: it is the only place BART publishes which stops are on a line, which is what answers 'can I get there without changing?'.

**Inputs**

- Route (`route`, text, required): Which route to look up. Pick one, or reference a route number from a previous step. A route is one direction of one line, so the northbound and southbound halves are separate routes.
- Schedule number (`schedule`, text): Read a specific published timetable rather than the one in force today. The numbers come from the List published schedules action; leave empty for the current one.
- Date (`date`, date): Which day to read. Leave empty for today. BART only publishes timetables for the schedules it has released, so a date far in the future falls back to the current one.

**Outputs**

- `route` (object)
- `schedule_number` (text): Which published timetable this came from.

**Example output**

```json
{
  "route": {
    "abbreviation": "YL-S",
    "color": "YELLOW",
    "destination": "SFIA",
    "direction": "South",
    "hex_color": "#ffff33",
    "holidays": 0,
    "name": "Antioch to SFIA/Millbrae",
    "number": "1",
    "origin": "ANTC",
    "route_id": "ROUTE 1",
    "station_count": 4,
    "stations": [
      "ANTC",
      "PITT",
      "EMBR",
      "SFIA"
    ]
  },
  "schedule_number": "37"
}
```

### Get service advisories

Read what BART is currently reporting about its service: delays, disruptions and anything else riders are being told. BART never answers this with an empty list, so when nothing is wrong it sends a single 'no delays reported' placeholder; that entry is recognised and dropped here, which means an empty advisories list really does mean normal service and has_advisories is the flag to branch on.

**Inputs**: None.

**Outputs**

- `advisories` (list): Everything BART is currently reporting. Empty when service is normal: BART's 'no delays reported' placeholder is dropped, so an empty list really means nothing is wrong.
- `count` (number): How many advisories are in force.
- `date` (text): BART's own date, mm/dd/yyyy.
- `has_advisories` (true/false): True when something is actually being reported. Branch on this rather than on the count of a list that always used to hold one row.
- `retrieved_at` (text): The same moment as an ISO 8601 instant.
- `time` (text): BART's own Pacific clock time.

**Example output**

```json
{
  "advisories": [
    {
      "description": "There is a 10 minute delay in service on the Yellow Line in the Antioch direction due to a maintenance problem.",
      "expires": "Thu Aug 27 2026 07:05:00 PM PDT",
      "id": "1",
      "posted": "Thu Aug 27 2026 05:05:00 PM PDT",
      "sms_text": "10 min delay Yellow Line to Antioch (maintenance).",
      "station": "BART",
      "type": "DELAY"
    }
  ],
  "count": 1,
  "date": "08/27/2026",
  "has_advisories": true,
  "retrieved_at": "2026-08-27T17:12:34-07:00",
  "time": "05:12:34 PM PDT"
}
```

### Get station access details

Find out how to get into, out of and around one station: parking and when it fills up, bike racks, lockers and bike stations, car share, and the connecting transit that serves it. Parking, bikes and lockers each come back twice, as a true/false flag and as the prose describing them, so a workflow can branch on the flag and show the words.

**Inputs**

- Station (`station`, text, required): Which station to look up. Pick one, or reference a station abbreviation such as EMBR from a previous step.

**Outputs**

- `station` (object)

**Example output**

```json
{
  "station": {
    "abbreviation": "EMBR",
    "bike_station_text": "A staffed bike station is next to the Market Street exit.",
    "car_share": "Car share vehicles are available nearby.",
    "destinations": "Muni Metro, ferries and downtown bus lines.",
    "entering": "Entrances are on both sides of Market Street.",
    "exiting": "Exits lead to Market Street and to the Embarcadero Center.",
    "fill_time": null,
    "has_bike_racks": true,
    "has_bike_station": true,
    "has_lockers": true,
    "has_parking": false,
    "link": "https://www.bart.gov/stations/EMBR",
    "lockers": "Bike lockers are available on the concourse.",
    "name": "Embarcadero",
    "parking": "There is no parking at this station.",
    "transit_information": "Muni, Golden Gate Transit and AC Transit."
  }
}
```

### Get station details

Get one station in full. This is the only lookup that carries the platform layout and the routes calling at the station in each direction, both of which the station list leaves out, along with BART's own description of the place and what is worth knowing nearby.

**Inputs**

- Station (`station`, text, required): Which station to look up. Pick one, or reference a station abbreviation such as EMBR from a previous step.

**Outputs**

- `station` (object)

**Example output**

```json
{
  "station": {
    "abbreviation": "EMBR",
    "address": "298 Market Street",
    "attraction": "The Embarcadero and Ferry Building",
    "city": "San Francisco",
    "county": "sanfrancisco",
    "cross_street": "Market Street at Spear Street",
    "food": "Ferry Building Marketplace",
    "intro": "Embarcadero Station is at the foot of Market Street, a short walk from the Ferry Building and the waterfront.",
    "latitude": 37.792874,
    "link": "https://www.bart.gov/stations/EMBR",
    "longitude": -122.39702,
    "name": "Embarcadero",
    "north_platforms": [
      "2"
    ],
    "north_routes": [
      "ROUTE 2",
      "ROUTE 4",
      "ROUTE 6",
      "ROUTE 8"
    ],
    "platform_info": "Northbound (Oakland) trains use platform 2.",
    "shopping": "Embarcadero Center",
    "south_platforms": [
      "1"
    ],
    "south_routes": [
      "ROUTE 1",
      "ROUTE 3",
      "ROUTE 5",
      "ROUTE 7"
    ],
    "state": "CA",
    "zipcode": "94105"
  }
}
```

### Get the fare between two stations

Look up what it costs to travel between two stations without planning a journey to get it. The headline fare comes back alongside every class BART prices the same trip at, cheapest first, so a workflow can quote the senior, youth or Clipper price rather than only the standard one.

**Inputs**

- From station (`origin`, text, required): Where the journey starts. Pick a station, or reference an abbreviation such as EMBR from a previous step.
- To station (`destination`, text, required): Where the journey ends. Must be a different station from the one it starts at.
- Date (`date`, date): Which day to read. Leave empty for today. BART only publishes timetables for the schedules it has released, so a date far in the future falls back to the current one.

**Outputs**

- `clipper_fare` (number): What the same journey costs paying with Clipper.
- `destination` (text): Where it ends, as a station abbreviation.
- `fare` (number): The headline fare, in US dollars.
- `fares` (list): Every fare class for this journey, cheapest first.
- `origin` (text): Where the journey starts, as a station abbreviation.
- `schedule_number` (text): Which published timetable the fare comes from.

**Example output**

```json
{
  "clipper_fare": 4.05,
  "destination": "12TH",
  "fare": 4.05,
  "fares": [
    {
      "amount": 1.55,
      "class": "clipper_senior",
      "name": "Senior/Disabled Clipper"
    },
    {
      "amount": 3.05,
      "class": "clipper_youth",
      "name": "Youth Clipper"
    },
    {
      "amount": 4.05,
      "class": "clipper",
      "name": "Clipper"
    }
  ],
  "origin": "EMBR",
  "schedule_number": "37"
}
```

### Get the number of trains running

Count the BART trains in service right now. It is the cheapest read of the system's health there is: the number falls towards zero overnight and drops sharply during a major disruption, so a workflow can watch it without opening a single departure board.

**Inputs**: None.

**Outputs**

- `date` (text): BART's own date, mm/dd/yyyy.
- `retrieved_at` (text): The same moment as an ISO 8601 instant.
- `time` (text): BART's own Pacific clock time.
- `train_count` (number): How many BART trains are in service right now. It falls towards zero overnight and during a major disruption.

**Example output**

```json
{
  "date": "08/27/2026",
  "retrieved_at": "2026-08-27T17:12:34-07:00",
  "time": "05:12:34 PM PDT",
  "train_count": 51
}
```

### List holidays

List the holidays BART runs a different timetable on, each with the day's service it runs instead. A Thursday marked 'Sunday' is enough on its own to tell a workflow that the weekday timetable does not apply, which is what makes this worth checking before quoting a commute.

**Inputs**: None.

**Outputs**

- `count` (number): How many that comes to.
- `holidays` (list): The holidays BART runs a different timetable on.

**Example output**

```json
{
  "count": 2,
  "holidays": [
    {
      "date": "01/01/2027",
      "name": "New Year's Day",
      "schedule_type": "Sunday"
    },
    {
      "date": "11/26/2026",
      "name": "Thanksgiving Day",
      "schedule_type": "Sunday"
    }
  ]
}
```

### List published schedules

List the timetables BART has published, each with the date it came into force. Every timetable and fare action takes one of these numbers in its Schedule number field, so this is where a workflow that needs something other than today's timetable gets the number to pass.

**Inputs**: None.

**Outputs**

- `count` (number): How many that comes to.
- `schedules` (list): Every timetable BART has published, oldest first.

**Example output**

```json
{
  "count": 2,
  "schedules": [
    {
      "effective_date": "02/10/2026",
      "id": "36"
    },
    {
      "effective_date": "06/15/2026",
      "id": "37"
    }
  ]
}
```

### List routes

List every route BART is running, with the colour each line is known by and the direction it runs in. A line is two routes, one per direction, so the northbound and southbound halves appear separately and direction is what tells them apart. The route number on each row is what the route actions take.

**Inputs**

- Schedule number (`schedule`, text): Read a specific published timetable rather than the one in force today. The numbers come from the List published schedules action; leave empty for the current one.
- Date (`date`, date): Which day to read. Leave empty for today. BART only publishes timetables for the schedules it has released, so a date far in the future falls back to the current one.

**Outputs**

- `count` (number): How many routes that comes to.
- `routes` (list): Every route BART is running under this timetable.
- `schedule_number` (text): Which published timetable these routes come from.

**Example output**

```json
{
  "count": 2,
  "routes": [
    {
      "abbreviation": "YL-S",
      "color": "YELLOW",
      "direction": "South",
      "hex_color": "#ffff33",
      "name": "Antioch to SFIA/Millbrae",
      "number": "1",
      "route_id": "ROUTE 1"
    },
    {
      "abbreviation": "YL-N",
      "color": "YELLOW",
      "direction": "North",
      "hex_color": "#ffff33",
      "name": "SFIA/Millbrae to Antioch",
      "number": "2",
      "route_id": "ROUTE 2"
    }
  ],
  "schedule_number": "37"
}
```

### List special schedules

List the planned service changes BART has announced: weekend track work, closures and single-tracking, each with the days and hours it applies to and the routes involved. These go up well in advance, so a workflow can warn about next weekend's closure before anyone is standing on a platform. Unlike an advisory, a quiet period really does return nothing.

**Inputs**: None.

**Outputs**

- `count` (number): How many that comes to.
- `notices` (list): The planned service changes BART has announced. Unlike an advisory, a quiet period really does return nothing.

**Example output**

```json
{
  "count": 1,
  "notices": [
    {
      "day_of_week": "SA-SU",
      "destination": "PITT",
      "end_date": "09/07/2026",
      "end_time": "11:59 PM",
      "link": "https://www.bart.gov/news/articles/2026/news20260828",
      "origin": "CONC",
      "routes_affected": "ROUTE 1, ROUTE 2",
      "start_date": "09/05/2026",
      "start_time": "12:00 AM",
      "text": "Track work between Concord and Pittsburg/Bay Point. Buses replace trains all weekend."
    }
  ]
}
```

### List stations

List every BART station with its address, city, county and coordinates. The whole system comes back in one request and it only changes when BART opens or renames a station, so this is where a workflow resolves a name or a location to the abbreviation every other action takes.

**Inputs**: None.

**Outputs**

- `count` (number): How many stations there are.
- `stations` (list): Every BART station, in the order BART lists them.

**Example output**

```json
{
  "count": 2,
  "stations": [
    {
      "abbreviation": "EMBR",
      "address": "298 Market Street",
      "city": "San Francisco",
      "county": "sanfrancisco",
      "latitude": 37.792874,
      "longitude": -122.39702,
      "name": "Embarcadero",
      "state": "CA",
      "zipcode": "94105"
    },
    {
      "abbreviation": "12TH",
      "address": "1245 Broadway",
      "city": "Oakland",
      "county": "alameda",
      "latitude": 37.803664,
      "longitude": -122.271604,
      "name": "12th St. Oakland City Center",
      "state": "CA",
      "zipcode": "94612"
    }
  ]
}
```

### Plan a trip

Plan a journey between two stations leaving at a given time. Each suggestion carries when it leaves and arrives, what it costs in every fare class BART prices it at, and the trains that make it up leg by leg, plus a duration and a transfer count worked out here because BART sends neither reliably. Leave the time empty to plan from now; use Trips before and Trips after to take in the departures either side of it.

**Inputs**

- From station (`origin`, text, required): Where the journey starts. Pick a station, or reference an abbreviation such as EMBR from a previous step.
- To station (`destination`, text, required): Where the journey ends. Must be a different station from the one it starts at.
- Depart at (`departure_time`, date and time): When the traveller wants to leave. Leave empty to plan from now. BART runs on Pacific time and the value is converted for you, so a time carried in from an earlier step does not have to be in that zone.
- Trips before (`before`, number): How many earlier departures to include as well, from 0 to 4. BART returns 2 when this is left empty. From 0 to 4.
- Trips after (`after`, number): How many later departures to include as well, from 0 to 4. BART returns 2 when this is left empty. From 0 to 4.

**Outputs**

- `count` (number): How many journeys came back.
- `date` (text): The day BART planned for.
- `destination` (text): The station they end at.
- `origin` (text): The station the journeys start from.
- `schedule_number` (text): Which published timetable they were planned against.
- `time` (text): The time BART planned from.
- `trips` (list): The journeys BART suggests, earliest first. More than one comes back because the Trips before and Trips after fields ask for the departures either side of the requested time.

**Example output**

```json
{
  "count": 1,
  "date": "08/27/2026",
  "destination": "12TH",
  "origin": "EMBR",
  "schedule_number": "37",
  "time": "5:12 PM",
  "trips": [
    {
      "arrive_date": "08/27/2026",
      "arrive_time": "5:40 PM",
      "arrives_at": "2026-08-27T17:40:00-07:00",
      "clipper_fare": 4.05,
      "depart_date": "08/27/2026",
      "depart_time": "5:18 PM",
      "departs_at": "2026-08-27T17:18:00-07:00",
      "destination": "12TH",
      "duration_minutes": 22,
      "fare": 4.05,
      "fares": [
        {
          "amount": 1.55,
          "class": "clipper_senior",
          "name": "Senior/Disabled Clipper"
        },
        {
          "amount": 3.05,
          "class": "clipper_youth",
          "name": "Youth Clipper"
        },
        {
          "amount": 4.05,
          "class": "clipper",
          "name": "Clipper"
        }
      ],
      "legs": [
        {
          "arrive_date": "08/27/2026",
          "arrive_time": "5:40 PM",
          "arrives_at": "2026-08-27T17:40:00-07:00",
          "carries_bikes": true,
          "depart_date": "08/27/2026",
          "depart_time": "5:18 PM",
          "departs_at": "2026-08-27T17:18:00-07:00",
          "destination": "12TH",
          "head_station": "ANTC",
          "line": "ROUTE 2",
          "load": "2",
          "order": 1,
          "origin": "EMBR",
          "train_id": "1234",
          "train_index": "42",
          "transfer_code": null
        }
      ],
      "origin": "EMBR",
      "transfer_count": 0
    }
  ]
}
```

### Plan a trip arriving by a time

Plan a journey worked backwards from when the traveller has to be there, which is what answers 'what is the last train that still gets me to the airport by six?'. The answer is shaped exactly like Plan a trip, so a workflow can read either the same way.

**Inputs**

- From station (`origin`, text, required): Where the journey starts. Pick a station, or reference an abbreviation such as EMBR from a previous step.
- To station (`destination`, text, required): Where the journey ends. Must be a different station from the one it starts at.
- Arrive by (`arrival_time`, date and time): When the traveller has to be there. Leave empty to plan from now. Converted to Pacific time for you, the same as the departure field.
- Trips before (`before`, number): How many earlier departures to include as well, from 0 to 4. BART returns 2 when this is left empty. From 0 to 4.
- Trips after (`after`, number): How many later departures to include as well, from 0 to 4. BART returns 2 when this is left empty. From 0 to 4.

**Outputs**

- `count` (number): How many journeys came back.
- `date` (text): The day BART planned for.
- `destination` (text): The station they end at.
- `origin` (text): The station the journeys start from.
- `schedule_number` (text): Which published timetable they were planned against.
- `time` (text): The time BART planned from.
- `trips` (list): The journeys BART suggests, earliest first. More than one comes back because the Trips before and Trips after fields ask for the departures either side of the requested time.

**Example output**

```json
{
  "count": 1,
  "date": "08/27/2026",
  "destination": "12TH",
  "origin": "EMBR",
  "schedule_number": "37",
  "time": "5:12 PM",
  "trips": [
    {
      "arrive_date": "08/27/2026",
      "arrive_time": "5:40 PM",
      "arrives_at": "2026-08-27T17:40:00-07:00",
      "clipper_fare": 4.05,
      "depart_date": "08/27/2026",
      "depart_time": "5:18 PM",
      "departs_at": "2026-08-27T17:18:00-07:00",
      "destination": "12TH",
      "duration_minutes": 22,
      "fare": 4.05,
      "fares": [
        {
          "amount": 1.55,
          "class": "clipper_senior",
          "name": "Senior/Disabled Clipper"
        },
        {
          "amount": 3.05,
          "class": "clipper_youth",
          "name": "Youth Clipper"
        },
        {
          "amount": 4.05,
          "class": "clipper",
          "name": "Clipper"
        }
      ],
      "legs": [
        {
          "arrive_date": "08/27/2026",
          "arrive_time": "5:40 PM",
          "arrives_at": "2026-08-27T17:40:00-07:00",
          "carries_bikes": true,
          "depart_date": "08/27/2026",
          "depart_time": "5:18 PM",
          "departs_at": "2026-08-27T17:18:00-07:00",
          "destination": "12TH",
          "head_station": "ANTC",
          "line": "ROUTE 2",
          "load": "2",
          "order": 1,
          "origin": "EMBR",
          "train_id": "1234",
          "train_index": "42",
          "transfer_code": null
        }
      ],
      "origin": "EMBR",
      "transfer_count": 0
    }
  ]
}
```
