Skip to main content

Overview

The Events service provides real-time streaming of authorization events via Server-Sent Events (SSE). Consume events with a channel-based Stream() method or use the Subscribe() convenience wrapper with a callback.

Stream

Open an SSE connection and receive authorization events on a channel. The connection remains open until the context is cancelled.
eventCh, errCh, err := client.Events.Stream(ctx, &grantex.StreamOptions{
    EventTypes: []string{"grant.created", "budget.threshold"},
})
if err != nil {
    log.Fatal(err)
}

for {
    select {
    case event := <-eventCh:
        fmt.Printf("Type: %s\n", event.Type)
        fmt.Printf("ID: %s\n", event.ID)
        fmt.Printf("Timestamp: %s\n", event.Timestamp)
        fmt.Printf("Data: %v\n", event.Data)
    case err := <-errCh:
        log.Printf("Stream error: %v\n", err)
        return
    case <-ctx.Done():
        return
    }
}

Parameters (StreamOptions)

ParameterTypeRequiredDescription
EventTypes[]stringNoFilter to specific event types. If empty, all types are streamed.
Since*stringNoISO 8601 timestamp to replay events from (for catch-up).

Event (GrantexEvent)

FieldTypeDescription
IDstringUnique event identifier.
TypestringEvent type (see Event types below).
TimestampstringISO 8601 timestamp when the event occurred.
Datamap[string]anyEvent payload. Shape varies by event type.

Subscribe

Subscribe to events with a callback function. Returns a cancel function to close the connection. This is a convenience wrapper around Stream().
cancel, err := client.Events.Subscribe(ctx, func(event grantex.GrantexEvent) {
    switch event.Type {
    case "grant.created":
        fmt.Printf("New grant: %s\n", event.Data["grantId"])
    case "grant.revoked":
        fmt.Printf("Grant revoked: %s\n", event.Data["grantId"])
    case "budget.threshold":
        fmt.Printf("Budget at %v%% for grant %s\n",
            event.Data["percentage"], event.Data["grantId"])
    case "budget.exhausted":
        fmt.Printf("Budget exhausted for grant %s\n", event.Data["grantId"])
    }
}, &grantex.StreamOptions{
    EventTypes: []string{"grant.created", "grant.revoked", "budget.threshold", "budget.exhausted"},
})
if err != nil {
    log.Fatal(err)
}
defer cancel()

// Block until interrupted
<-ctx.Done()

Parameters

ParameterTypeRequiredDescription
handlerfunc(grantex.GrantexEvent)YesCallback invoked for each event.
options*StreamOptionsNoOptional stream configuration.

Returns

Returns a func() cancel function and an error. Call the cancel function to close the SSE connection.

Event types

grant.created

Emitted when a new grant is created after user consent.
// event.Data fields:
// "grantId"     - string
// "agentId"     - string
// "principalId" - string
// "scopes"      - []any

grant.revoked

Emitted when a grant is revoked.
// event.Data fields:
// "grantId"   - string
// "revokedBy" - string ("developer" | "principal" | "system")

token.issued

Emitted when a grant token is issued (via exchange or refresh).
// event.Data fields:
// "grantId" - string
// "tokenId" - string
// "method"  - string ("exchange" | "refresh")

budget.threshold

Emitted when a grant’s budget consumption crosses 50% or 80%.
// event.Data fields:
// "grantId"    - string
// "percentage" - float64 (50 or 80)
// "remaining"  - float64
// "initial"    - float64

budget.exhausted

Emitted when a grant’s budget is fully consumed.
// event.Data fields:
// "grantId" - string
// "initial" - float64