The General Transit Feed Specification (GTFS) uses 2 different files to model fares:
fare_attributes.txt:
This file contains a FareAttribute that defines a fare class. A FareAttribute has a price, currency, and a setting for whether it must be purchased on board the service or before boarding. It also defines the number of transfers it can be used for, and the duration for which it is valid.fare_rules.txt:
This file contains a description of how tickets are applied in the transit system.
This article describes how the 2 different files work together to create an accurate data feed for your fares.
Fare attributes
The file fare_attributes.txt
defines aspects of a fare (ID, payment type, etc.). This file has the following structure:
This example shows a simple fare_attributes.txt
file:
fare_id |
price |
currency_type |
payment_method |
transfers |
transfer_duration |
---|---|---|---|---|---|
1 | 0.00 | USD | 0 | 0 | 0 |
2 | 0.50 | USD | 0 | 0 | 0 |
3 | 1.00 | USD | 0 | 0 | 0 |
4 | 1.50 | USD | 0 | 0 | 0 |
5 | 2.00 | USD | 0 | 0 | 0 |
For each fare, define in the fare_attributes.txt
file the price
, currency_type
and payment_method
. Allow or prevent transfers with the transfers
field (0 is none allowed, 1 allows one, 2 allows two; an empty field allows unlimited transfers). Set the length of time (in seconds) before a transfer expires in the transfer_duration
field. The system calculates the transfer_duration
from the departure of the first trip until the arrival of the last trip (check the example below.)
Important:
- To indicate how long a ticket is valid for a fare where no transfers are allowed, set
transfers
to 0 and set the valid time (in seconds) withtransfer_duration
. - Unless you use
transfer_duration
to indicate ticket validity, we recommend you omit this field or leave it empty when you settransfers
to 0.
Fare rules
The fare_rules.txt
file describes how tickets are applied in the transit system. This file has the following structure:
The following example shows a simple fare_rules.txt
file:
fare_id |
route_id |
origin_id |
destination_id |
contains_id |
---|---|---|---|---|
a | TSW | 1 | 1 | |
a | TSE | 1 | 1 | |
a | GRT | 1 | 1 | |
a | GRJ | 1 | 1 | |
b | GRT | 3 | 3 | |
c | GRT | 6 |
The fare_rules.txt
file supports the following fare structures.
- Fare depends on which route the itinerary uses.
- To associate a fare with a specific route, define the
route_id
field. - If a fare is valid for multiple routes, specify an entry for each route in
fare_rules
.
- To associate a fare with a specific route, define the
- Fare depends on origin or destination zones or stations.
- To define fare rules based on the origin or destination zone or station, use the
origin_id
anddestination_id
fields . Origin_id
anddestination_id
reference the zones in which the origin and destination stations are located. To provide this information in filestops.txt
, add thezone_id
field.- To define rules that are station-based only, define a zone for each station in the
stops.txt
file.
- To define fare rules based on the origin or destination zone or station, use the
- Fare depends on which zones the itinerary passes.
- To define fare rules based on zones through which the itinerary passes, use the
contains_id
field to define each zone for which the fare is valid. contains_id
references azone_id
defined in filestops.txt
.
- To define fare rules based on zones through which the itinerary passes, use the
Most fare systems use one of these fare structures or a combination of them. Fares defined without rules are valid for all itineraries that meet their transfer limitations.
If multiple fares are valid for a specific itinerary, the system displays to users the cheapest option.
Fares for multiple agencies
If the feed contains multiple transit agencies, add the agency_id
field to file fare_attributes.txt
for each fare. A fare can belong to only one agency. If a fare belongs to several agencies, you must duplicate the fare.
Special fare categories
Google Maps does not support different fare categories (such as adult, senior, or child). Only one fare appears in routing results. Use the default fare category.
Examples scenarios & how to structure fares
The following sections describe example scenarios and how to structure the fares.
Example 1: All trips have the same fare, unlimited transfers
Suppose Demo Transit Agency has the following fare structure:
- Passengers pay $1.00 on boarding (
price
='1.00',currency
='USD',payment_method
='0'). - Ticket is good for all vehicles and doesn't expire (
transfers
=''). - Passengers can ride as long as they like because
transfer_duration
is omitted.
Since all trips have the same fare, Demo Transit can omit fare_rules.txt
.
File fare_attributes.txt
fare_id |
price |
currency_type |
payment_method |
transfers |
---|---|---|---|---|
only_fare |
1.00 |
USD |
0 |
Calculating an adult fare
The trip planner calculates a fare of $1 for each leg of the itinerary that includes a change of vehicle. However, unlimited transfers are permitted, so the trip planner only displays the lowest charge, that is, the Adult fare of $1.
Example 2: All trips have the same fare, no transfers
Suppose Demo Transit Agency has the following fare structure:
- Passengers pay $1 on boarding (
price
='1.00',currency
='USD',payment_method
='0'). - Passengers can ride as long as they like because
transfer_duration
is omitted. - Any change in vehicles requires a new fare. (
transfers
='0').
Since all trips have the same fare, Demo Transit can omit fare_rules.txt
.
File fare_attributes.txt
fare_id |
price |
currency_type |
payment_method |
transfers |
---|---|---|---|---|
only_fare |
1.00 |
USD |
0 |
0 |
Calculating an adult fare
The trip planner calculates a fare of $1 for each leg of the itinerary that includes a change of vehicle. So an itinerary that requires a change of buses would be $2.
Example 3: All trips have the same fare, transfers allowed
Suppose Demo Transit Agency has the following fare structure:
- Passengers pay $1 on boarding (
price
='1.00',currency
='USD',payment_method
='0'). - Unlimited transfers are allowed within 90 minutes (
transfers
='',transfer_duration
='5400').
Since all trips have the same fare, Demo Transit can omit fare_rules.txt
.
File fare_attributes.txt
fare_id |
price |
currency_type |
payment_method |
transfers |
transfer_duration |
---|---|---|---|---|---|
only_fare |
1.00 |
USD |
0 |
5400 |
Calculating an adult fare
The trip planner calculates a fare of $1 for each leg of the itinerary that includes a change of vehicle. Then it calculates the time for the itinerary. If the itinerary time is less than 90 minutes, the fare is $1.
Example 4: Different pricing for local & express routes
Suppose Demo Transit Agency has the following fare structure:
- Passengers pay $1.75 on boarding local buses (route 1).
- Passengers pay $5 on boarding express buses (routes 2 and 3).
- Transfers aren't allowed.
Since some trips cost more than others, Demo Transit must include fare_rules.txt
, and each route must have an entry to associate it with a fare.
File fare_attributes.txt
fare_id |
price |
currency_type |
payment_method |
transfers |
---|---|---|---|---|
local_fare |
1.75 |
USD |
0 |
0 |
express_fare |
5.00 |
USD |
0 |
0 |
File fare_rules.txt
fare_id |
route_id |
---|---|
local_fare |
Route_1 |
express_fare |
Route_2 |
express_fare |
Route_3 |
Calculating an adult fare
The $5.00 fare is only applicable if you ride routes 2 or 3. The $1.75 fare only applies on route 1. If an itinerary uses routes 1 and 2, the fare is $6.75.
Example 5: Buying a transfer increases the fare
Suppose Demo Transit Agency has the following fare structure:
- Passengers pay $1.75 on boarding local buses.
- Passengers can pay an extra $0.25 on boarding to purchase a transfer.
- Transfers purchased are valid for 90 minutes.
Since these rules apply to all trips, Demo Transit can omit fare_rules.txt
.
File fare_attributes.txt
fare_id |
price |
currency_type |
payment_method |
transfers |
transfer_duration |
---|---|---|---|---|---|
simple_fare |
1.75 |
USD |
0 |
0 |
|
plustransfer_fare |
2.00 |
USD |
0 |
5400 |
Calculating an adult fare
Technically, both fares apply on itineraries that have no transfers. However, the trip planner always chooses the least expensive applicable fare:
- For an itinerary with one transfer,
simple_fare
is $3.50 vs. $2.00 when a transfer is purchased. So the trip planner will report $2.00 fare on all itineraries that require a change of vehicle. - For an itinerary with no transfers, $1.75 fare is less than
plustransfer_fare
of $2.00. So if an itinerary doesn't require a change of vehicle, the fare is $1.75.
Example 6: Fare depends on station pairs, how you get there doesn't matter
In this example, only the entry and exit points from the system matter. To define this fare structure for the feed, each station must have its own unique zone ID defined in stops.txt
. Each station is considered a single zone.
- The
fare_attributes.txt
andfare_rules.txt
files define one row for each pair of stations. - In file
fare_attributes.txt
, theorigin_id
anddestination_id
fields identify station pairs by zone ID.
File fare_attributes.txt
fare_id |
price |
currency_type |
payment_method |
transfers |
---|---|---|---|---|
!S1_to_S2 |
1.75 |
USD |
0 |
|
!S1_to_S3 |
3.25 |
USD |
0 |
|
!S1_to_S4 |
4.55 |
USD |
0 |
|
... |
||||
!S10_to_S1 |
5.65 |
USD |
0 |
File fare_rules.txt
fare_id |
origin_id |
destination_id |
---|---|---|
!S1_to_S2 |
S1 |
S2 |
!S1_to_S3 |
S1 |
S3 |
!S1_to_S4 |
S1 |
S4 |
... |
||
!S10_to_S1 |
S10 |
S1 |
Calculating an adult fare
The trip planner calculates an itinerary, and then looks up the fare rules until it finds a matching origin/destination station pair. The public feed from SF Bay Area BART provides a real-world illustration of this type of fare structure.
Example 7: Fare depends on zones
Suppose Demo Transit Agency has a concentric three-zone system, where fares depend on which zones a passenger passes through during an itinerary. To define this fare structure for the feed, files fare_attributes.txt
and fare_rules.txt
must contain a line for each possible combination of zones. For very complex cross-zone fare structures, it may be simpler to programmatically output fare_rules.txt
using origin and destination to define fares.
File fare_attributes.txt
fare_id |
price |
currency_type |
payment_method |
transfers |
---|---|---|---|---|
F1 |
4.15 |
USD |
0 |
|
F2 |
2.20 |
USD |
0 |
|
F3 |
2.20 |
USD |
0 |
|
F4 |
2.95 |
USD |
0 |
|
F5 |
1.25 |
USD |
0 |
|
F6 |
1.95 |
USD |
0 |
|
F7 |
1.95 |
USD |
0 |
File fare_rules.txt
fare_id |
contains_id |
---|---|
F1 |
1 |
F1 |
2 |
F1 |
3 |
F2 |
1 |
F2 |
2 |
F3 |
1 |
F3 |
3 |
F4 |
2 |
F4 |
3 |
F5 |
1 |
F6 |
2 |
F7 |
3 |
Calculating an adult fare
Let's look more closely at the definitions in fare_rules.txt
.
- F1 applies to any trip that passes through zones (1,2,3).
- F2 applies to any trip that passes through zones (1,2).
- F3 applies to any trip that passes through zones (1,3).
- F4 applies to any trip that passes through zones (2,3).
- F5 applies to any trip that passes through zone 1 only.
- F6 applies to any trip that passes through zone 2 only.
- F7 applies to any trip that passes through zone 3 only.
The trip planner calculates an itinerary, and then looks up the fare rules to determine the fares that apply based on zone. Since F1 also includes travel in zone 1, only F4 ($2.95) applies to a trip from zone 2 to zone 3. A fare rule only applies when the set of zones passed through in an itinerary exactly matches the set specified by the fare rule. For a trip between zones 2 and 3, the trip planner reports $2.95 as the adult fare.
Example 8: Influence of transfers & transfer_duration
The following is an example of a transfer:
- Trip 1 departs at 10:00 and arrives at 11:00.
- Trip 2 departs at 11:15 and arrives at 12:00.
- To make the fare valid for the complete journey, you must allow for at least one transfer and a transfer_duration of at least 2 hours (from 10:00 to 12:00).
Example 9: Fares & block transfers
A block transfer combines 2 trips belonging to different routes, allows passengers to remain on the same vehicle while they transfer from one route to the next. For a trip that has a block transfer, the system selects a fare for all routes involved. Block transfers aren’t counted as transfers for fare modeling.
The following is an example model of a fare for block transfer:
- Assume that there are two routes, A and B.
- Any trip on route A or B costs $1, and any trip including A and B costs $2.
The values in fare_attributes.txt
and fare_rules.txt
should look as follows:
File fare_attributes.txt
fare_id |
price |
currency_type |
payment_method |
transfers |
transfer_duration |
---|---|---|---|---|---|
fare_A |
1.00 |
USD |
0 |
0 |
|
fare_B |
1.00 |
USD |
0 |
0 |
|
fare_AB |
2.00 |
USD |
0 |
0 |
File fare_rules.txt
fare_id |
route_id |
origin_id |
destination_id |
contains_id |
|
---|---|---|---|---|---|
fare_A |
route_A |
||||
fare_B |
route_B |
||||
fare_AB |
route_A |
||||
fare_AB |
route_B |