Skip to main content

Authentication Guide

Every Agility API endpoint requires authentication except meta.v1, which is anonymous by design — the schema is not instance data. The method for API clients is a token sent as a Bearer header: an Agility-issued personal access token, or on OIDC-configured instances a token from the identity provider. Almost all customer instances authenticate members through SSO — the recommended configuration for security — via OIDC, or SAML where configured; API clients on those instances use tokens. (Basic authentication exists, but it is effectively a dev/demo setting; some on-premise instances instead use Windows Integrated Authentication.)

Step 1: Generate an Access Token​

  1. Log into your Agility instance
  2. Open the member menu (your avatar) and choose Applications
  3. Enter an application name (e.g., "My Integration") and select type Personal
  4. Click Add
  5. The access token is displayed once — copy it and store it securely. You cannot view it again after closing the popup.

Agility-issued tokens always begin with 1. followed by 28 characters of base64 — knowing the shape helps you spot a truncated paste. (Tokens issued by an identity provider on OIDC-configured instances look different.)

note

An administrator can disable access tokens for an instance. If the Applications page will not issue one, ask your administrator.

Step 2: Store Your Token Securely​

Environment variables (recommended):

# Linux/macOS
export AGILITY_BASE_URL="https://www7.v1host.com/YourInstance"
export AGILITY_ACCESS_TOKEN="your-token-here"

# Windows PowerShell
$env:AGILITY_BASE_URL="https://www7.v1host.com/YourInstance"
$env:AGILITY_ACCESS_TOKEN="your-token-here"

Examples across this site assume those two variables. Never commit tokens to source control, share them in chat or email, store them in plain text in a codebase, or reuse one token across applications.

Step 3: Include Authentication Headers​

Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
Accept: application/json

Code Examples​

cURL​

curl "${AGILITY_BASE_URL}/query.v1" \
-H "Authorization: Bearer ${AGILITY_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"from": "Story",
"select": ["Number", "Name"],
"page": { "size": 50, "start": 0 }
}'

Python​

import os
import requests

class AgilityClient:
def __init__(self):
self.base_url = os.environ['AGILITY_BASE_URL']
self.token = os.environ['AGILITY_ACCESS_TOKEN']
self.headers = {
'Authorization': f'Bearer {self.token}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}

def query(self, payload):
response = requests.post(
f'{self.base_url}/query.v1',
headers=self.headers,
json=payload,
timeout=30
)
response.raise_for_status()
return response.json()

# Usage
client = AgilityClient()
result = client.query({
'from': 'Story',
'select': ['Number', 'Name'],
'page': {'size': 50, 'start': 0}
})

TypeScript​

class AgilityClient {
private baseUrl: string;
private token: string;
private headers: HeadersInit;

constructor(baseUrl: string, token: string) {
this.baseUrl = baseUrl;
this.token = token;
this.headers = {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
Accept: 'application/json',
};
}

async query(payload: unknown): Promise<unknown> {
const response = await fetch(`${this.baseUrl}/query.v1`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(payload),
});

if (!response.ok) {
throw new Error(`Query failed: ${response.status}`);
}

return response.json();
}
}

// Usage
const client = new AgilityClient(process.env.AGILITY_BASE_URL!, process.env.AGILITY_ACCESS_TOKEN!);

const result = await client.query({
from: 'Story',
select: ['Number', 'Name'],
page: { size: 50, start: 0 },
});

Basic Authentication (Dev and Demo Instances Only)​

Basic authentication works only where Agility itself stores the member's password — which in practice means development and demo instances. Almost all customer instances authenticate through SSO, the recommended configuration for security reasons, and there Basic does not apply. Treat it as a local convenience, never an integration strategy:

# suitable for a local dev instance only
curl -u "username:password" "${AGILITY_BASE_URL}/rest-1.v1/Data/Story?sel=Name&page=1,0"

Even where it works, prefer tokens: a leaked password exposes the whole account and every session, while a leaked token can be revoked on its own.

Windows Integrated Authentication (On-Premise Only)​

On-premise installations on Enterprise and Ultimate editions can be configured to authenticate members through Windows Integrated Authentication (NTLM) instead of Agility's own login. An administrator selects it during installation, when IIS has the Windows Authentication component.

On these instances IIS turns off anonymous access for rest-1.v1, so a Bearer token sent there gets an NTLM challenge and never reaches Agility. Send access-token requests for rest-1.v1 to ~/rest-1.oauth.v1 instead (the SDKs do this with UseOAuthEndpoints). query.v1 and api/asset accept the token at their usual paths. Basic authentication isn't available on these instances, so use Access Token Authentication for API clients.

OIDC Access Tokens​

Instances configured for OIDC single sign-on also accept access tokens issued by the identity provider Agility is directly configured against as Bearer credentials — an alternative to Agility-generated tokens in those environments. In most OIDC configurations the authentication is federated: the Digital.ai platform sits between Agility and your organization's own identity provider. In that arrangement, the tokens that work are the ones issued by the Digital.ai platform — tokens issued directly by your organization's identity provider are not accepted. Whether this applies to your instance, and how to obtain a working token, depends on the identity configuration; ask your administrator.

Token Lifecycle​

Tokens do not expire. A token stays valid until you revoke it or an administrator disables access tokens for the instance — which makes deliberate lifecycle habits more important, not less:

  • Name tokens for what uses them ("CI/CD Pipeline", "Local Development") so revocation is surgical
  • Create separate tokens per application
  • Rotate on a schedule of your choosing, and immediately when a team member leaves or a token may have been exposed: create the new token, switch your secrets over, verify, then revoke the old one

A token is not a scoped credential. It always acts with the full rights and privileges of the member it belongs to — Agility currently offers no way to narrow an access token's reach. To limit what an integration can do, run it as a dedicated member whose role grants only what it needs — see Roles and permissions.

To revoke a token: member menu → Applications → remove the application entry. Revocation is immediate.

A Note on OAuth 2.0​

The Agility API has never supported OAuth 2.0 — despite naming, in old endpoint paths and internal machinery, that suggests otherwise.

You may still see paths like rest-1.oauth.v1 in older material. They were never OAuth 2.0: they existed so that access tokens could authenticate on instances using delegated SSO. Use the standard endpoints with a Bearer token instead, except on instances using Windows Integrated Authentication.

(The broader Digital.ai Platform API is a separate product surface with its own authentication.)

Testing Authentication​

# meta.v1 needs no credentials — a 200 here proves the URL is right
curl "${AGILITY_BASE_URL}/meta.v1/Story?accept=application/json" \
-H "Accept: application/json"

# a 200 here proves the token works
curl "${AGILITY_BASE_URL}/query.v1" \
-H "Authorization: Bearer ${AGILITY_ACCESS_TOKEN}" \
-H "Content-Type: application/json" \
-d '{"from":"Story","select":["Number"],"page":{"size":1,"start":0}}'

Testing the two in that order separates "wrong URL" from "bad credentials" — the two most common setup failures.

Common Authentication Errors​

ErrorLikely causeWhat to check
401 UnauthorizedMissing or invalid token; access tokens disabled instance-wideThe Authorization header, the token value, and — if both look right — whether your administrator has disabled tokens
403 ForbiddenAuthenticated, but your member's role lacks the rightThe member's role and project access

Security Best Practices​

✅ Do​

  • Store tokens in environment variables or a secret manager
  • Use separate tokens for dev, staging and production
  • Rotate tokens on a schedule — nothing expires them for you
  • Revoke immediately on any suspicion of exposure
  • Run integrations as a dedicated member with a minimal role
  • Use HTTPS for every request

❌ Don't​

  • Commit tokens to source control, or share them in chat or email
  • Reuse one token across applications
  • Put credentials in URLs or query strings
  • Assume a token is limited — it carries the member's full rights and privileges

Troubleshooting​

"401 with a Correct-Looking Token"​

Check the header shape — the space between Bearer and the token matters, and the token itself must start with 1.:

Authorization: Bearer 1.abc123...

An Agility-issued token always starts with 1. — anything else is most often a truncated or mangled paste (or, on OIDC-configured instances, an identity-provider token, which is legitimate).

"Works in Browser but Not in Code"​

The browser is riding a cookie-based session from the UI login. Code must send explicit credentials on every request.