# TypeScript SDK

The TypeScript SDK is a strong fit for Node services, developer platforms, and browser-adjacent tooling that need ZeroID admin and token workflows.

It uses a resource-based `ZeroIDClient` with fetch-based transport and typed request and response models.

### Choosing the Right Method

| I want to...                                          | Use                                                                    |
| ----------------------------------------------------- | ---------------------------------------------------------------------- |
| Register a new agent                                  | `client.agents.register()`                                             |
| Get an access token from an API key                   | `client.tokens.issue({ grant_type: "api_key", ... })`                  |
| Verify a token fast (no network, no revocation check) | `client.tokens.verify()`                                               |
| Verify a token and check for revocation               | `client.tokens.session()`                                              |
| Verify from a raw `Authorization: Bearer ...` header  | `client.tokens.verifyBearer()` or `client.tokens.sessionFromRequest()` |
| Delegate authority to a sub-agent                     | `client.tokens.delegate()`                                             |
| Check if a token is still active (online)             | `client.tokens.introspect()`                                           |
| Invalidate a token                                    | `client.tokens.revoke()`                                               |
| Manage credential lifecycle from admin tooling        | `client.credentials`                                                   |
| Ingest a CAE signal                                   | `client.signals.ingest()`                                              |

### verify() vs session()

|                                     | `tokens.verify()`      | `tokens.session()`                           |
| ----------------------------------- | ---------------------- | -------------------------------------------- |
| Network call                        | No — uses cached JWKS  | Yes — calls introspection endpoint           |
| Reflects revocation                 | Not until JWKS rotates | Immediately                                  |
| Latency                             | \~1ms (local)          | \~20–50ms (network)                          |
| Returns                             | `ZeroIDIdentity`       | `AgentSession`                               |
| `requireScope()` / `requireTrust()` | No                     | Yes                                          |
| Use when                            | Service mesh, hot path | Public API boundary, high-security decisions |

### Installation

```bash
npm install @highflame/sdk
```

### Create a Client

```typescript
import { ZeroIDClient } from "@highflame/sdk";

const client = new ZeroIDClient({
  baseUrl: "http://localhost:8899",
  accountId: "acct-demo",
  projectId: "proj-demo",
});
```

For quick local experiments, `accountId` and `projectId` can be omitted and the client will generate them automatically.

### Available Resources

Current TypeScript resources:

* `client.identities`
* `client.agents`
* `client.oauthClients`
* `client.credentialPolicies`
* `client.apiKeys`
* `client.tokens`
* `client.signals`
* `client.credentials`

### Register an Agent

```typescript
const registered = await client.agents.register({
  name: "Billing Orchestrator",
  external_id: "billing-orchestrator",
  sub_type: "orchestrator",
  trust_level: "first_party",
  created_by: "dev@company.com",
});

console.log(registered.identity.wimse_uri);
console.log(registered.api_key);
```

### Exchange an API Key for a Token

```typescript
const token = await client.tokens.issue({
  grant_type: "api_key",
  api_key: registered.api_key,
});

console.log(token.access_token);
console.log(token.expires_in);
```

If the client itself was initialized with `apiKey`, the SDK can also cache that access token internally for later delegation workflows.

### Introspect and Revoke

```typescript
const info = await client.tokens.introspect(token.access_token);

console.log(info.active);

await client.tokens.revoke(token.access_token);
```

### Delegate to a Sub-Agent

When the client was initialized with an API key, the TypeScript client can exchange the cached token automatically:

```typescript
const client = new ZeroIDClient({
  baseUrl: "http://localhost:8899",
  apiKey: "zid_sk_...",
  accountId: "acct-demo",
  projectId: "proj-demo",
});

const delegated = await client.tokens.delegate({
  actor_token: actorToken,
  scope: "data:read",
});
```

### Verify a Token Locally

Use `tokens.verify()` or `tokens.verifyBearer()` to validate a JWT using ZeroID's JWKS without a network round-trip to the introspection endpoint.

{% hint style="info" %}
**Use `verify()` when** you need low latency and can tolerate a brief window where a revoked token still passes (until the next JWKS rotation). Ideal for service-to-service calls inside a trust boundary.
{% endhint %}

```typescript
// From a raw token string
const identity = await client.tokens.verify(token.access_token);

// From an Authorization header value
const identity = await client.tokens.verifyBearer(request.headers.authorization);

console.log(identity.sub);
console.log(identity.trust_level);
```

The returned `ZeroIDIdentity` object includes helper methods:

```typescript
identity.hasScope("data:read");   // boolean
identity.hasTool("bash");         // boolean
identity.isDelegated();           // boolean — true if act.sub is present
identity.delegatedBy();           // string | undefined — the orchestrator sub
```

### Session Verification (Introspection-Based)

Use `tokens.session()` or `tokens.sessionFromRequest()` for an online check that reflects the latest revocation state.

{% hint style="info" %}
**Use `session()` when** you need immediate revocation awareness. It makes a network call to the introspection endpoint. `requireScope()` and `requireTrust()` (which throw on failure) are only available on `AgentSession`, not on `ZeroIDIdentity`.
{% endhint %}

```typescript
// From a raw token string
const session = await client.tokens.session(token.access_token);

// From request headers (reads the Authorization: Bearer ... header)
const session = await client.tokens.sessionFromRequest(request.headers);

if (!session.active) {
  // token revoked or expired
}

session.hasScope("data:read");         // boolean
session.requireScope("data:read");     // throws if scope missing
session.isDelegated();                 // boolean
session.delegatedBy();                 // string | undefined
session.requireTrust("first_party");   // throws if trust level below minimum
```

### Credentials Resource

TypeScript currently exposes a direct `credentials` resource, which is useful when you need more explicit control over credential lifecycle from admin workflows.

That is helpful for:

* internal control planes
* admin tooling
* integration tests

### Recommended Usage Pattern

For TypeScript services:

1. Create one client instance per service context
2. Use explicit tenant IDs outside local development
3. Use typed resource calls rather than hand-built fetch wrappers
4. reserve direct REST calls for features not yet wrapped


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.highflame.ai/api-reference/sdk/zeroid/typescript-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
