Uber API Tutorial

BUILD A PARTY INVITATION

In this tutorial you'll build a digital invitation for your next party and, at the same time, learn how to use the Uber API. By the end of this tutorial your invitation will show users the nearest Uber ride, and link to your account so you can earn rewards through the Uber API Affiliate Program

If you're interested in learning more about web development, you should take a look at our Frontend Web Development Course.

Get Started
Uber API Tutorial

In this tutorial you'll build a digital invitation for your next party and, at the same time, learn how to use the Uber API. By the end of this tutorial your invitation will show users the nearest Uber ride, and link to your account so you can earn rewards through the Uber API Affiliate Program

Here's a quick preview:

Topics covered:

  • How to access the Uber API with token authentication

  • Using the Uber API's Time Estimates

  • Deep-linking to Uber's mobile web app

  • Styling your app with the Uber API Design Guidelines

Prerequisites

This tutorial assumes the following knowledge:

Note: This guide is open to the public. You can view the source code on GitHub where you'll find a sample app to follow along.

Ready? Let's dive in!

First things first: Let's create an invitation template using HTML and CSS.

At a minimum, your invite should include some info about when and where your party is taking place, similar to the image you saw above.

If you don't want to start from scratch, you can customize our invitation template. To do this:

  • Go to the repo

  • Click "Download Zip"

  • Open the zipped file

  • Go to app/01-static-invitation

  • Open index.html in your browser

  • You can change the invitation design by modifying app/01-static-invitation/css/style.css as you see fit

Getting an Address' Latitude and Longitude

If you want to create your own map, like we did in our example, you'll first need to get your party's address latitude and longitude. Here's how to do this:

  1. On your computer, visit Google Maps

  2. Search for an address

  3. Right-click a location on the map

  4. Select "What's here?"

  5. Coordinates will appear either in or below the search box

Next, to generate the map image, modify this URL by changing the latitude and longitude from the step above. In this example, our latitude is 40.725255 and our longitude is -73.996842

http://maps.googleapis.com/maps/api/staticmap?zoom=17&format=png&sensor=false&size=280x280&maptype=roadmap&style=element:geometry.fill|color:0xf4f4f4&markers=color:red|40.725255,-73.996842&scale=2

Here's the result:

Pro-tip

For design: Use Google Fonts to find amazing (and free) fonts, Unsplash for images, and play around with Google's Styled Maps Wizard.

If you're starting from scratch: Make sure your invitation is mobile optimized and responsive! If you're not sure how to do this, you can join Thinkful's Frontend Web Development Course to learn this and much more with one-on-one mentorship.

Code check:

01-static-invitation

Let's Take an Uber!

Uber provides ready-made images we can use to make our Uber button. Click here to download the assets. Uber also provides helpful design guidelines offering rules of thumb for button placement and sizing.

Creating the Button

To start, we need to create a button container. This is where we'll have the actual button as well as live time estimates for the nearest Uber ride.

If you're using our template, under the map image, create a new div with a class of button.

<div class="button"></div>

Notice we used a div rather than just an img tag. This is because we're planning to overlay the button with live time estimates to the nearest Uber ride.

Now let's actually load the Uber button image inside the div.

  • Download and open the Uber assets

  • Go to Assets/Uber API Buttons/Grey/PNGs/2x and choose the image you prefer

    • The main difference is each image's border-radius

  • Copy this image into your project's /img folder

Note: Depending on your invitation's style, you can choose either the black or grey buttons provided by Uber.

Styling the Button

It's time to make our button look good. To do this, we'll use the image you chose earlier and make it the div's background-image. Here's how we do this:

.button {
    background-image: url('../img/UBER_API_Button_2x_Grey_hard edge.png');
    background-size: cover;
    width: 280px;
    height: 44px;
    margin: 0 auto;
}

Note: Because we're using the background-image property, we have to specify the width and height of the .button class; otherwise, the div won't appear on our invitation.

Adding Time Estimates

Next, we'll add a placeholder for the time estimate. Later in the tutorial, we'll update the placeholder text with real time estimates using the Uber API.

Create a paragraph inside the <div class="button"> and assign it an id=time. We'll use the id to update the time using Javascript in a bit. Your button's HTML should now look like this:

<div class="button">
    <p id="time">ESTIMATING TIME</p>
</div>

Note we still have to position the p in the div using CSS. Here's how we achieve this:

#time {
    text-align: right;
    margin-top: 2%;
    padding-top: 12px;
    padding-right: 14px;
}

Here's how your invitation should look by now — notice the Uber button:

Code check:

02-static-uber-button

Now that our static invitation is complete, it's time to sign up for the Uber API at developer.uber.com.

Registering Your App

You're now ready to create your first Uber app. Choose Register App and enter your app's details.

You'll need to provide:

  • The name for your app (e.g. "Thinkful Party Invitation")

    • This name needs to be unique (you could use "Thinkful Party Invitation" + a random number)

  • A description ("An Uber-powered party invitation to a party at Thinkful HQ in NYC!")

As an extra security measure, Uber whitelists the domains that are allowed to access their servers. To develop on your local computer, you'll need to set the "Origin URI" in the "Authentication" section of the page to http://localhost:8000 (assuming your server is running on port 8000).

Pro Tip: Your "Origin URI" should not contain a trailing slash. That is, http://localhost:8000 works, while http://localhost:8000/ might not.

Before clicking save, you'll also need to indicate whether you'd like to enroll in the Uber API Affiliate Program and whether you agree to the Uber API Terms of Use.

Note: Under List of Scope, do not select either option. Uber users' personal data isn't needed for this tutorial. If you do need Uber users' personal data for a later project, you'll need to provide a redirect URL and privacy policy URL before proceeding.

After saving your app, you'll see a Client ID, Server Token, and Secret. We'll come back to these and how to use them as we dig into the API.

Now that you've registered your app with Uber, let's dig into the API's endpoints.

Note: "Endpoint" is a generic term for specific web services: in this case, JSON-formatted data about Uber that can be accessed via regular URLs.

The Uber API provides different endpoints that can be used to pull information about Uber users, products, price and time estimates. For our app, we plan to show our users how far away they are from pick-up by an Uber vehicle, which is included in both the Time Estimates and the Price Estimates endpoints.

Later on, we'd like to add the estimated Uber ride price. Because of this, we'll use the Price Estimates endpoint.

As mentioned earlier, endpoints are nothing more than regular URLs that return some JSON data. In order to use endpoints, you sometime need to provide parameters. Parameters are used to pass information to the endpoint so that you can get the answer you want. In the "Google Maps" world, you can imagine an endpoint requiring an address and, in response, returning information about said address (such as latitude and longitude).

The Uber Price Estimates endpoint requires a few parameters:

  • Authorization (an OAuth 2.0 bearer token or server_token)

  • start_latitude

  • start_longitude

  • end_latitude

  • end_longitude

Let's start by getting our user's GPS coordinates (latitude and longitude) so that we can provide them to the Uber API.

We can request the user's GPS coordinates by using the Geolocation Web API that's built into every modern browser.

You need to use JavaScript to get the Geolocation Web API working. Before writing any code, we need to create a JavaScript file (which we're calling uber.js) and link it to our index.html file.

We'll be using jQuery to communicate with the Uber API, so we'll add a script element for jQuery as well.

Just before the </body> tag, insert the following code:

<script src="js/jquery-2.1.1.min.js"></script>
<script src="js/uber.js"></script>

Note: Order matters: make sure you load jQuery before loading your custom script. Also, make sure you've saved jQuery in your /js folder.

Code check:

03-javascript-ready

Locating the User

The Uber API documentation recommends requesting updated time estimates every minute; since we want to show accurate time estimates we'll be using the Geolocation API's watchPosition function. This will enable us to submit the latest GPS coordinates to the Uber API each time we make a request.

In uber.js, create variables to store the user's location data, and then update those variables with the latest values after calling the watchPosition function. Your code should look like this:

// create placeholder variables
var userLatitude
  , userLongitude;

navigator.geolocation.watchPosition(function(position) {
    // Update latitude and longitude
    userLatitude = position.coords.latitude;
    userLongitude = position.coords.longitude;
});

Check Your Code: To make sure you're receiving reasonable location data, you can add a console.log(position) statement in the function(position) callback, and check your JavaScript Console while viewing the page in your browser. Your code should look like this (we just added the console.log(position):

// create placeholder variables
var userLatitude
  , userLongitude;

navigator.geolocation.watchPosition(function(position) {
    console.log(position);

    // Update latitude and longitude
    userLatitude = position.coords.latitude;
    userLongitude = position.coords.longitude;
});

Where the Party At

At this point, you can also add location data for your end destination. Just add partyLatitude and partyLongitude, like so:

var userLatitude
  , userLongitude
  , partyLatitude = 40.7283405
  , partyLongitude = -73.994567;

It might be a good time to load some vintage 2001 tunes, too, if you're so inclined.

We now have 4 of the 5 query parameters we need in order to use the Uber Price Estimates API:

  • userLatitude and userLongitude

    • These will become start_latitude and start_longitude when calling the Uber endpoint

  • partyLatitude and partyLongitude

    • These will become end_latitude and end_longitude when calling the Uber endpoint

The last parameter missing is the app authentication. Let's dive into this next!

Authenticating your App

The Uber Price Estimates API specifies that you can use an OAuth 2.0 bearer token or a server_token to access time estimates. In our case, we'll be using the server_token generated when we registered our app to authenticate.

Note: Using an OAuth 2.0 bearer token would require our users to log in with their Uber accounts, and would grant us access to the User Activity and User Profile endpoints. We won't focus on this today.

At the top of the uber.js file, add two variables to store the Uber client_id and the server_token:

// Uber API Constants
var uberClientId = "YOUR_CLIENT_ID"
  , uberServerToken = "YOUR_SERVER_TOKEN";

Warning: Your uberClientId and uberServerToken will be visible to anyone who views the source code for your web app once it's published on the internet. To keep them 100% private, you would need to do this on the server (we won't cover server-side requests today).

Note: We'll be using the uberClientId next, in the deep linking section.

Getting Data from the API

Since the userLatitude and the userLongitude will be changing as the user moves (e.g. walking down the street) we'll have to request Uber data repeatedly. In order to simplify our code, we're going to create a separate function to call the Uber API: getEstimatesForUserLocation(latitude,longitude).

We'll use jQuery's ajax method to request time estimates from the Uber API. Your Ajax request should look like this:

function getEstimatesForUserLocation(latitude,longitude) {
  $.ajax({
    url: "https://api.uber.com/v1/estimates/price",
    headers: {
        Authorization: "Token " + uberServerToken
    },
    data: {
        start_latitude: latitude,
        start_longitude: longitude,
        end_latitude: partyLatitude,
        end_longitude: partyLongitude
    },
    success: function(result) {
        console.log(result);
    }
  });
}

Within the watchPosition callback, call getEstimatesForUserLocation(userLatitude, userLongitude).

Here's our uber.js code so far:

// Uber API Constants
var uberClientId = "YOUR_CLIENT_ID"
  , uberServerToken = "YOUR_SERVER_TOKEN";

// Create variables to store latitude and longitude
var userLatitude
  , userLongitude
  , partyLatitude = 40.7283405
  , partyLongitude = -73.994567;

navigator.geolocation.watchPosition(function(position) {
    // Update latitude and longitude
    userLatitude = position.coords.latitude;
    userLongitude = position.coords.longitude;

  // Query Uber API if needed
    getEstimatesForUserLocation(userLatitude, userLongitude);
});

function getEstimatesForUserLocation(latitude,longitude) {
  $.ajax({
    url: "https://api.uber.com/v1/estimates/price",
    headers: {
        Authorization: "Token "  uberServerToken
    },
    data: {
      start_latitude: latitude,
      start_longitude: longitude,
      end_latitude: partyLatitude,
      end_longitude: partyLongitude
    },
    success: function(result) {
      console.log(result);
    }
  });
}

In this code check, if you open your console in your browser, you should see something like this.

If you see a 401 error (No 'Access-Control-Allow-Origin' header is present on the requested resource.) in the console, make sure you've added an Origin URI to your app on your Uber Manage Apps dashboard. In our example, we're using port 8000 for the URL http://localhost:8000/app/04-fetching-time-estimates/). This port needs to be the same as the one you have in your Uber app settings (where Origin URI should equal http://localhost:8000). If you change this, you might need to generate a new server_token and then update uber.js with the new value.

Note: To run this code check you'll need to make sure you're using a server. On a Mac, you can do this by running python -m SimpleHTTPServer. If you're on windows, try doing this by installing Mongoose.

Reading the JSON

In your browser console, if you click on the Object and then on prices you should see something like this:

{
  "prices": [
    {
      "localized_display_name": "uberX",
      "duration": 352,
      "low_estimate": "8",
      "display_name": "uberX",
      "product_id": "b8e5c464-5de2-4539-a35a-986d6e58f186",
      "distance": 0.73,
      "surge_multiplier": 1,
      "estimate": "$8",
      "high_estimate": "8",
      "currency_code": "USD"
    },
    {
      "localized_display_name": "uberXL",
      "duration": 352,
      "low_estimate": "12",
      "display_name": "uberXL",
      "product_id": "1e0ce2df-4a1e-4333-86dd-dc0c67aaabe1",
      "distance": 0.73,
      "surge_multiplier": 1,
      "estimate": "$12",
      "high_estimate": "12",
      "currency_code": "USD"
    }
  ],
  etc...
}

Examining the response from the Uber API, we can see that there's a prices key which we can use to extract an array of Uber products.

Updating your App with Uber Data

Our app could show the different Uber products and their time estimates, but our app only needs one time estimate to update p id=time.

We'll need to sort the data array from shortest to longest, extract the shortest time estimate, and use jQuery to update p id=time with the number of minutes to pickup. Here's how you can do this:

var data = result["prices"];
if (typeof data != typeof undefined) {
  // Sort Uber products by time to the user's location
  data.sort(function(t0, t1) {
    return t0.duration - t1.duration;
  });

  // Update the Uber button with the shortest time
  var shortest = data[0];
  if (typeof shortest != typeof undefined) {
    console.log("Updating time estimate...");
    $("#time").html("IN " + Math.ceil(shortest.duration / 60.0) + " MIN");
  }
}

Code check:

05-parsing-uber-api

Here's what your screen should look like:

Uber's API recommends refreshing estimates every 60 seconds. To do so, we'll use JavaScript's built-in timer functions.

Start by adding var timer; outside of the watchPosition callback

Storing the timer outside of the callback allows us to ensure that a new timer isn't created each time watchPosition updates latitude and longitude.

Note: There are different ways to handle the timer but we're using this implementation for code simplicity.

Next, in the watchPosition callback, check for the existence of the timer object. If one hasn't been created yet, generate the timer using setInterval. Make sure to call getEstimatesForUserLocation once separately, since our timer won't fire for at least 60 seconds.

Here's what our code looks like now:

// Create variable to store timer
var timer;

navigator.geolocation.watchPosition(function(position) {
    // Update latitude and longitude
    userLatitude = position.coords.latitude;
    userLongitude = position.coords.longitude;

  // Create timer if needed
  // Once initialized, it will fire every 60 seconds as recommended by the Uber API
  // We only create the timer after we've gotten the user's location for the first time
  if (typeof timer === typeof undefined) {
    timer = setInterval(function() {
        getEstimatesForUserLocation(userLatitude, userLongitude);
    }, 60000);

    // Query Uber API if needed
    getEstimatesForUserLocation(userLatitude, userLongitude);
  }
});

Code check:

06-refresh-estimates

At this point, your app should be automatically updating the Uber button every minute with the time-to-pickup based on the user's location.

But so far our button doesn't do anything.

First, wrap the button in an <a> tag so that your HTML looks something like this:

<a href="#">
    <div class="button">
        <p id="time">ESTIMATING TIME</p>
    </div>
</a>

Next, we'll use jQuery to intercept the link:

$("a").click(function(event){
    // Intercepted Click Event
});

Deep Linking

Uber offers several deep linking options if you're building a native app. Since our app is a web app, we'll use the mobile web deep linking infrastructure.

The minimum parameter we must include to redirect users to the Uber mobile web app (m.uber.com) is client_id.

You can specify over 20 additional parameters to customize your user's experience; in our case we'll specify as much information about the user and about the party as we can:

$("a").click(function(event){
// Redirect to Uber API via deep-linking to the mobile web-app
var uberURL = "https://m.uber.com/sign-up?";

// Add parameters
uberURL += "client_id=" + uberClientId;
if (typeof userLatitude != typeof undefined) uberURL += "&" + "pickup_latitude=" + userLatitude;
if (typeof userLongitude != typeof undefined) uberURL += "&" + "pickup_longitude=" + userLongitude;
uberURL += "&" + "dropoff_latitude=" + partyLatitude;
uberURL += "&" + "dropoff_longitude=" + partyLongitude;
uberURL += "&" + "dropoff_nickname=" + "Thinkful";

// Redirect to Uber
window.location.href = uberURL;
});

After constructing the URL, we're finally ready to redirect our users to Uber: window.location.href = uberURL;

You won't be able to sign-in on m.uber.com on your desktop -- to fully test the deep-linking (and call an Uber in the process) you'll need to fire up your iOS Simulator or upload your project to the web and access it from a mobile device:

Code check:

final-section

Note: To run this code check you'll need to:

  • Make sure you've downloaded the code. To do this:

    • Go to the repo

    • Click "Download Zip"

    • Open the zipped file

    • Run a simple local server

      • On a Mac, you can do this by running python -m SimpleHTTPServer

      • If you're on windows, try doing this by installing Mongoose

  • In your browser, go to http://localhost:8000/app/final-section/

Next Steps

You're done! Your party invitation should now show time estimates to the nearest Uber, deep-link into the Uber mobile web app, and update automatically every minute.

But the fun's only beginning. If you want to make your party invitation even better:

  • Add the price estimate that we're already getting from the endpoint

  • If you show prices, don't forget to follow Uber's design guidelines and show the surge indicator if needed

  • Improve user experience for errors that could occur during our ajax call, or when finding the user's location

Finally: Don't forget to upload your party invitation to a public webserver and share it with the world. And make sure you invite us to the party!

If you're interested in learning more about web development, you should take a look at our Frontend Web Development Course.

Created by