API Authentication¶
TestGen uses OAuth 2.1 for API authentication. You register a client once and sign in through your browser to obtain a long-lived refresh token. Your automation then exchanges that refresh token for short-lived access tokens on each run, with no further interactive steps.
Note
API requests use the permissions of the authenticated user. The actions available through the API are governed by the user's role on each project. See User Access for role details.
Prerequisites¶
- A TestGen user account with appropriate project permissions.
One-time setup¶
Run these steps once to register an OAuth client and obtain a refresh token. The refresh token is a durable credential that your automation will reuse on every run.
Register a client¶
Register a new OAuth client:
curl -X POST https://<your-testgen-host>/oauth/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "<my-ci-pipeline>",
"redirect_uris": ["http://localhost:8080/callback"],
"grant_types": ["authorization_code", "refresh_token"]
}'
The response includes your client_id and client_secret. Store both securely — the secret cannot be retrieved later.
{
"client_id": "a1b2c3d4e5f6...",
"client_secret": "...",
"client_name": "my-ci-pipeline",
"grant_types": ["authorization_code", "refresh_token"],
"redirect_uris": ["http://localhost:8080/callback"],
"token_endpoint_auth_method": "client_secret_basic"
}
Generate a PKCE pair¶
TestGen requires PKCE on the authorization code flow. Generate a code_verifier (a random secret you keep locally) and derive a code_challenge (SHA-256 hash, base64url-encoded) that you'll send to the server:
import os, hashlib, base64
code_verifier = base64.urlsafe_b64encode(os.urandom(32)).decode().rstrip("=")
code_challenge = base64.urlsafe_b64encode(
hashlib.sha256(code_verifier.encode()).digest()
).decode().rstrip("=")
print(f"CODE_VERIFIER={code_verifier}")
print(f"CODE_CHALLENGE={code_challenge}")
Save the code_verifier — you'll need it in the token exchange step.
Authorize the client¶
Open the authorization URL in your browser, signing in with your TestGen user account and approving the client. Include the code_challenge as a query parameter:
https://<your-testgen-host>/oauth/authorize?response_type=code&client_id=<client_id>&redirect_uri=http://localhost:8080/callback&code_challenge=<code_challenge>&code_challenge_method=S256
After you approve, your browser redirects to the callback URL with an authorization code appended as a query parameter:
The callback does not need to resolve — copy the code value from the browser's address bar.
Exchange the code for tokens¶
Trade the authorization code for an access token and a refresh token, passing the code_verifier you saved earlier:
curl -X POST https://<your-testgen-host>/oauth/token \
-u "<client_id>:<client_secret>" \
-d "grant_type=authorization_code" \
-d "code=<authorization_code>" \
-d "redirect_uri=http://localhost:8080/callback" \
-d "code_verifier=<code_verifier>"
The response includes both tokens and the access token's lifetime in seconds:
Store the refresh_token as a secret in your automation environment (e.g., a CI variable or secret manager). This is the credential your script will use going forward.
Token lifetimes
Access tokens are valid for 1 hour (expires_in in the response is 3600). Refresh tokens are valid for 30 days from issuance. Run through the one-time setup again to issue a new refresh token before yours expires.
Call the API¶
Each time your automation runs, trade the refresh token for a fresh access token and use it to call the API. No browser or user interaction is needed.
Get a fresh access token¶
curl -X POST https://<your-testgen-host>/oauth/token \
-u "<client_id>:<client_secret>" \
-d "grant_type=refresh_token" \
-d "refresh_token=<refresh_token>"
The response includes a new access token:
Make API requests¶
Include the access token in the Authorization header of each request. For example, to list recent jobs in a project:
curl -H "Authorization: Bearer <access_token>" \
"https://<your-testgen-host>/api/v1/projects/<project_code>/jobs"
Revoke a token¶
Invalidate a token before it expires. Common reasons to revoke:
- A credential was accidentally exposed (committed to a repo, shared in logs, included in a screenshot).
- The owner of the automation left the team and their access should end immediately.
- You rotate credentials on a regular schedule.
- An integration is being decommissioned and you want to cut off its access without waiting for natural expiry.
curl -X POST https://<your-testgen-host>/oauth/revoke \
-u "<client_id>:<client_secret>" \
-d "token=<token>"
You can revoke either an access token or a refresh token. Revoking the refresh token ends the automation's ability to obtain new access tokens, effectively terminating its access.
Related topics¶
- User Access — role and permission details