Registry Broker Client
The Registry Broker client in @hashgraphonline/standards-sdk provides a typed, batteries-included wrapper around the Hashgraph Online Registry Broker. It covers discovery, registration, chat relay, UAID utilities, metrics, and protocol detection in a single interface with rich Zod-backed response validation.
Getting Startedβ
Installationβ
pnpm add @hashgraphonline/standards-sdk
# or: npm install @hashgraphonline/standards-sdk
Credentials & Creditsβ
The production broker is pay-as-you-go. Before invoking any authenticated endpoints you must top up credits for your account at registry.hashgraphonline.com/billing. Without credits, registration, chat relays, vector search, and other metered APIs will fail with 402 responses.
Once credits are loaded you can generate an API key (or use session tokens) and create a client:
π‘ The Registry Broker production API is available at
https://registry.hashgraphonline.com/api/v1. OverridebaseUrlonly if youβve been provisioned a private deployment.
Creating a clientβ
import { RegistryBrokerClient } from '@hashgraphonline/standards-sdk';
const client = new RegistryBrokerClient({
// Optional: override the default https://registry.hashgraphonline.com/api/v1
baseUrl: process.env.REGISTRY_BROKER_API_URL,
// Optional: supply an API key issued by your Registry Broker instance
apiKey: process.env.REGISTRY_BROKER_API_KEY,
});
baseUrlβ defaults to the production broker (https://registry.hashgraphonline.com/api/v1). Trailing slashes and missing/api/v1segments are normalized automatically.apiKeyβ when provided, the client sets anx-api-keyheader on every request. You can update it later withclient.setApiKey(newKey).defaultHeadersβ useclient.setDefaultHeader(name, value)to add or remove headers after instantiation (values are trimmed; falsy values remove the header).fetchImplementationβ pass a custom fetch (for Cloudflare Workers, Node polyfills, testing, etc.).
const client = new RegistryBrokerClient({
fetchImplementation: (input, init) => myInstrumentationFetch(input, init),
defaultHeaders: {
'x-trace-id': crypto.randomUUID(),
},
});
You can inspect the current header set with client.getDefaultHeaders().
Quickstart: Paid OpenRouter chat relayβ
import { RegistryBrokerClient } from '@hashgraphonline/standards-sdk';
const client = new RegistryBrokerClient({
baseUrl: 'https://registry.hashgraphonline.com/api/v1',
apiKey: process.env.REGISTRY_BROKER_API_KEY,
});
const session = await client.chat.createSession({
agentUrl: 'openrouter://anthropic/claude-3.5-sonnet',
auth: { type: 'bearer', token: process.env.OPENROUTER_API_KEY! },
});
const reply = await client.chat.sendMessage({
sessionId: session.sessionId,
message: 'Give me a one-line summary of your pricing.',
auth: { type: 'bearer', token: process.env.OPENROUTER_API_KEY! },
});
console.log(reply.message);
If you omit the auth block for paid models, the broker returns a 401 from the adapter. Free-tier models do not require this step.
Architecture Overviewβ
The SDK mediates every request, ensuring headers and schemas are applied consistently. Credits purchased in the billing portal authorize metered endpoints; without an active balance, the broker returns 402 responses.
Searching the Registryβ
Keyword searchβ
import type { SearchResult } from '@hashgraphonline/standards-sdk';
const result: SearchResult = await client.search({
q: 'custody agent',
registry: 'hol',
capabilities: ['messaging'],
minTrust: 70,
page: 1,
limit: 25,
});
console.log(`Found ${result.total} agents`);
for (const hit of result.hits) {
console.log(hit.name, hit.registry, hit.capabilities);
}
SearchParams supports q, page, limit, registry, minTrust, and capability filtering (capabilities can be AIAgentCapability enum values or arbitrary strings).
Vector searchβ
The broker also exposes embedding-powered search:
const vectorResult = await client.vectorSearch({
query: 'tax strategy assistant for small businesses',
limit: 10,
filter: {
capabilities: ['financial-services'],
registry: 'hol',
},
});
vectorResult.hits.forEach(hit => {
console.log(hit.agent.name, hit.score);
});
The optional filter can constrain results by capability, registry, agent type, or protocol.
Registry-specific namespace searchβ
const namespaceSearch = await client.registrySearchByNamespace('hol', 'fraud');
namespaceSearch.hits.forEach(hit => {
console.log(`${hit.registry}: ${hit.name}`);
});
This is useful when you want to query adapters that expose their own internal namespaces (for example, Hol or Virtuals).
Discovery Insightsβ
-
Registries & Popular Searches
const registries = await client.registries(); // { registries: string[] }
const popular = await client.popularSearches(); // { searches: string[] } -
Snapshot stats
const stats = await client.stats();
console.log(stats.totalAgents, stats.registries); -
Operational metrics
const metrics = await client.metricsSummary();
console.log(metrics.search.queriesTotal, metrics.websocket.connections);
const websocket = await client.websocketStats();
const dashboard = await client.dashboardStats();
These responses are strongly typed and validated, making them safe to expose in dashboards without additional schema definitions.
Working With UAIDsβ
The client includes helpers for dealing with agent UAIDs:
const resolved = await client.resolveUaid('uaid:aid:123...');
console.log(resolved.agent.name);
const validation = await client.validateUaid('uaid:aid:123...');
console.log(validation.valid, validation.formats);
const status = await client.getUaidConnectionStatus('uaid:aid:123...');
if (!status.connected) {
console.log('Agent offline');
}
await client.closeUaidConnection('uaid:aid:123...');
Each method returns the appropriate schema-backed response (UaidValidationResponse, UaidConnectionStatus).
Chat Sessionsβ
The chat namespace exposes a conversation relay with the brokerβs chat worker:
const session = await client.chat.createSession({ uaid: 'uaid:aid:123...' });
const reply = await client.chat.sendMessage({
sessionId: session.sessionId,
message: 'Hello from the SDK!',
streaming: false,
});
console.log(reply.content);
await client.chat.endSession(session.sessionId);
You can also seed the chat by agent URL instead of UAID ({ agentUrl: 'https://...' }). The streaming flag is passed through to the broker; if the backend supports streaming, you can adapt the response accordingly.
Passing downstream auth (paid OpenRouter models)β
Many adapters (notably OpenRouter) require user-provided credentials for paid tiers. Supply the downstream token with the auth block so the relay can authenticate on your behalf.
const session = await client.chat.createSession({
agentUrl: 'openrouter://anthropic/claude-3.5-sonnet',
auth: {
type: 'bearer',
token: process.env.OPENROUTER_API_KEY!, // the user's key, not the broker's
},
});
const response = await client.chat.sendMessage({
sessionId: session.sessionId,
message: 'Summarize your pricing in one sentence.',
auth: {
type: 'bearer',
token: process.env.OPENROUTER_API_KEY!,
},
});
AgentAuthConfig supports four schemes:
type | Fields used | Example |
|---|---|---|
bearer | token | { type: 'bearer', token: 'sk-or-...' } |
basic | username, password | { type: 'basic', username, password } |
apiKey | headerName, headerValue | { type: 'apiKey', headerName: 'x-api-key', headerValue: '...' } |
header | headerName, headerValue, optional headers map | Use for bespoke header names or multi-header payloads |
When you set auth, the broker caches the normalized header set and reuses it for the session (updating the downstream client if subsequent requests provide different credentials). Omit auth for free models or agents that do not require authentication.
Agent Registrationβ
Registering an agent is a single call that expects a fully-formed HCS-11 profile:
import type { HCS11Profile } from '@hashgraphonline/standards-sdk';
const profile: HCS11Profile = {
version: '1.0.0',
type: 1,
display_name: 'Ledger Guard',
bio: 'Monitoring transactions for anomalies',
aiAgent: {
type: 'openai',
model: 'gpt-4o-mini',
capabilities: ['monitoring', 'compliance'],
},
};
const registration = await client.registerAgent({
profile,
registry: 'hol',
protocol: 'aid',
endpoint: 'https://ledger-guard.example.com',
metadata: {
trustScore: 92,
uptime: 99.95,
},
});
console.log(registration.uaid, registration.agent.nativeId);
The response supplies UAID, agent metadata, optional HCS-10 registry results, and OpenConvAI compatibility data when available.
Protocol Discoveryβ
const protocols = await client.listProtocols(); // { protocols: string[] }
const detected = await client.detectProtocol({
message: {
headers: { 'content-type': 'application/json' },
body: '{"hello":"world"}',
},
});
console.log(detected.protocol); // e.g. "aid"
Use this to guess which adapter or protocol an incoming payload belongs to before routing it.
Handling Errorsβ
All HTTP failures throw RegistryBrokerError; schema validation issues throw RegistryBrokerParseError.
try {
await client.search({ registry: 'unknown' });
} catch (error) {
if (error instanceof RegistryBrokerError) {
console.error('Broker rejected the request', error.status, error.body);
} else if (error instanceof RegistryBrokerParseError) {
console.error('Unexpected response shape', error.cause);
} else {
throw error;
}
}
Both error classes expose contextual data so you can log or retry intelligently.
Advanced: Custom Fetch Pipelinesβ
The client is fetch-agnostic. You can instrument every request (for retries, auth rotation, tracing) by wrapping a fetch implementation:
const client = new RegistryBrokerClient({
fetchImplementation: async (input, init) => {
const start = performance.now();
const response = await fetch(input, init);
console.log(`[registry-broker] ${new URL(input as string).pathname} -> ${response.status} in ${performance.now() - start}ms`);
return response;
},
});
Example: Discover and Chatβ
const client = new RegistryBrokerClient({ apiKey: process.env.RB_API_KEY });
// 1. Find high-trust audit agents
const auditAgents = await client.search({ q: 'audit', minTrust: 80, limit: 5 });
// 2. Ask the top result a question
const topAgent = auditAgents.hits[0];
const session = await client.chat.createSession({ uaid: topAgent.uaid });
await client.chat.sendMessage({ sessionId: session.sessionId, message: 'Summarize your capabilities.' });
This flow demonstrates how the SDK threads the brokerβs discovery, chat, and UAID utilities into a single toolkit.
Referenceβ
All return types are exported from @hashgraphonline/standards-sdk/services/registry-broker:
SearchResult,RegistryStatsResponse,PopularSearchesResponseCreateSessionResponse,SendMessageResponseRegisterAgentResponse,ProtocolsResponse,DetectProtocolResponseRegistrySearchByNamespaceResponse,VectorSearchResponseWebsocketStatsResponse,MetricsSummaryResponse,DashboardStatsResponseUaidValidationResponse,UaidConnectionStatus
Check the source for the latest schemas and helper utilities.
With the Registry Broker client you can wire up agent discovery, registration, chat, and monitoring in a handful of lines while relying on the Standards SDK to validate every response.