2. Authentication (JWT Bearer Grant Flow)
DocEndorse uses the OAuth 2.0 JWT Bearer Grant flow to allow your application to securely obtain access tokens on behalf of your users.
This method allows your system to:
- Authenticate using your application's private key
- Act on behalf of a specific user
- Request scoped access to create AI agent sessions
- Avoid storing user passwords
Overview of the Authentication Process
To obtain an access token, you must:
- Generate an RSA public/private key pair.
- Upload the public key to DocEndorse.
- Store the private key securely in your system.
- Create a signed JWT assertion using your private key.
- Exchange the JWT assertion for an access token.
- Use the access token to call the handoff endpoint.
Step 1: Create a JWT Assertion
Your application must generate a JWT signed using RS256 with your private key.
The JWT must contain the following claims:
| Claim | Description |
|---|---|
| iss | Your Client ID |
| sub | The external user ID |
| aud | https://api.docendorse.com |
| iat | Issued at timestamp |
| exp | Expiration (max 5 minutes) |
| jti | Unique ID to prevent replay attacks |
| User's email | |
| given_name | User's first name |
| family_name | User's last name |
| scope | agent_sessions:create openid |
Example JWT Payload (JSON)
{
"iss": "client_c646d5b95f3eb6cf38ec1b41157fb1ee",
"sub": "usr_hahua8h7",
"aud": "https://api.docendorse.com",
"iat": 1710000000,
"exp": 1710000300,
"jti": "550e8400-e29b-41d4-a716-446655440000",
"email": "user@example.com",
"given_name": "John",
"family_name": "Doe",
"scope": "agent_sessions:create openid"
}
You must sign this payload using your private key with the RS256 algorithm.
The result will be a JWT assertion string that looks like: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
Step 2: Exchange JWT for Access Token
Once the JWT is created, you must exchange it for an access token.
Token Endpoint
POST | https://app.docendorse.com/oauth2/v2/token
Required Form Fields:
| Field | Value |
|---|---|
| grant_type | urn:ietf:params:oauth:grant-type:jwt-bearer |
| assertion | Your signed JWT |
Example Using curl:
curl -X POST https://app.docendorse.com/oauth2/v2/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer" \
-d "assertion=YOUR_SIGNED_JWT_HERE"
Step 3: Successful Token Response
If successful, you will receive a JSON response:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"refresh_token": "def50200aabbccddeeff...",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "agent_sessions:create openid"
}
Step 4: Using the Access Token
You must include the access token in the Authorization header when calling the handoff endpoint:
Authorization: Bearer ACCESS_TOKEN
curl -X POST https://docendorse.com/api/v1/agent-sessions/create \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..." \
-H "Content-Type: application/json" \
-d '{ ... }'
Important Security Notes
- The JWT must expire within 5 minutes.
- Always generate a unique jti value.
- Store your private key securely (never expose it in frontend code).
- Access tokens should be stored securely and refreshed when expired.
- Never share your client secret publicly.