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 differentMost 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
- Installation is initiated from within Stok.ly. A user installs your app by navigating to your app's installation page and selecting "Install".
- 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.
- Stok.ly calls
/oauth/authorizeinternally. This happens entirely within Stok.ly. You will never call this endpoint yourself, and it isn't part of your app's integration surface. - Stok.ly redirects to your app's
redirectUriwith an authorizationcodein the query string. - Your app exchanges the code for tokens. Your app calls the
/oauth/tokenendpoint withgrant_type=authorization_code. - 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 tenantAt 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| Parameter | Description |
|---|---|
grant_type | Must be authorization_code. |
code | The authorization code from the redirect in step 4. |
redirect_uri | Must match the redirectUri registered in your app's manifest. |
client_id | Your app's client ID, issued when you created the app. |
client_secret | Your 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.xxxxxxxxxxxxxxxxRequests 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_SECRETThe 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.readcatalogue.items.create
Click here for a complete list of Access Scopes.
Updated 4 months ago
