Best Practices
The Uber API gives you the ability to Request an Uber Product on behalf of users within your application. Given you know where a user currently is, where they want to go, and which Uber product they want to use to get there, you have all of the tools to make that happen with a few simple API endpoints.
While we are giving developers a lot of freedom on how to build interfaces and present information to the users of their applications, there are a few essentials that must be included to ensure a user has all necessary information. This tutorial aims to walk through all of the required Uber API Request calls, how they interact with one another, and provide best practices for building an intuitive user experience.
¶ The Basics
There are essentially five things the ride request endpoints enable your application to do:
- Reserve an upfront fare for a Ride Request - With a start lat/long, end lat/long, and a
product_id
get a Ride Request estimate. - Make a Ride Request - With a start lat/long, end lat/long, a
product_id
, and afare_id
start a Ride Request. - Get a Ride Request Status - Once a Ride Request has been created, you can GET that status and details of that Ride Request. Poll the - Ride Request Details endpoint or use webhooks to be notified of changes.
- Get a Map for a Ride Request - If you need to show a visual representation of the Ride Request.
- Cancel a Ride Request - If a user needs to cancel a Ride Request.
¶ The Sandbox
Because of the real-world nature of the Ride Request endpoints, which call active drivers on the system which result in financial transactions on Uber rider accounts, the Uber API provides a sandbox environment for testing. All ride requests made to the sandbox will result in a simulated ride request that can be programmatically updated. To get an understanding on how to set up your environment for making ride requests within the sandbox environment, see the sandbox guide.
¶ Life cycle of a Ride Request
A ride request can go through many states between the start and end. We indicate this state as the status attribute returned by the ride request endpoint. The possible values for status are:
Status | Description |
---|---|
processing |
The ride request is matching to the most efficient available driver. |
no_drivers_available |
The ride request was unfulfilled because no drivers were available. |
accepted |
The ride request has been accepted by a driver and is “en route” to start location. |
arriving |
The driver has arrived or will be shortly. |
in_progress |
The ride request is “en route” from the start location to the end location. |
driver_canceled |
The ride request has been canceled by the driver. |
rider_canceled |
The ride request canceled by |
completed |
The ride request has been completed by the driver. |
Overall Request Flow
¶ Authorization and Authentication
Applications that wish to take advantage of the ride request endpoints must have their users authorize their application to make requests on their behalf. This is done by having a user grant access of the request
scope to your application via OAuth2.0. See the OAuth 2.0 section of our tutorials for more details.
Once a user has effectively authorized your application, all requests to the ride request endpoint must be made with an OAuth bearer token.
Applications using the request
scope must be approved by Uber before they can be made available to the general public. By default, only the developer and invited application admins may make Requests. Access to the request
scope can be requested in the Auth tab of your app’s dashboard.
¶ Preparing to make a Ride Request
Once a user has granted your application permission to make Requests on their behalf, you only need three pieces of information to do so:
- Product - the
product_id
of the Product the user wishes to have requested. - Start Location - the latitude and longitude pair of where the user would like to be picked up (usually their current location).
- End Location - the latitude and longitude pair of where the user would like to be dropped off.
There are typically three items a user wants to know about a Product before choosing one for making a Request:
- Products Available - given a location, the Uber Products a user can take advantage of, provided by the Products endpoint.
- Estimated Time of Arrival - how quickly a particular product get to your user, provided by the Time Estimates endpoint.
- Estimated Cost of Service - how much a user will be charged to go from the start to the end of a Request, provided by the Price Estimates endpoint.
Once you’ve collected the above info, you can present these details to your user to help them select which product is right for them.
To get the user’s start and end locations, there are quite a few different approaches. Depending on the platform you are developing for, you may get the current location of a user by asking their device at the system level. Perhaps you have a list of recommend locations they can chose. You could also take the same approach as the Uber app and give them a pin on a map that can be dragged and dropped to specify location.
¶ Creating a Ride Request
Now that you have the product they wish to use and the start and end locations of the ride request they would like to make, we have everything we need. Take those values and make a POST on behalf of the user to the Ride Request endpoint.
curl -H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" -X POST -d \
'{"product_id": "821415d8-3bd5-4e27-9604-194e4359a449", "start_latitude":"37.775232", "start_longitude": "-122.4197513", "end_latitude":"37.7899886", "end_longitude": "-122.4021253","fare_id":"650235cb925e3503e87f14e62f9ef3e90beb0e14d893395c4b8e5118f1ac872c"}' \
https://api.uber.com/v1.2/requests
This POST will result in three possible responses:
- 202 Accepted - Your Request is successfully being processed
- 409 Conflict - An error has occurred, possibly due to Surge Pricing or no drivers available.
- 422 Unprocessable Entity - An error has occurred, most likely due to an issue with the user’s Uber account.
In most cases, as long as you provide a valid product, start location, and end location, you will get a 202 Accepted response letting you know that the ride request was created successfully.
Status-code 202 Accepted
{
"status": "processing",
"product_id": "821415d8-3bd5-4e27-9604-194e4359a449",
"destination": {
"latitude": 37.7899886,
"longitude": -122.4021253
},
"driver": null,
"pickup": {
"latitude": 37.775232,
"longitude": -122.4197513
},
"request_id": "0aec0061-1e20-4239-a0b7-78328e9afec8",
"eta": null,
"location": null,
"vehicle": null,
"shared": false
}
In the cases where you receive a 409 Conflict
for surge pricing, please see our Handling Surge Pricing section of the tutorial.
¶ Processing a Ride Request
Now that you have successfully created a ride request and have a request_id
that was returned in the response to your POST, you can continuously poll the Uber API to get the current status and additional details of a Request. We recommend you do this every 3-5 seconds to give the most up-to-date details possible.
curl "https://api.uber.com/v1.2/requests/<REQUEST_ID>" \
-H "Authorization: Bearer <TOKEN>"
Details you will be provided include the the driver’s name, picture, and phone number as well as the location, make, model and license plate of the vehicle. The more of these details you provide, the better the experience the user will have and the more likely they will successfully complete a Ride Request.
Status-Code: 200 OK
{
"status": "accepted",
"product_id": "821415d8-3bd5-4e27-9604-194e4359a449",
"destination": {
"latitude": 37.7899886,
"eta": 13,
"longitude": -122.4021253
},
"driver": {
"phone_number": "+14155551212",
"rating": 5.0,
"picture_url": "https://d1w2poirtb3as9.cloudfront.net/16ce502f4767f17b120e.png",
"name": "Travis",
"sms_number": "+14155551212"
},
"pickup": {
"latitude": 37.775232,
"eta": 3,
"longitude": -122.4197513
},
"request_id": "9bdb3278-21bd-46b8-90fa-51404b0d6acf",
"location": {
"latitude": 37.7818891732,
"bearing": 171,
"longitude": -122.427424444
},
"vehicle": {
"make": "BMW",
"picture_url": "http://d3a74cgiihgn4m.cloudfront.net/2016/bmw/7-series/0814_CCCCCC_3.png",
"model": "7-series",
"license_plate": "UBER"
},
"shared": false
}
¶ Canceling a Ride Request
If implementing ride requests functionality in your application, you must provide the ability to cancel that Ride Request within your application.
Make a request to the DELETE /requests/{request_id} with the specified request_id
and ensure a successful response is returned. This is usually the result of a user pressing a ‘Cancel’ button and confirming within a modal.
curl -X "DELETE" "https://api.uber.com/v1.2/requests/<REQUEST_ID>" \
-H "Authorization: Bearer <TOKEN>"
Request Initiation and Processing
¶ Displaying Details of a Ride Request
As a ride request is ongoing, you will want to display the details of the ride request to the user in a way that helps them understand what is happening and give them the information they need to find or get in touch with their driver.
For instance, when a ride request is processing
it’s probably best to let the user know Uber is attempting to find them a driver. Using a spinner or other loading indicator can convey this message well.
Once a ride request status has changed to accepted
you can let your user know a vehicle is enroute, what the details of the driver are, and remind them their pickup location. You can even show them the location of the vehicle on a map because the Uber API provides this location information.
If the ride request status becomes arriving
you probably want to indicate this to the user in a way that gets their attention. Once a ride request is in_progress
you can provide the information a user might find useful once they are already in the vehicle.
Unfortunately, there are some times when a driver must cancel a Request, and your application should let the user know when this happens. This will be indicated when the status of a ride request is returned as driver_canceled.
At this point it’s usually helpful to make it easy for a user to re attempt a Request.
Lastly, sometimes a user needs to get in touch with a driver to clarify their location, so please provide an easy way to call or SMS the driver from within your application.
Request Accepted Flow
¶ Indicating Ride Status Throughout Application
One of the benefits of integrating the ride request endpoints within your application is that while a ride request is ongoing, you can continue to interact with your user without them leaving your app.
To take advantage of this, we recommend you present the status of an ongoing ride request throughout your application. This provides ride request status at a quick glance as well as easy access to more details and ride request actions.
The most common statuses and information users are interested are:
- Processing - The dispatch is waiting for a driver to accept the ride.
- Accepted - The driver is en route, so it is a great place to show an ETA.
- Arriving - The driver is arriving now! Let your users know it is time to find their driver.
- In Progress - The user is in a vehicle and off to their destination.
- Completed - The user has arrived at their destination.
Indicate Ride Status
¶ Upfront Fares
We moved to upfront, per trip fares two years ago when we launched uberPOOL. Riders needed to enter their destinations so we could match them with other people headed the same way. This allowed us to calculate the actual fare in advance and show it to riders before they booked their ride. We provide upfront fares for all products which requires specifying the end location at the time of the request.
Upfront fares are calculated using the expected time and distance of the trip and local traffic, as well as how many riders and nearby drivers are using Uber at that moment. And when fares go up due to increased demand, instead of surge lightning bolts and pop-up screens, riders are given the actual fare before they request their ride. There’s no complicated math and no surprises: passengers can just sit back and enjoy the ride.
Upfront fares means the total fare is known before the ride is taken.
- An end location is required
- There is no surge confirmation flow
- The user should specify a
fare_id
to confirm consent to the upfront fare - The user should specify the number of seats that are required for shared products (like UberPOOL)
- In the products endpoint
GET /products
, products will have theupfront_fare_enabled
field set totrue
. - Use the ride request estimate endpoint
POST /requests/estimate
with theproduct_id
to get afare_id
. Thefare_id
can be used to lock down an upfront fare and arrival time for a trip. Thefare_id
expires after two minutes. If thefare_id
is expired or not valid, we return a422
error. - Request the ride using the ride request endpoint
POST /requests
with thefare_id
returned in the previous step.
¶ Handling Surge Pricing
If a product has the upfront_fare_enabled
field set to false
you will still need to support surge pricing. The way a user accepts surge pricing is similar to how they authorize your application to use the request
scope. We provide you with an HREF you send the user to, they accept the the surge multiplier by submitting a web form, and then we redirect back to your application with a surge_confirmation_id
that you use to successfully make a Request.
Surge Flow
While most of the time making a Ride Request is as easy as providing product and location information, there is a chance that a product with have surge pricing in effect. With surge pricing, Uber rates increase to get more cars on the road and ensure reliability during the busiest times. When enough cars are on the road, prices go back down to normal levels.
To ensure your users are fully informed about the current pricing of a Product, the Uber API will not allow a ride request to be made without the user accepting the current surge price multiple.
To test this, you need to enable surge pricing by making a PUT to the Products sandbox endpoint with the desired surge_multiplier
. Anything above 1.0 will activate surge pricing for a particular Product, which turns on the surge confirmation flow when making a ride request for that Product in the sandbox.
When surge pricing is in effect, a POST to create a ride request will be returned with a 409 Conflict
error that contains a surge_confirmation
object within the meta
component of the response; there are two values present, which are surge_confirmation_id
and href.
For a user to accept surge pricing, you must send them to the HREF within a web browser. They will be presented with a surge confirmation screen where they must accept the surge multiplier by submitting a web form. In some cases, when the surge multiplier is above a certain limit (most of the time when 2.0x or above), the confirmation page will be a two step process.
Once a user successfully accepts the surge pricing multiple, they will be redirected to your application via SURGE_CONFIRMATION_REDIRECT_URI
(that is configurable via the Application Dashboard) which will include the surge_confirmation_id
as a querystring parameter.
Now that the user has accepted surge and has returned to your application, you may make a second POST to the Ride Request endpoint with the surge_confirmation_id
parameter filled in with the appropriate identifier.
¶ uberPOOL
UberPOOL allows you to share your ride and split the cost of your trip with another Uber rider headed in the same direction. To integrate with UberPOOL, here is the recommended flow:
- In the products endpoint
GET /products
, UberPOOL products will have theshared
field set totrue
. - If the user chooses a shared product, prompt for the number of seats needed (1 or 2).
- Use the ride request estimate endpoint
POST /requests/estimate
with the UberPOOLproduct_id
andseat_count
to get afare_id
. - Request the ride using the ride request endpoint
POST /requests
with thefare_id
returned in the previous step. - The trip details
GET /requests/{request_id}
will include UberPOOL specific fields. The fields add more context to the trip. For instance, the list ofriders
sharing the trip with your user and a list ofwaypoints
, which include any pickup or dropoff stops scheduled before your user’s final destination.
API fields specific to uberPOOL Some endpoints have UberPOOL specific fields. See below for how these endpoints differ for UberPOOL products:
GET /products
- the response body includes a shared field, which is set to true for uberPOOLPOST /requests/estimate
- the request should include aseat_count
parameter and the response will contain afare_id
fieldPOST /requests
- the request should includeseat_count
andfare_id
parameters for the uberPOOL rideGET /requests/{request_id}
andGET /requests/current
- the response body hasriders
andwaypoints
fields that contain additional details about the trip
Note: We built UberPOOL to work seamlessly with existing integrations. This means you can still request an UberPOOL using the standard ride request API flow without additional changes. However you will miss out on the additional UberPOOL features, like locking in an upfront fare. When a user requests a ride, two seats will be requested by default. Upon arrival, if there is only one seat actually required, the partner driver should update the uberPOOL trip to reflect this.
¶ Places
The Uber Rider app enables users to save their home and work as places exposed via the GET /places/{place_id}. When creating a Ride Request to a user place you should always pass the start_place_id
or end_place_id
and not use the raw address provided.
¶ Uber Rider App
Since a ride request that is made in a 3rd party application is done on behalf of an Uber rider, the status and all details of those ride requests will be available within the official Uber apps. This means that if a user chooses to open the Uber app after making a ride request with your application, they will have complete functionality as if they made the Request normally.
This also means that a user can perform the standard actions against a Request within an official Uber app, including canceling. Because of this, your application should always rely on the information provided by the GET /requests/{request_id} endpoint to provide the real time status and details of a Request.
¶ Notifications
All notifications that a user would receive from Uber, as if they requested using the official Uber app, will be sent for ride requests initiated by 3rd party applications. This includes, but is not limited to:
- Push or SMS notifications regarding a ride request status
- Email receipts
Because Uber is handling notifications to the user about Requests, we recommend only showing in-app notifications about ride request status so that a user isn’t bombarded with duplicate messaging. See Indicating Ride Status Throughout Application for some example in-app status indicators.
¶ Limitations
While the current endpoints give you the essentials for requesting trips, there are a few interactions that cannot be completed by the Uber API. These include:
- Rating drivers - Requests made and completed cannot be given a rating by a user via the Uber API. All ratings must be done by the Uber app
- Splitting the fare - There is no way to initiate a Split Fare request through the Uber API, but users can continue to utilize this feature within the Uber app during the lifecycle of a request
- Exclusive products not available - Uber is continuously creating experimental or promotional products that may not be available to request through the Uber API
- Optimizing pickup location The Uber app has a feature that optimizes a rider’s pickup location based on their current location - for example, the Uber app can detect that a rider is in an airport and provide a list of designated pickup locations to choose from. The Uber API, however, does not provide a way to get optimal pickup locations based on lat/long at this time.
¶ Guidelines and Assets
To help you create an application that has an intuitive and familiar user experience, we have provided design assets, design guidelines, and an overview of how an entire Ride Request can be implemented within an app.
¶ Client Libraries
There are official and community client libraries for popular languages to help you get started building moving experiences with Uber.