Skip to content

OAuth Flows

GoTab supports two OAuth 2.0 grant types. Which one you use depends on whether your integration acts on behalf of itself (server-to-server) or on behalf of a specific GoTab user.

FlowBest for
Client CredentialsServer-to-server integrations, background jobs, data imports
Authorization CodeMarketplace apps, multi-tenant SaaS, acting as a specific manager

For the quick path to a token (most integrations start here), see Authentication.


The client credentials grant is the simplest flow GoTab supports. Your server exchanges its api_access_id and api_access_secret directly for a Bearer token — no user interaction required.

Terminal window
curl --request POST \
--url https://gotab.io/api/oauth/token \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"api_access_id": "YOUR_API_ACCESS_ID",
"api_access_secret": "YOUR_API_ACCESS_SECRET"
}'

Response:

{
"tokenType": "Bearer",
"token": "eyJ...",
"initiated": 1659020513,
"expires": 1659106913,
"expiresIn": 86400,
"refreshToken": "..."
}

Before your integration can read or write location data, an authorized GoTab user must grant it access. Send users to the authorization portal:

https://gotab.io/manager/oauth?access_id=YOUR_ACCESS_ID&redirect_url=YOUR_REDIRECT_URL

Optional query parameters:

ParameterDescription
loc_limitMax locations a user can authorize at once. Omit for no limit. Must be > 0.
response_typeSet to token or omit entirely for client credentials.

After the user clicks Authorize, GoTab redirects to your redirect_url with:

?locationUuids=uuid1,uuid2,uuid3

Your integration now has access to those locations. List locations will return the full set of authorized locations.


Use this flow when your integration needs to act on behalf of a specific GoTab user — for example, showing a manager only the locations they personally have access to.

Step 1 — Direct the user to the authorization endpoint

Section titled “Step 1 — Direct the user to the authorization endpoint”

Place a button or link in your app that sends the user to:

https://gotab.io/manager/oauth?response_type=code&access_id=YOUR_ACCESS_ID&redirect_url=YOUR_REDIRECT_URL&state=RANDOM_UUID

Required parameters:

ParameterValue
response_typeMust be code
access_idYour api_access_id
redirect_urlMust exactly match a URL configured in the Integration Dashboard
stateOptional but recommended — a random value (e.g. UUID) to prevent CSRF

After the user authorizes, GoTab redirects to your redirect_url with:

?code=AUTH_CODE&state=YOUR_STATE_VALUE

Verify the state matches what you sent. The code is single-use and short-lived.

Terminal window
curl --request POST \
--url https://gotab.io/api/oauth/token \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"grant_type": "authorization_code",
"api_access_id": "YOUR_API_ACCESS_ID",
"api_access_secret": "YOUR_API_ACCESS_SECRET",
"code": "CODE_FROM_REDIRECT"
}'

Response:

{
"tokenType": "Bearer",
"token": "eyJ...",
"initiated": 1659020513,
"expires": 1659106913,
"expiresIn": 86400,
"refreshToken": "..."
}

Pass the token as Authorization: Bearer YOUR_TOKEN on every request. Requests are scoped to that user: List locations, for example, returns only the locations that user can access — not all locations the integration has access to.


Both flows land users on the same GoTab authorization portal. Here’s what the authorization screen looks like:

GoTab OAuth authorization portal

  • Store tokens server-side, never in the browser.
  • Keep api_access_id and api_access_secret in environment variables or a secrets manager.
  • Associate tokens with the location UUIDs or user IDs they were issued for.

Tokens expire after 24 hours (expiresIn: 86400). Schedule a refresh before expiry to avoid mid-session failures:

Terminal window
curl --request POST \
--url https://gotab.io/api/oauth/token \
--header 'Content-Type: application/json' \
--data '{
"grant_type": "refresh_token",
"api_access_id": "YOUR_API_ACCESS_ID",
"api_access_secret": "YOUR_API_ACCESS_SECRET",
"refresh_token": "YOUR_REFRESH_TOKEN"
}'

The refresh token itself does not expire, but it is invalidated if the access is revoked.

ErrorMeaningAction
401 UnauthorizedToken expired or revokedRefresh the token and retry
403 ForbiddenToken invalid (bad format, wrong credentials)Do not retry — re-authenticate

Handle 401 responses gracefully in your HTTP client by automatically refreshing and retrying once before surfacing an error to the user.