This is a guide to implementing a simple mobile web app that illustrates how to authenticate with the Moves API and invoke API endpoints.

The mobile web app will use Ruby, Sinatra and jQuery Mobile.

API flow


You will need Ruby with RubyGems and Bundler already set up.

Create your app

To obtain your API Client ID and Secret you must create your app. Keep your Client Secret confidential.

Make sure your Redirect URI matches the location the app will be deployed to. For this example you can enter http://[ip_address]:4567/auth/moves/callback where ip_address is your development machine’s IP address. Since this app will be a mobile website, you’ll need your phone to be on the same network as your development machine.


You can browse the finished project at

Here are the files that comprise the mobile web app sample:

├── Gemfile
├── app.rb
├── public
│   └── js
│       └── viz.js
└── views
    ├── index.erb
    ├── layout.erb
    ├── profile.erb
    ├── recent.erb
    └── signin.erb

Create the a file named Gemfile which describes the app’s dependencies:

source ''

gem 'sinatra'
gem 'oauth2'
gem 'json'

Then run the following command to make sure dependencies are installed:

bundle install

Next, create a file name containing the following:

require 'rubygems'
require 'bundler'


require File.expand_path(File.dirname(__FILE__) + '/app')

run Sinatra::Application

We are now ready to start on the app itself. Create a file named app.rb and paste in the following:

require 'sinatra'
require 'oauth2'
require 'json'
require 'date'

# access tokens will be stored in the session
enable :sessions
set    :session_secret, 'super secret'  # you should change this

def client
    :site => '',
    :authorize_url => 'moves://app/authorize',
    :token_url => '')

The client method sets up a OAuth::Client instance configured to communicate with the Moves OAuth endpoint. The environment variables MOVES_CLIENT_ID and MOVES_CLIENT_SECRET refer to the values from your [registered app].

Let’s set up some handlers to manage authenticating with Moves. Append the following to app.rb:

get "/" do
  if !session[:access_token].nil?
    erb :index
    @moves_authorize_uri = client.auth_code.authorize_url(:redirect_uri => redirect_uri, :scope => 'activity')
    erb :signin

get '/moves/logout' do
  session[:access_token]  = nil
  redirect '/'

get '/auth/moves/callback' do
  new_token = client.auth_code.get_token(params[:code], :redirect_uri => redirect_uri)
  session[:access_token]  = new_token.token
  redirect '/'

def redirect_uri
  uri = URI.parse(request.url)
  uri.path = '/auth/moves/callback'
  uri.query = nil

def access_token, session[:access_token], :refresh_token => session[:refresh_token])

The OAuth2 gem makes it easy to deal with authentication against the Moves API. The /auth/moves/callback handler retrieves the access token and stores it in the session. With the access token obtained, we can move on to invoke Moves API endpoints. Let’s set up a handler that queries the User Profile endpoint:

get '/moves/profile' do
  @json = access_token.get("/api/1.1/user/profile").parsed
  erb :profile, :layout => !request.xhr?

Another handler that queries the activity summaries for the past 7 days and extracts step counts from walks:

get '/moves/recent' do
  @json = access_token.get("/api/1.1/user/summary/daily?pastDays=7").parsed
  @steps = { |day|
    unless day["summary"].nil?
      (day["summary"].find { |a| a["group"] == "walking"})["steps"]
  erb :recent, :layout => !request.xhr?

Here’s how it looks like:


You can run the app with

rackup -p 4567