Skip to main content
The Stigg Agent SDK is in public beta and its API may change before general availability.

Installation

Requires Node.js 22 or later. The package does not depend on any LLM vendor SDK: install only the vendor clients you use.

How it connects to Stigg

The Agent SDK builds on two Stigg clients and picks one for each operation. You never call either of them directly. On an account without Governance, the SDK uses the Node server SDK alone, at customer level. For caching, see Caching and accuracy. For concepts, see LLM and gateway wrappers and Agent governance.

StiggAgentSDK

Create one instance per Stigg environment and share it. The constructor is synchronous and makes no network calls. The connection to Stigg is set up on the first call that needs it, or up front with init(). If it fails, for example because Stigg is briefly unreachable, a later call tries again after a short wait, so the SDK recovers without a restart. For example, new StiggAgentSDK({ apiKey, baseUrl: 'https://stigg.internal', ingest: 'sync' }). The shorthand takes the API key first and the other options second, for example new StiggAgentSDK(apiKey, { ingest: 'sync' }).
StiggAgentSDKOptions
Optional settings. Every one has a working default.

Methods

In the order you typically use them: wrap a client, register an agent, check and report anything a wrapped client does not cover, read the summary, flush before the process exits, and deregister agents you no longer need.

wrap

Returns a new client that behaves like client. Every model call it makes is checked before the call (when the context sets entitlement) and its usage is reported after it. The client you passed in is not changed. Synchronous. Each covered method also accepts a stiggContext field in its own parameters, which overrides the client’s default for that call. A client wrapped with no customerId can serve every customer, and then each call must name its own.
object
required
The LLM or gateway client to wrap, for example new Anthropic(). See Supported providers.
ClientOptions
WrappedClient
The wrapped client. It also has a stigg property with these members:
Throws if no recipe matches the client, or if the client is already wrapped. A call through the wrapped client throws if its stiggContext has a field the SDK does not recognize, such as a misspelled agentId, rather than ignore it.

register

Creates or updates an agent in Governance: its entity and, optionally, its budget and parent. For how to use it, see Agent governance.
string
required
The customer that owns the agent.
string
required
Your stable ID for the agent.
string
required
The Governance entity type to create it as, for example agent. It must already exist. See Setting up governance.
string
A readable name for the agent, shown in the Stigg app instead of its ID.
Record<string, string>
Your own key-value data to store on the agent’s entity, for example { owner: 'research-lead' }. Values must be strings. See Entities.
AgentBudget
The agent’s budget and place in the tree for one credit currency or metered feature (a Governance assignment). Omit it to save only the agent’s entity.
Promise<string>
The agent ID you passed in.
Throws GovernanceNotEnabledError when the input sets a budget and Governance is not enabled on the account. Without a budget, it logs a warning instead and returns.

check

Checks whether a customer or agent has access, without making a model call. Use it for actions a wrapped client does not cover, such as a tool call, or to check before an agent starts a task. See Gating actions that are not model calls.
StiggContext
required
Who the check is for and what it is checked against. Must include customerId and entitlement. See StiggContext.
number
default:"1"
How much the action is about to use. See Requested usage.
Promise<AccessDecision>
The decision. When access is denied, check() returns a decision with hasAccess: false rather than throwing an AccessDeniedError, so you can branch on it directly.

report

Reports usage directly. A wrapped client reports the usage of model calls for you. Use this for usage it cannot see, such as the number of searches a tool made.
StiggContext
required
Who the usage is attributed to. Must include customerId. See StiggContext.
Record<string, number>
required
The usage to report, keyed by Stigg feature or credit currency ID, for example { 'feature-web-searches': 1 }.
Promise<IngestResult>
The ingest result. A failed report does not throw: the result has ok: false, and the error is passed to onError.

summary

A method of each wrapped client, not of the SDK instance. Returns what that client has done so far, without waiting for pending reports. To wait for them first, use flush.
SessionSummary

flush

Waits for pending usage reports. Reports are sent in the background, so call this before a serverless function, request-scoped worker or CLI exits.
boolean
default:"false"
stigg.flush() only. After flushing, also release the SDK’s connections, like close.
Promise<SessionSummary[]>
stigg.flush() returns one summary per wrapped client. governed.stigg.flush() returns that client’s summary.

deregister

Archives an agent’s entity. Optional for long-lived agents. Deregister ephemeral agents, created for a single task or session, when they finish. See Agent governance.
string
required
The customer that owns the agent.
string
required
The agent to archive.

Other methods

init

Connects to Stigg up front instead of on the first call, so a wrong API key fails at startup. Optional. Returns which client serves each operation.

close

Releases the SDK’s connections. A Node server SDK client you passed in as client is not closed.

denial

Returns the decision if err is an AccessDeniedError, otherwise undefined. Use it in a catch block to tell denied access apart from other errors. The same as isAccessDenied(err).

governanceHeaders

The x-stigg-customer-id, x-stigg-dimensions, x-stigg-attribution-key and x-stigg-run-id headers for a context, with no wrapped client involved. See A gateway you operate.

ingestFromHeaders

For a gateway or proxy you operate. Reads the customer and agent from the x-stigg-* request headers and reports the usage the proxy observed. It never checks access.
Record<string, string | string[] | undefined>
required
The incoming request’s headers.
object
required
Promise<IngestResult>

StiggContext

Says who a call is for and how it is checked and reported. Pass it to wrap() as the default for every call through a client, and inside any call’s own parameters to override it for that call. Every field is optional in either place, but each call must end up with a customerId. A field the SDK does not recognize, such as a misspelled agentId, throws an error rather than being ignored.
string
The Stigg customer the call belongs to.
{ currencyId } | { featureId }
The credit currency or metered feature the call is checked against. Omit it to meter without checking.
string
The agent the call is attributed to. Requires attributionKey. See Agent governance.
string
The attribution key of the agent’s entity type, for example agentId. The agent ID is sent under this key on every check and report.
Record<string, string>
More attribution, such as a user or a model, sent on every check and report. Merged key by key when overridden.
'allow' | 'deny'
Overrides the SDK’s fallback strategy.
(measurement: Measurement) => Record<string, number>
What to report. Defaults to the vendor’s own metrics. See Usage mappers.
'async' | 'sync'
Overrides the SDK’s ingest mode.
{ name: string }
The event name in async mode. Defaults to the vendor call, such as anthropic.messages.create.
string
Deduplicates the report. Defaults to the vendor’s request ID when it has one.
string
Sent as x-stigg-run-id, to correlate work across processes.

AccessDecision

What a check returns: from check(), from stigg.denial(err), and to the onDecision hook.
boolean
Whether access is granted and the call may go ahead. The same as hasAccess in an entitlement check.
string | undefined
The entity whose limit denied access: an agent, a team, or the customer.
string | undefined
Why access was denied, such as BudgetExceeded or InsufficientCredits.
'top-up' | 'raise-budget' | 'subscribe' | 'retry' | undefined
What would let the call through. See Remedies are product decisions.
number | undefined
The smallest budget left anywhere in the chain.
number | null | undefined
The limit of the budget that decided.
number | undefined
The usage of the budget that decided.
'rest' | 'node-sdk' | 'cache' | 'policy' | 'unenforced'
What produced the decision. policy means the check could not complete and the fallback strategy decided. unenforced means no entitlement was set.
number
When the check was made, in epoch milliseconds.
boolean | undefined
Stigg answered from fallback state.
boolean | undefined
The SDK made the decision from live data, not Stigg. For a credit check, Stigg returns the balance and the SDK compares it with the requested usage. Can be true together with isFallback.
string
A sentence to show the user, matched to the remedy.
string
A one-line description for logs.

IngestResult

What a usage report returns.
boolean
true only if every metric was accepted.
Record<string, number>
What was reported, by feature or currency ID.
string
The key the report was deduplicated on.
'async' | 'sync'
Which ingest mode was used.
boolean | undefined
sync only: Stigg had already seen these keys, so nothing was counted again.
number | undefined
sync only: the credits the report used, when what it reported draws a credit balance. Not set when the reported features are not mapped to credits.
unknown
The failure, when ok is false.

Helpers

Errors

isAccessDenied(err) returns the decision for an AccessDeniedError and undefined otherwise. isGovernanceNotEnabled(err) and isEngineError(err) check the other two. They work without instanceof, so they are safe across bundles.