Developer Center
Getting Started
Using Jobber’s API
Building Your App
Publishing Your App
App Template Project
Custom Integrations

App Authorization (OAuth 2.0)

Jobber uses OAuth 2.0 to authorize an app's access to a Jobber user's account.

OAuth 2.0 is an authorization framework. It provides authorization flows for web applications, desktop applications, and mobile devices. Some apps that use OAuth are Facebook, GitHub, and Jobber.

OAuth 2.0 gives applications limited access to user accounts on an HTTP service. It delegates user authentication to the service that hosts the user's account. It then authorizes third-party apps to access the user's account.

OAuth 2.0 Roles

OAuth 2.0 defines four roles:

  • Resource Owner
  • Client
  • Resource Server
  • Authorization Server

The Resource Owner is a User

The resource owner is the Jobber admin user who authorizes your application to access their Jobber Account. The application is granted an access level corresponding to the scopes specified when the app was created.

The Client is an Application

The client is the app that you want to give access to the user’s Jobber account. Two things must happen before the client gains access:

  • The API must authenticate the user
  • The user must authorize the client

The Resource & Authorization Server is the API

The resource server hosts the protected user accounts. The authorization server verifies the identity of the user and gives access tokens to the client. Jobber’s API fulfills both the resource and authorization server roles. We will refer to both of these roles combined, as the Service or API role.

OAuth 2.0 Protocol Flow

  1. The client requests authorization from the user.
  2. The client receives an authorization grant from the authorization server.
  3. The client requests an access token from the authorization server. It presents authentication of its own identity. The client also presents the authorization grant.
  4. The authorization server issues an access token and refresh token to the client.
  5. The client requests resource from the resource server. It presents access token for authentication.
  6. The resource server serves the resource to the client.
  7. If the access token expires, the client requests a new one. (See below refresh token flow)

Client ID and Client Secret

After you add your app, Jobber will give you a client identifier and a client secret. The client ID is a publicly exposed string. Jobber uses it to identify the application. It's also used to build authorization URLs that are presented to users.

Jobber uses the client secret to authenticate the identity of the application. You must keep it private between the application and the API.

Authorization Grant

In the Protocol Flow above, the first four steps cover obtaining an authorization grant and access token. Jobber implements the authorization code grant type.

Authorization Code Grant Type

The authorization code grant type is the most commonly used because it is optimized for server-side applications, where source code is not publicly exposed, and Client Secret confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the user-agent (i.e. the user's web browser) and receiving API authorization codes that are routed through the user-agent.

Authorization Code Flow

There are two ways for the Authorization Code Flow to begin. Either the Jobber admin user clicks on the Connect button from the app listing in Jobber's App Marketplace, or the admin user accesses an authorization link of the form:<CLIENT_ID>&redirect_uri=<CALLBACK_URL>&state=<STATE>

Here is an explanation of the authorization link components:

  • is the API authorization endpoint
  • <CLIENT_ID> is where the app inserts its Client ID value that can be looked up from the Developer Center
    • This is how the API identifies the app
  • <CALLBACK_URL> is where Jobber will redirect the user immediately after the authorization code is granted
    • This is set by the developer in the Developer Center and must be URL encoded
  • <STATE> is a random string that the client has the option of generating so that it's possible to confirm that the same <STATE> string is returned with the granted authorization code (see Step 3)
    • When the authorization flow is started from Jobber's App Marketplace, there is no <STATE> string provided

Step 2: User Authorizes Application

When the user clicks the link above or clicks on the Connect button from Jobber's App Marketplace, they will be prompted to authorize the scopes of the app (as configured in the Developer Center) and they must click on the Allow Access button to proceed. If the user was not already logged in to their Jobber account in the current browser, then they will first be prompted to log in before seeing the screen below:

OAuth screen

Step 3: Application Receives Authorization Code

If the user chooses to approve the access request, Jobber redirects the user-agent to your application's redirect URI, along with an authorization code. The redirect would look something like this (assuming the application is ""):

At this point the client should check that the state parameter matches the value set in step 1 (if applicable).

If the user chooses to deny the access request, Jobber redirects the user-agent to your application's redirect URI with no additional parameters:

Step 4: Application Requests Access Token

The application requests an access token from the API, by passing the authorization code along with authentication details, including the client secret, to the API token endpoint. Your application must use HTTPS, rather than HTTP, for this request. Here is an example POST request to Jobber's token endpoint:

POST /api/oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded


The result will look something like

  "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ...MH0.FAz4g5Q-UugrsjU4OuSB0PwHXDqsxcc-mRa4BW2lNJw",
  "refresh_token": "5dd9bed1bd99b837cd3acaf2f59fb8fa"

This example does not contain a complete access token. The actual access token contains three components:

encodeBase64(header) + '.' +
encodeBase64(payload) + '.' +

where the payload may be of interest as it contains an exp value that encodes the expiry time of the token. These are standard JWT tokens with signatures that are only verifiable by Jobber.

Step 5: Application Receives Access Token

If the authorization is valid, the API will return a JSON response containing the "access_token" and a "refresh_token" to your app.

Your app is now authorized. It may use the access token to make GraphQL queries or mutations against Jobber's API. It is highly recommended to use the account query to collect the account name and id for easier tracking of which Jobber account the access token can be used for. This will also be important for tracking app disconnects in the future.

The access token can continue to be used until it expires (default expiration time is 60 minutes) or until the app is disconnected. The refresh token may be used at any time to request a new access token.

Refresh Token Flow

After an access token expires, using it to make a request from the API will result in a 401 "Invalid Token Error". At this point the refresh token can be used to request a fresh access token from the authorization server. Note: You do not need to wait for the access token to expire to use the refresh token. It may be used at any time.

There are a few cases where the refresh token may expire:

  • App is disconnected from the account via either:
    • Admin user disconnecting the app using the Disconnect button on the App Marketplace listing
    • appDisconnect mutation getting used
    • Automatic disconnection as a result of account churn, plan downgrade, or admin user deactivation
  • Client Secret is rolled (note this cannot be done manually at this time)
  • The app connection is re-authorized after a scope change
    • After this process the new Authorization Code can be used to request a new access token and refresh token

If both the access and refresh token are expired for whatever reason, an admin user will need to start the OAuth flow again. The app will prompt them to do so by sending them to Jobber and redirecting back to the app's Callback URL.

Here is an example POST request to obtain a new access token via the refresh token:

POST /api/oauth/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded


In return you will receive the access token and a refresh token. It is important to note that when Refresh Token Rotation is OFF, then the above POST request will return the same refresh token as before. In this configuration, the refresh token is meant to be long-lived.

If Refresh Token Rotation is ON, then the returned refresh token will be a new one every time. This new refresh token should always be saved, as it is the one to be used on the next request for a fresh access token. The same refresh token should never be sent to the API more than once in this Refresh Token Rotation configuration.

Example Access Token Usage

Once the application has an access token, it may use the token to access the user's account via the API until the token expires or is revoked.Here is an example of an API request using curl. Note that it includes the access token:

curl -X POST -H "Authorization: Bearer ACCESS_TOKEN" ""

Assuming the access token is valid, the API will process the request according to its API specifications. If the access token is invalid, the API will return a 401 "invalid_request" error.

Handling App Disconnects

Once a Jobber account has been connected to an app (and the Access and Refresh Tokens have been granted) there are typically two mechanisms for the account to disconnect the app:

  1. Admin user on the account clicks the DISCONNECT button from the app listing page in Jobber's App Marketplace
    • This will immediately invalidate the Access and Refresh Tokens for that account and will also trigger the APP_DISCONNECT webhook
    • It is highly recommended that all apps subscribe to this webhook
  2. User disconnects the app/integration from another system outside of Jobber
    • For this case we highly recommend using the appDisconnect GraphQL mutation to notify Jobber that the account has disconnected
    • The Access and Refresh Tokens will also be invalidated using this process

See below for an example of using the appDisconnect mutation:

  mutation Disconnect {
    appDisconnect {
    app {
    userErrors {