Request an access token

Now it's up to you to do the OAuth dance ๐Ÿ•บ! The temporary authorization code you received must be exchanged for an OAuth access token.

To do so, you make an API request with your OAuth application credentials and the authorization code. If successful, our server generates an OAuth token and includes it in the response.

Select an API server

During development use:

  • US: ๐Ÿ‡บ๐Ÿ‡ธ
  • CA: ๐Ÿ‡จ๐Ÿ‡ฆ

And once your app is live (available after your development app is approved by our team), switch to:

  • US: ๐Ÿ‡บ๐Ÿ‡ธ ๐ŸŒ
  • CA: ๐Ÿ‡จ๐Ÿ‡ฆ ๐ŸŒ


Your HTTP request for an access token goes to our api/oauth/token endpoint on the correct sandbox or production server (remember to set US vs Canada).

For example, a test query for an app targeting our US servers uses this endpoint:


Example request

The same endpoint can both create a new access token or refresh an existing one. To let the server know your call is to trade an authorization code for a new access token, set the grant_type to authorization_code and set code to the value received when the user authorized your app.

This is also the first time you need to provide the client_secret you copied from the Fullscript API Dashboard during OAuth setup.

curl -X "POST" "" \
  -H 'Content-Type: application/json' \
  -d $'{
  "grant_type": "authorization_code",
  "client_id": "83x92x21xx29x643xx9954x8x2xx651xxx87x66521x08x9x2x408x26x801x394",
  "client_secret": "5305x72xxx6xx7xx4848xxxxx040x4xx4xx965xx566x662xxxxx6x7xxx5x730x",
  "code": "x8x9xx06x9138x41x0x4xx3xxx726x0x2749xxx798x1x7x3x46x902x4068664x",
  "redirect_uri": ""

Example response

Assuming you made the call within 10 minutes of receiving the authorization code, our servers respond with the user's OAuth access token. You can think of an access_token as a user's identity and password combined into a single field.

  "oauth": {
    "access_token": "96x5x67x09168xx64x4x8xx5xx541xxxxx38x10071xx1xxx24x66x0xxxxxxx74",
    "token_type": "Bearer",
    "expires_in": 7200,
    "refresh_token": "xxxx4x98xxxx7x03xxxxxx73x95x2514x0xx2x9xx15882xx7947496376x343x9",
    "scope": "catalog:read",
    "created_at": "2021-06-16T14:57:21.000Z",
    "resource_owner": {
      "id": "xx7x357x-9x36-xxxx-x553-7x3xx398xxx",
      "type": "Practitioner"

The OAuth access token has a 2 hour lifetime, which you can calculate from the provided created_at and expires_in values. But they also come with a non-expiring refresh_token so you can refresh an expired token when needed.

Store the access_token, refresh_token, the userโ€™s Fullscript id and user type (also returned with the token) alongside other private user profile info in your app.

Use the access token

Once you've successfully received and stored the OAuth token, use it to interact with the Fullscript API on behalf of that authorizing user.


Each user (practitioner or staff member) needs their own unique OAuth token so Fullscript knows which user is interacting with the clinic data.

To make a request on behalf of a user, just include their token in the header of your request, like so:

{ "Authorization" => "Bearer 96x5x67x09168xx64x4x8xx5xx541xxxxx38x10071xx1xxx24x66x0xxxxxxx74" }

And that's it! You've done the OAuth dance, and you can now make calls on behalf of your user.

Just one more thing. ๐Ÿ˜‰ Remember we said that the token expires in two hours. Avoid making the user go through the whole authorization process each time they use the API, and instead, use our refresh token process to simply refresh their expired OAuth token.


Applications created before August 26, 2021 use OAuth 2.0 with clinic level authorization instead of role-based access control. For those apps, thereโ€™s no requirement to create and store an OAuth token per user, but itโ€™s still good practice to do so. If your app allows users to connect their own Fullscript clinic accounts, you may already be doing this.