Skip to content
synthreo.ai

API Authentication - Synthreo Builder

Authentication guide for the Builder API - generate access tokens using client credentials, add Bearer authorization headers, and manage API access for multi-tenant environments.

The Synthreo Builder API uses a JWT (JSON Web Token) based authentication model. To interact with the API, you must first obtain an access token by authenticating with your user credentials. This token must then be included in the Authorization header of all subsequent API requests.

Important: Access tokens expire after 24 hours and must be renewed by re-authenticating. The token response also includes a refreshToken (see Token Expiration and Management).

To get an access token, you need to send a POST request to the authentication endpoint with your Synthreo login credentials.

POST https://auth.synthreo.ai/oauth2/builder/token

The request body must be a JSON object containing your email and password. If your identity has access to more than one account, you can optionally include an accountId to scope the token to a specific account.

{
"email": "your.email@domain.com",
"password": "your_password"
}
{
"Content-Type": "application/json",
"Origin": "https://builder.synthreo.ai"
}

Note: The Accept header is not required. The Origin header should be set to the application you’re logging into (e.g., https://builder.synthreo.ai).

FieldTypeRequiredDescription
emailstringYesYour Synthreo Builder login email address
passwordstringYesYour Synthreo Builder login password
accountIdintegerNoScopes the token to a specific account. If omitted, your default account is used. Valid values come from the accountOptions array in the response.
codestringNoOne-time MFA code. Only required when your account has multi-factor authentication enabled (see Multi-Factor Authentication).
Terminal window
curl -X POST 'https://auth.synthreo.ai/oauth2/builder/token' \
-H 'Content-Type: application/json' \
-H 'Origin: https://builder.synthreo.ai' \
-d '{
"email": "your.email@domain.com",
"password": "your_password"
}'

A successful authentication request returns a JSON object containing the JWT access token, a refresh token, the timestamp of your last login, and - when your identity can access more than one account - an accountOptions array.

{
"token": "eyJhbGciOiJFUzI1NiIsImtpZCI6...",
"refreshToken": "eyJhbGciOiJFUzI1NiIsImtpZCI6...",
"accountOptions": [
{
"accountId": 1234,
"accountName": "API User",
"instanceName": "Production",
"isOwner": false,
"roleId": 4,
"roleName": "Full Power User"
}
],
"lastLoginAt": "2026-06-09T15:40:05.863546"
}

accountOptions is omitted when your identity has access to only one account. When present, it lists every account you can authenticate against; pass the desired accountId back in the request body to scope a new token to that account.

FieldTypeDescription
tokenstringThe JWT access token to be used for authenticating API requests
refreshTokenstringA refresh token issued alongside the access token (see Token Expiration and Management)
accountOptionsarrayAccounts your identity can authenticate against. Omitted when only one account is accessible.
accountOptions[].accountIdintegerAccount ID. Pass this as accountId in the request body to scope a token to this account.
accountOptions[].accountNamestringDisplay name for the account
accountOptions[].instanceNamestringName of the application instance the account belongs to
accountOptions[].isOwnerbooleanWhether you are the owner of this account
accountOptions[].roleIdintegerNumeric role ID for your access to this account
accountOptions[].roleNamestringHuman-readable role name (e.g., “Full Power User”)
lastLoginAtstringISO 8601 timestamp of the last successful login

If the authentication fails, the API will return an error response with a corresponding HTTP status code.

Status CodeMeaningCommon Cause
400 Bad RequestMalformed requestMissing required fields or invalid JSON
401 UnauthorizedInvalid credentialsIncorrect email or password
{
"error": "Invalid credentials"
}

If your account has multi-factor authentication (MFA) enabled, the initial token request returns 202 Accepted instead of 200 OK, indicating that a one-time code is required. For email-based MFA, a code is sent to your email at this point.

To complete authentication, resend the same request with the one-time code in the code field:

Terminal window
curl -X POST 'https://auth.synthreo.ai/oauth2/builder/token' \
-H 'Content-Type: application/json' \
-H 'Origin: https://builder.synthreo.ai' \
-d '{
"email": "your.email@domain.com",
"password": "your_password",
"code": "123456"
}'

A successful response returns the standard token object described above.

Your authentication credentials consist of your regular Synthreo Builder login information:

  • Email: Your regular login email for Synthreo Builder
  • Password: Your regular login password for Synthreo Builder

If your identity can access multiple accounts, the response includes an accountOptions array. Pass the chosen accountId in the request body to scope your token to a specific account. If you’re unsure which account to use, contact your Synthreo representative.

Once you have obtained an access token, you must include it in the Authorization header of all subsequent API requests. The token should be prefixed with Bearer.

Authorization: Bearer YOUR_JWT_TOKEN

Replace YOUR_JWT_TOKEN with the token you received from the authentication endpoint.

Terminal window
curl -X GET 'https://builder-api.synthreo.ai/your-endpoint' \
-H 'Authorization: Bearer YOUR_JWT_TOKEN' \
-H 'Content-Type: application/json'

Access tokens have a limited lifetime and expire after 24 hours. The token response includes a refreshToken, but a programmatic refresh flow for direct API clients is not yet available. Until it is, renew an expired token by re-authenticating against the /oauth2/builder/token endpoint.

Before making an API call, check if the cached token is still valid. If it has expired or is about to expire, request a new token using the authentication endpoint.

from datetime import datetime, timedelta, timezone
import requests
class SynthreoApiClient:
AUTH_URL = "https://auth.synthreo.ai/oauth2/builder/token"
ORIGIN = "https://builder.synthreo.ai"
def __init__(self, email, password, account_id=None):
self.email = email
self.password = password
self.account_id = account_id
self.token = None
self.token_expiry = None
def _token_expired(self):
if not self.token or not self.token_expiry:
return True
return datetime.now(timezone.utc) > (self.token_expiry - timedelta(minutes=5))
def ensure_valid_token(self):
if self._token_expired():
self.authenticate()
def authenticate(self):
body = {"email": self.email, "password": self.password}
if self.account_id is not None:
body["accountId"] = self.account_id
resp = requests.post(
self.AUTH_URL,
headers={
"Content-Type": "application/json",
"Origin": self.ORIGIN,
},
json=body,
timeout=30,
)
resp.raise_for_status()
data = resp.json()
self.token = data.get("token")
if not self.token:
raise ValueError("Authentication succeeded but token missing")
self.token_expiry = datetime.now(timezone.utc) + timedelta(hours=24)
def make_request(self, url, method="GET", headers=None, **kwargs):
self.ensure_valid_token()
req_headers = {"Authorization": f"Bearer {self.token}"}
if headers:
req_headers.update(headers)
return requests.request(method, url, headers=req_headers, **kwargs)

If you receive a 401 Unauthorized response during API calls, it typically means your token has expired. Re-authenticate and retry the request:

Terminal window
curl -X POST 'https://auth.synthreo.ai/oauth2/builder/token' \
-H 'Content-Type: application/json' \
-H 'Origin: https://builder.synthreo.ai' \
-d '{
"email": "your.email@domain.com",
"password": "your_password"
}' \
| jq -r '.token'

A single Synthreo identity can have access to more than one account, including accounts across multiple customers (tenants) and application instances. When you authenticate, the response includes an accountOptions array listing every account your identity can use (it is omitted when only one account is accessible).

To scope a token to a specific account, pass its accountId in the request body:

{
"email": "example@company.com",
"password": "your_password",
"accountId": 1234
}

If accountId is omitted, the token is generated for your default account. This pattern works against any of the /oauth2/{app}/token endpoints (builder, threo, tenant) and is the basis for building applications that switch context between accounts.

  • Never expose your credentials in client-side code or version control
  • Use environment variables or a secure secret management system to store your email and password
  • Implement token refresh logic to handle token expiration gracefully
  • Do not log sensitive information, such as passwords or access tokens
  • Store tokens securely in memory or secure storage, never in plain text files
  • Use HTTPS exclusively for all API communications to protect credentials in transit

Related pages: