Skip to main content

Overview

The events sub-client provides real-time streaming of authorization events. You can consume events as an async generator via stream(), or use the convenience subscribe() wrapper for a callback-based approach. Events are delivered via Server-Sent Events (SSE).
// Stream events or subscribe with a handler
for await (const event of grantex.events.stream()) {
  console.log(event.type, event.data);
}

// Or use the convenience wrapper
const unsubscribe = grantex.events.subscribe((event) => {
  console.log(event.type, event.data);
});

events.stream()

Open an SSE connection and yield authorization events as an async generator. The connection remains open until you break out of the loop or the server closes it.
for await (const event of grantex.events.stream()) {
  console.log(event.type);      // 'grant.created' | 'grant.revoked' | 'token.issued' | ...
  console.log(event.id);        // 'evt_01HXYZ...'
  console.log(event.timestamp); // '2026-03-08T14:30:00Z'
  console.log(event.data);      // { grantId: 'grnt_01HXYZ...', ... }

  if (event.type === 'budget.exhausted') {
    // Handle budget exhaustion
    break;
  }
}

Parameters

eventTypes
string[]
Filter to specific event types. If omitted, all event types are streamed.
since
string
ISO 8601 timestamp to replay events from. Useful for catching up after a disconnection.

Yielded: GrantexEvent

id
string
Unique event identifier.
type
string
Event type: 'grant.created', 'grant.revoked', 'token.issued', 'budget.threshold', or 'budget.exhausted'.
timestamp
string
ISO 8601 timestamp when the event occurred.
data
object
Event payload. Shape varies by event type — see Event types below.

events.subscribe()

Subscribe to events with a callback function. This is a convenience wrapper around stream() that handles the async iteration for you and returns an unsubscribe function to close the connection.
const unsubscribe = grantex.events.subscribe((event) => {
  switch (event.type) {
    case 'grant.created':
      console.log(`New grant: ${event.data.grantId}`);
      break;
    case 'grant.revoked':
      console.log(`Grant revoked: ${event.data.grantId}`);
      break;
    case 'token.issued':
      console.log(`Token issued for grant: ${event.data.grantId}`);
      break;
    case 'budget.threshold':
      console.log(`Budget at ${event.data.percentage}% for grant: ${event.data.grantId}`);
      break;
    case 'budget.exhausted':
      console.log(`Budget exhausted for grant: ${event.data.grantId}`);
      break;
  }
});

// Later: close the SSE connection
unsubscribe();

Parameters

handler
(event: GrantexEvent) => void
required
Callback function invoked for each event.
options
object
Optional configuration with eventTypes and since fields (same as stream()).

Returns: () => void

An unsubscribe function. Call it to close the SSE connection and stop receiving events.

Event types

grant.created

Emitted when a new grant is created after user consent.
{
  type: 'grant.created',
  data: {
    grantId: 'grnt_01HXYZ...',
    agentId: 'ag_01HXYZ...',
    principalId: 'user_abc123',
    scopes: ['calendar:read', 'contacts:read'],
  }
}

grant.revoked

Emitted when a grant is revoked (by the developer, principal, or system).
{
  type: 'grant.revoked',
  data: {
    grantId: 'grnt_01HXYZ...',
    revokedBy: 'developer',  // 'developer' | 'principal' | 'system'
  }
}

token.issued

Emitted when a grant token is issued (via exchange or refresh).
{
  type: 'token.issued',
  data: {
    grantId: 'grnt_01HXYZ...',
    tokenId: 'tok_01HXYZ...',
    method: 'exchange',  // 'exchange' | 'refresh'
  }
}

budget.threshold

Emitted when a grant’s budget consumption crosses 50% or 80%.
{
  type: 'budget.threshold',
  data: {
    grantId: 'grnt_01HXYZ...',
    percentage: 80,
    remaining: 200,
    initial: 1000,
  }
}

budget.exhausted

Emitted when a grant’s budget is fully consumed.
{
  type: 'budget.exhausted',
  data: {
    grantId: 'grnt_01HXYZ...',
    initial: 1000,
  }
}

Full example

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

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

// Subscribe to budget events only
const unsubscribe = grantex.events.subscribe(
  (event) => {
    if (event.type === 'budget.threshold') {
      console.warn(`Budget alert: ${event.data.percentage}% used for ${event.data.grantId}`);
    }
    if (event.type === 'budget.exhausted') {
      console.error(`Budget exhausted for ${event.data.grantId} — revoking grant`);
      grantex.grants.revoke(event.data.grantId);
    }
  },
  { eventTypes: ['budget.threshold', 'budget.exhausted'] },
);

// Clean up on shutdown
process.on('SIGINT', () => {
  unsubscribe();
  process.exit(0);
});