Building Integrations with the ScopeStack API
1. How ScopeStack Authentication Works
Before diving into implementation, it helps to understand how the pieces fit together.
Two Types of Client Credentials
ScopeStack uses OAuth 2.0 Client IDs and Client Secrets. There are two kinds, and which one you use depends on your authentication flow.
Account-level credentials are issued per ScopeStack account. These identify your application and are used with the Authorization Code and Password Grant flows. They do not carry user identity on their own. You provide a username and password (or a browser login) separately to identify which user is making the request.
Service Account credentials are issued per service account user. These identify both the application and the user in a single pair. They are used with the Client Credentials flow and do not require a separate username or password. This is the recommended approach for new server-to-server integrations. See Service Account Credentials for setup.
Users Determine Access
Every API request ultimately runs as a specific ScopeStack user. The user determines:
- Which account the request operates in (if a user belongs to multiple accounts)
- What permissions are available (based on the user’s role)
With account-level credentials, the user is determined by the login or password you provide. With service account credentials, the user is the service account that owns the credentials.
Two Domains, Two Purposes
| Domain | Use |
|---|---|
app.scopestack.io | Authentication (getting tokens) |
api.scopestack.io | API calls (using tokens) |
2. Choosing an Authentication Flow
ScopeStack supports three OAuth 2.0 flows. Your choice depends on whether a human will be present during authentication.
| Scenario | Flow | Why |
|---|---|---|
| Web app where users log in | Authorization Code | User can complete browser login |
| Interactive Postman testing | Authorization Code | You’re at the keyboard |
| Workato / Zapier | Client Credentials | No browser, no passwords needed |
| Backend service / cron job | Client Credentials | Single request, runs unattended |
| MCP server connections | Client Credentials | Headless server-to-server access |
| Custom scripts | Client Credentials | Automated execution |
| Existing integrations using password grant | Password Grant | Still supported for existing setups |
3. Authorization Code Flow
Use this flow when a user can complete a browser-based login.
How It Works
- Your application redirects the user to ScopeStack’s authorization endpoint
- The user logs into ScopeStack (including SSO/MFA if configured)
- ScopeStack redirects back to your callback URL with an authorization code
- Your application exchanges the code for an access token
Endpoints
- Authorization: https://app.scopestack.io/oauth/authorize
- Token Exchange: https://app.scopestack.io/oauth/token
4. Client Credentials Flow
Use this flow for server-to-server integrations, automation platforms, and MCP connections. A single request exchanges your service account’s client ID and secret for an access token.
Setup
Create a service account and generate client credentials. See Service Account Credentials for the full walkthrough.
Token Request
POST https://app.scopestack.io/oauth/token
Content-Type: application/x-www-form-urlencoded
| Parameter | Value |
|---|---|
| grant_type | client_credentials |
| client_id | Your service account’s Client ID |
| client_secret | Your service account’s Client Secret |
Response
{
"access_token": "eyJ...",
"expires_in": 86400,
"token_type": "Bearer"
}
No refresh token is returned. When the token expires, make the same request again to get a new one.
5. Resource Owner Password Grant
This flow is supported for existing integrations. For new integrations, use Client Credentials (above) instead.
Use this flow for automation—no browser, no redirect, just a direct token exchange.
⚠️ Postman Users: If you’re testing this flow in Postman, do NOT use the OAuth 2.0 helper with “Password Credentials” selected. That sends a redirect_uri parameter that causes errors. Instead, make a direct POST request to the token endpoint. See the Quick Start guide for step-by-step instructions.
Token Request
POST https://app.scopestack.io/oauth/token
Content-Type: application/x-www-form-urlencoded
| Parameter | Value |
|---|---|
| grant_type | password |
| client_id | Your application’s Client ID |
| client_secret | Your application’s Client Secret |
| username | Service account email |
| password | Service account password |
Response
{
"access_token": "eyJ...",
"refresh_token": "abc123...",
"expires_in": 86400,
"token_type": "Bearer"
}
6. Setting Up Service Accounts
For production integrations, always use a dedicated service account rather than a personal user account. This ensures your integration keeps working when people leave the company.
Creating a Service Account
- In ScopeStack, go to Settings → Users
- Click Add User
- Set the User Type to “Service”
- Enter an email address
- Assign a role with appropriate permissions
- Save the user
Setting Up Client Credentials
Once the service account exists, create client credentials for it. See Service Account Credentials for the full walkthrough.
Best Practices
- Create a dedicated “Integration” or “Service Account” role with only the permissions your integration needs
- Use descriptive email addresses like workato@yourcompany.com or salesforce-sync@yourcompany.com
- Document which service account is used for which integration
- Use separate client credentials for separate integrations
- Rotate secrets periodically per your security policy
7. Token Management
Token Expiration
Access tokens expire after the time specified in the expires_in response field (in seconds). Plan to refresh tokens before they expire.
Refreshing Tokens (Password Grant Only)
If you are using the Password Grant flow, use the refresh token to get a new access token without re-authenticating. Client Credentials tokens do not use refresh tokens. When they expire, request a new token with the same client ID and secret.
POST https://app.scopestack.io/oauth/token
Content-Type: application/x-www-form-urlencoded
| Parameter | Value |
|---|---|
| grant_type | refresh_token |
| client_id | Your Client ID |
| client_secret | Your Client Secret |
| refresh_token | The refresh token from your original token response |
Handling Token Errors
Your integration should handle 401 and 403 errors by attempting a token refresh. If the refresh fails, fall back to full re-authentication.
8. Making API Calls
Required Headers
Every API call must include:
Authorization: Bearer {access_token}
Accept: application/vnd.api+json
The Accept header is required—calls without it may fail.
Getting Account Context
After authenticating, call the /v1/me endpoint to get your account context:
GET https://api.scopestack.io/v1/me
This returns:
- account-slug: Used in API URLs (e.g., /{account-slug}/v1/clients)
- account-id: Used in relationship objects when creating/linking records
Store these values—you’ll need them for most API operations.
Pagination
List endpoints are paginated. Control the page with page[number] and page[size]:
GET https://api.scopestack.io/v2/projects?page[number]=1&page[size]=250
- The default page size is 250. The maximum accepted is 1000 — a larger value returns a
400telling you the size exceeds the maximum. - Every list response includes a
metaobject withrecord-count(total matching records) andpage-count(number of pages). Readpage-countonce and loop, rather than paging until you get an empty response. - Responses also include
linkswithfirst,next, andlastURLs where applicable.
Filtering
Filters use the JSON:API filter[...] convention. Which filters a resource accepts varies by endpoint; the Swagger UI lists them per endpoint.
Archived records are excluded by default. Many collections — including projects — support filter[active], which controls whether archived records are returned. Collections with no concept of archiving do not accept it:
| Value | Returns |
|---|---|
| omitted | Active records only — this is the default |
filter[active]=true | Active records only (identical to omitting it) |
filter[active]=false | Archived records only |
filter[active]=true,false | Both active and archived |
High-volume paging can trip rate limits on document and export endpoints — see 429 Too Many Requests.
This catches people out in two directions. If you are missing records you expected, they may be archived and silently excluded. If you are trying to reconcile a total against the ScopeStack UI, make sure both sides agree on whether archived records count.
9. Using the ScopeStack Workato Connector
ScopeStack provides a pre-built Workato connector that handles authentication, token refresh, and common operations automatically.
The connector is being updated to support the Client Credentials flow. Contact ScopeStack for access to the connector and setup information.
10. API Reference
Full API documentation is available at https://api.scopestack.io (Swagger UI).
The API follows JSON:API conventions. Key patterns:
- GET /{account-slug}/v1/{resource} — List resources
- GET /{account-slug}/v1/{resource}/{id} — Get single resource
- POST /{account-slug}/v1/{resource} — Create resource
- PATCH /{account-slug}/v1/{resource}/{id} — Update resource
- DELETE /{account-slug}/v1/{resource}/{id} — Delete resource
Questions? Contact ScopeStack support via chat or email.
When a sync stops delivering data
If records stop arriving from an integration platform such as Workato, check the job history for the recipe, not the connection’s health indicator.
A connection can report a healthy authorization while every job still fails at the step that writes to the destination system, because an action-level credential rejection never updates the connection record. Individual jobs can also finish with a status of succeeded after exiting early on a conditional branch, so a run of green jobs is not proof that anything was delivered.
Open a failed job and read the step-level error. The step name plus the error text tells you which side rejected the request, which is usually enough to know whether the fix belongs on the ScopeStack side or the destination side.
Note that development and production environments use separate connections and separate recipes, so confirming one is healthy says nothing about the other.
New to ScopeStack?
ScopeStack automates scoping, pricing, and SOW generation for IT services teams. See how it fits your process.