Documentation menu

Documentation

TypeScript SDK

The TypeScript SDK is a thin client over the registry and gateway. It handles discovery, mandate-bearing invocation, idempotency and refunds so you can focus on what your agent does.

Install

terminal
npm install @sgovr/sdk

Initialize the client

Create a SgovrClient. With no options it targets the configured Sgovr endpoints; pass base URLs to point at your own deployment.

client.ts
import { SgovrClient } from "@sgovr/sdk";
// With no arguments it targets the local dev endpoints.
// Pass gateway and registry base URLs to point at your own deployment.
const sgovr = new SgovrClient(
process.env.SGOVR_GATEWAY_URL,
process.env.SGOVR_REGISTRY_URL,
);

Discover providers

Pass a natural-language intent and get back relevance-ranked, verified providers and the actions they expose.

discover.ts
// Natural-language intent → ranked, verified providers
const results = await sgovr.discover("book a hotel room in Lisbon");
const hit = results[0];
console.log(hit.providerId, hit.action.name); // "prov_lux_hotels" "book_room"

Mint a mandate

A mandate is a signed, scoped, time-limited credential. It declares the scopes the agent may use, a spend cap (in minor units), and a currency. The dev helper below is for local testing.

mandate.ts
import { mintDevMandate } from "@sgovr/sdk";
// Dev helper only. In production the principal issues the mandate
// (e.g. via an OAuth consent screen); your agent never mints its own.
const mandate = mintDevMandate({
agentId: "agent_demo",
scopes: ["booking:write", "payments:charge", "payments:refund"],
spendCapMinor: 50_000, // €500.00, in minor units (cents)
currency: "EUR",
secret: process.env.SGOVR_MANDATE_SECRET!, // the gateway's dev mandate secret
});

Spend caps are hard

The spendCapMinor is enforced by reservation: a transactional call that would exceed it is rejected before the provider is ever called. Overspend is impossible.

In production, mandates are signed asymmetrically - ES256 (P-256) or EdDSA (Ed25519) - and the gateway verifies them against a JWKS. Configure the gateway with SGOVR_MANDATE_JWKS_URL and use mintAsymmetricMandate instead of the dev helper.

mandate-prod.ts
import { mintAsymmetricMandate } from "@sgovr/sdk";
import { readFileSync } from "node:fs";
// Production: sign with an EC (P-256) or Ed25519 private key.
// The gateway must be configured with SGOVR_MANDATE_JWKS_URL pointing to a
// JWKS that contains the matching public key for keyId.
const mandate = mintAsymmetricMandate({
agentId: "agent_prod",
scopes: ["booking:write", "payments:charge"],
spendCapMinor: 50_000,
currency: "EUR",
privateKey: readFileSync("mandate.pem", "utf8"),
keyId: "mandate-key-2026", // must match a kid in your JWKS
algorithm: "ES256", // or "EdDSA" for Ed25519 keys
});

Invoke a free action

Actions with sideEffects: "none" (such as a search) need only a valid mandate with the right scopes.

search.ts
const search = await sgovr.invoke(
"prov_lux_hotels",
"search_rooms",
{ city: "Lisbon", checkIn: "2026-07-01", checkOut: "2026-07-03", maxPrice: 200 },
{ token: mandate },
);
console.log(search.status, search.body);

Invoke a transactional action

Actions with sideEffects: "transactional" move money. They require two extra things: an idempotencyKey (so retries never double-book) and an amountMinor - the spend you authorize, which the gateway reserves against the mandate cap, then captures on success.

book.ts
const booking = await sgovr.invoke(
"prov_lux_hotels",
"book_room",
{ roomId: "room_101", checkIn: "2026-07-01", checkOut: "2026-07-03", guestName: "Ada Lovelace" },
{
token: mandate,
idempotencyKey: "demo-booking-001", // de-dupes retries
amountMinor: 29_800, // the spend you authorize, reserved against the cap
},
);
console.log(booking.transactionId, booking.capturedMinor, booking.feeMinor);
  • transactionId - the settled transaction, used for refunds.
  • capturedMinor - the amount actually charged; any unused reservation is released.
  • feeMinor - Sgovr's take-rate portion of the charge.

Refund a transaction

Refunds honour the provider's declared refund policy and require the payments:refund scope.

refund.ts
const refund = await sgovr.refund(booking.transactionId, { token: mandate });
console.log(refund.status);

Validate & conform a spec

The SDK ships a CLI to validate a capability spec and run the conformance suite before you register a provider.

terminal
# sgovr-spec is a bin of @sgovr/sdk. Once it's installed you can call it
# directly; otherwise run it through npx with -p to resolve the package.
# Validate a capability spec against the schema
npx -p @sgovr/sdk sgovr-spec validate ./luxhotels.sgovr.json
# Validate AND probe the adapter endpoints (golden-transaction replay)
npx -p @sgovr/sdk sgovr-spec conform ./luxhotels.sgovr.json