---
title: SDK
description: @tollrelay/sdk signs every outbound request and checks the mandate as a courtesy before it leaves.
canonical: https://tollrelay.com/docs/sdk
lastmod: 2026-09-23
---

# SDK

@tollrelay/sdk signs every outbound request and checks the mandate as a courtesy before it leaves.

```sh
npm install @tollrelay/sdk
```

## signedFetch

A fetch wrapper. It signs the request per RFC 9421, checks the mandate as a courtesy, and sets the interim identity header.

```ts
import { signedFetch } from "@tollrelay/sdk";

const call = signedFetch({
  key: { keyid: "did:web:acme#agent-1", privateKey: machine.private_key },
  mandate: { usd_per_day: "10.000", sellers_allow: ["seller.example.com"] },
  identityToken: identity.token,
});

const response = await call("https://seller.example.com/quote", {
  method: "POST",
  body: JSON.stringify({ sku: "abc" }),
});
```

## signRequest

The signing primitive under the wrapper, for a caller that sets its own headers.

```ts
import { signRequest } from "@tollrelay/sdk";

const headers = await signRequest({
  method: "POST",
  url: "https://seller.example.com/quote",
  body: JSON.stringify({ sku: "abc" }),
  key: { keyid: "did:web:acme#agent-1", privateKey: machine.private_key },
});
```

## What is signed

Covered components: `@method`, `@authority`, `@path`, `content-digest`. Algorithm `ed25519`, digest `sha-256` (RFC 9530), signature label `trlay`. The signature expires 30 seconds after it is created.

A seller checks the signature against the agent's public key, published at `https://api.trlay.dev/.well-known/jwks.json`.

## The courtesy check

The mandate check the SDK runs before a request leaves is a courtesy: it spares the agent a call the seller would refuse. It is never the control. The seller's gate enforces the mandate, and the wallet enforces the spend.

## The interim identity header

`X-Trlay-Identity` carries the identity token until the credential travels in each rail's own slot.
