Skip to main content

Overview

The tokens sub-client handles the token lifecycle: exchanging authorization codes for grant tokens, verifying tokens via the API, and revoking tokens.
// Exchange, verify, revoke
const token = await grantex.tokens.exchange({ code, agentId: agent.id });
const result = await grantex.tokens.verify(token.grantToken);
await grantex.tokens.revoke(result.grantId);

tokens.exchange()

Exchange an authorization code for a signed grant token (RS256 JWT).
const token = await grantex.tokens.exchange({
  code: 'auth_code_from_callback',
  agentId: agent.id,
});

console.log(token.grantToken);   // RS256 JWT string
console.log(token.grantId);      // 'grnt_01HXYZ...'
console.log(token.scopes);       // ['calendar:read', 'payments:initiate:max_500']
console.log(token.expiresAt);    // '2026-03-02T12:00:00Z'
console.log(token.refreshToken); // 'rt_01HXYZ...'

Parameters

code
string
required
The authorization code received at your redirectUri after user consent.
agentId
string
required
The ID of the agent that initiated the authorization request.
codeVerifier
string
The PKCE code verifier. Required if codeChallenge was provided in the authorize step. See PKCE.

Response: ExchangeTokenResponse

grantToken
string
The signed RS256 JWT grant token. Pass this to your agent for use in API calls.
grantId
string
The unique grant record ID.
scopes
string[]
The scopes granted by the user.
expiresAt
string
ISO 8601 timestamp when the grant token expires.
refreshToken
string
A refresh token for obtaining new grant tokens without re-authorization.

tokens.refresh()

Refresh a grant token using a refresh token. Returns a new grant token and a new refresh token (the old refresh token is invalidated). The grantId stays the same. Refresh tokens are single-use and rotated on every refresh per SPEC §7.4.
const newToken = await grantex.tokens.refresh({
  refreshToken: token.refreshToken,
  agentId: agent.id,
});

console.log(newToken.grantToken);   // new RS256 JWT
console.log(newToken.refreshToken); // new refresh token (old one invalidated)
console.log(newToken.grantId);      // same grant ID

Parameters

refreshToken
string
required
The refresh token from a previous exchange() or refresh() response.
agentId
string
required
The agent ID associated with the grant.

Response: ExchangeTokenResponse

Returns the same shape as exchange() — see above for field descriptions.
Each refresh token can only be used once. If you attempt to reuse a refresh token, the request will be rejected with a 400 error. Always store and use the new refreshToken from the response.

tokens.verify()

Verify a grant token online via the Grantex API. This is useful when you want server-side validation without managing JWKS yourself.
const result = await grantex.tokens.verify(token.grantToken);

if (result.valid) {
  console.log(result.grantId);   // 'grnt_01HXYZ...'
  console.log(result.scopes);    // ['calendar:read']
  console.log(result.principal);  // 'user_abc123'
  console.log(result.agent);      // 'did:grantex:ag_01HXYZ...'
  console.log(result.expiresAt);  // '2026-03-02T12:00:00Z'
}

Parameters

token
string
required
The grant token JWT string to verify.

Response: VerifyTokenResponse

valid
boolean
Whether the token is valid and not expired/revoked.
grantId
string
The grant record ID (present when valid is true).
scopes
string[]
The granted scopes.
principal
string
The user (principal) who authorized the grant.
agent
string
The agent DID that holds the grant.
expiresAt
string
ISO 8601 timestamp when the token expires.
For zero-latency, offline verification without calling the Grantex API, use verifyGrantToken() instead.

tokens.revoke()

Revoke a token by its token ID (the jti claim). The API responds with 204 No Content.
await grantex.tokens.revoke('tok_01HXYZ...');
// Returns void — the token is now invalid

Parameters

tokenId
string
required
The token ID (jti claim from the JWT) to revoke.

Response

Returns void. The token is immediately invalidated.

Full example

import { Grantex } from '@grantex/sdk';

const grantex = new Grantex({ apiKey: process.env.GRANTEX_API_KEY });

// Exchange the code from the OAuth callback
const token = await grantex.tokens.exchange({
  code: req.query.code,
  agentId: 'ag_01HXYZ...',
});

// Hand the grant token to your agent
const grantToken = token.grantToken;

// Later: verify the token is still valid
const check = await grantex.tokens.verify(grantToken);
if (!check.valid) {
  throw new Error('Token has been revoked or expired');
}

// When the task is complete, revoke the token
await grantex.tokens.revoke(check.grantId);