Authentication

Stok.ly uses OAuth 2.0 to let third-party apps request access to a tenant's account. If you've integrated OAuth before, there's one important difference from the flow you're used to: your app never redirects a user to Stok.ly's /oauth/authorize endpoint directly.

Installation always starts from inside Stok.ly, not from your app.

📘

Why this is different

Most OAuth integrations start with the third-party app sending the user to an authorize URL. With Stok.ly, the user is already inside Stok.ly when they choose to install your app, so Stok.ly initiates that step on your behalf. Your app only needs to handle the redirect back to you and the token exchange.

Overview of the flow

  1. Installation is initiated from within Stok.ly. A user installs your app by navigating to your app's installation page and selecting "Install".
  2. The user consents to installation. Stok.ly shows a consent screen listing the scopes your app has requested (defined in your App Manifest). The user approves or cancels.
  3. Stok.ly calls /oauth/authorize internally. This happens entirely within Stok.ly. You will never call this endpoint yourself, and it isn't part of your app's integration surface.
  4. Stok.ly redirects to your app's redirectUri with an authorization code in the query string.
  5. Your app exchanges the code for tokens. Your app calls the /oauth/token endpoint with grant_type=authorization_code.
  6. Stok.ly responds with an access token and refresh token, which your app stores and uses for subsequent API calls.
sequenceDiagram
    actor User
    participant Stokly as Stok.ly
    participant App as Your App

    User->>Stokly: Navigate to install URL
    Stokly->>User: Show consent screen (requested scopes)
    User->>Stokly: Approve installation
    Stokly->>Stokly: Call /oauth/authorize internally
    Stokly->>App: Redirect to redirectUri?code=...
    App->>Stokly: POST /oauth/token (grant_type=authorization_code, code)
    Stokly->>App: access_token + refresh_token
    App->>Stokly: API requests with Authorization: Bearer {access_token}

Step 4: the redirect to your app

Once the user approves installation, Stok.ly redirects their browser to the redirectUri registered in your app's manifest, with an authorization code attached:

https://myapp.example.com/callback?code=AUTH_CODE_HERE

This code is short-lived and single-use - exchange it for tokens immediately.

📘

Discovering the tenant

At the moment, you do not know the tenant in Stok.ly that has initiated the installation of your application. Complete the token exchange immediately as the response will contain the accountkey, identifying the Stok.ly tenant.

You can then authenticate the user in your own system if required, and create the link between the Stok.ly tenant and your own.

Step 5: exchange the code for tokens

Your app's backend, never the browser, makes this request

POST https://api.stok.ly/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&
code=AUTH_CODE_HERE&
redirect_uri=https://myapp.example.com/callback&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET
ParameterDescription
grant_typeMust be authorization_code.
codeThe authorization code from the redirect in step 4.
redirect_uriMust match the redirectUri registered in your app's manifest.
client_idYour app's client ID, issued when you created the app.
client_secretYour app's client secret, issued when you created the app.

Stok.ly responds with

{
  "access_token": "stk.at.xxxxxxxxxxxxxxxx",
  "refresh_token": "stk.rt.xxxxxxxxxxxxxxxx",
  "token_type": "Bearer",
  "expires_in": 3600,
	"accountkey": "xxxxx"
}

Both tokens are opaque in that they're not JWTs, and you shouldn't attempt to decode or inspect them. Treat them as bearer secrets.

Using the access token

Include the access token as a bearer token on every API request:

GET https://api.stok.ly/v0/items
Authorization: Bearer stk.at.xxxxxxxxxxxxxxxx

Requests without a valid token, or with a token whose scopes don't cover the endpoint being called, are rejected.

Refreshing an access token

Access tokens are short-lived. When one expires, use the refresh token to get a new one without involving the user again:

POST https://api.stok.ly/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&
refresh_token=stk.rt.xxxxxxxxxxxxxxxx&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET

The response has the same shape as the initial token exchange.

Not that a new refresh token will be returned and the old refresh token will be invalidated. Ensure you store the new token for the next refresh request.

Token revocation

If a user uninstalls your app from Stok.ly, its access and refresh tokens are invalidated automatically - any subsequent API calls using them will fail.

Scopes

Every access token is limited to the scopes your app requested and the user approved during installation. Scopes are namespaced by resource and action, for example:

  • catalogue.items.read
  • catalogue.items.create

Click here for a complete list of Access Scopes.



Did this page help you?