DelegusDocsv0.3 rc1

Docs/Integrate

Getting started

Integrate Delegus as a relying party

This page is for the engineer whose service is about to receive an action from an AI agent it has never seen. It describes the integration surface that the v0.3 release candidate of the protocol specifies (profile delegus-base-v3). v0.3 is the current release candidate, so details can still change; nothing here is a measured figure or a guarantee.

Availability. The production API at api.delegus.ai is serving. Sign up for a verify key: the sandbox is free with no card, and production starts with a 14-day free trial; the quickstart walks through your first signed decision.

What arrives with the request#

An agent acting for a company sends two extra headers with its HTTP request:

HeaderContentsSigned by
Delegus-GrantThe Grant: what this agent may do, for which company, until when. Spec §3.The company (the Principal), with a key in its DID document
Delegus-ProofA Proof bound to this Grant, this recipient, this exact action, and this moment. Spec §4.The agent

You do not parse either. You forward them, together with your own description of the action, to Delegus.

Install#

bash
npm install @delegus/sdk

The SDK bundles the CLI (npx delegus) and pulls in the pure engine @delegus/core. Both are Apache-2.0.

Use @delegus/sdk 0.2.0 or later: it is the first release that carries v0.3 (protocol: "v0.3", the opening and commitment checks, and "auto" as the default). 0.1.4 has none of it.

The one call#

This is the complete relying-party integration as spec §15 gives it:

ts
import { Delegus } from "@delegus/sdk";
const delegus = new Delegus({ apiKey: process.env.DELEGUS_API_KEY, publicBaseUrl: "https://seller.example" });

app.post("/orders", async (req, res) => {
  const d = await delegus.verify({
    grant: req.header("Delegus-Grant"),
    proof: req.header("Delegus-Proof"),
    action: { type: "commerce:purchase", resource: req.body.orderId, amount: req.body.amountMinor, currency: req.body.currency },
    request: { method: req.method, path: req.path },
  });
  if (d.decision !== "ALLOW") return res.status(403).json({ reason: d.reason });
  // proceed; persist d.receipt with the order
});

The Proof carries the method and URL the agent signed for (spec §4). /verify doesn't compare them with your request; the SDK does, before it calls Delegus Check, when you pass request, and throws ProofBindingError on a mismatch. publicBaseUrl is the origin the agent addressed; the SDK joins request.path to it. amount is an integer in minor units; the protocol never uses decimals.

What comes back#

decision is ALLOW or DENY. On DENY, reason is the first check that failed, in the fixed order the profile document lays down, for example GRANT_EXPIRED, AUTHORITY_REVOKED, PROOF_REPLAYED or AMOUNT_EXCEEDS_AUTHORITY. The full list and its order are in the delegus-base-v3 profile and spec §5. The profile is published at /profiles/delegus-base-v3.

v0.3 specifies that Delegus Check fails closed: an unknown, missing, ambiguous or unavailable input is a DENY, never an ALLOW. If Delegus itself cannot answer, the SDK surfaces SERVICE_UNAVAILABLE, and your service decides what to do with a request it could not verify.

Some answers come back before any check runs. They're refusals rather than decisions, so there's no receipt, and the agent's Proof isn't spent; the same Proof works once the cause is fixed. The SDK throws them as DelegusApiError with the HTTP status and the code.

HTTPerrorMeaning
403RP_UNVERIFIEDYour relying party is on your own domain, and that domain is not verified for your organization. See Verify your domain.
403RP_SUSPENDEDDelegus has suspended your relying party or marked it disputed. Write to hello@delegus.ai.

On v0.3 the response also carries, beside the receipt and outside its signature, the matched authority in plain form and the values that tie it to the receipt. The SDK checks that they match what the receipt pins and throws ResponseIntegrityError if they do not; do not act on such a response. The fields are authority (the authority that matched), authority_opening and, for a Grant with a budget, capability_key_opening; the receipt pins them as authority_commitment and evidence.consumption.capability_key_commitment (spec §5.6, §6.2).

Keep the receipt#

Every decision, ALLOW and DENY alike, comes with a signed Decision Receipt (spec §6). It pins hashes of the Grant, the request, the authority that matched, the company's DID document as it stood, the revocation list as it stood, the profile that was applied, and the evaluation time. Store it with the order. You can also list and search your decisions later with GET /decisions (newest first, filters by time, decision, reason, Principal or Grant). Anyone holding the receipt can check that it is authentic and unchanged without calling Delegus. Checking what it pins against the preserved artifacts (spec §8) is open to the receipt's relying party and Principal; re-evaluating the checks themselves offline is not available yet.

Before you can call it#

If you are the company issuing Grants#

On the other side of the protocol is the Principal, the company whose agent acts. v0.3 specifies that it proves control of its domain (spec §2.1), signs Grants with a key in its DID document (spec §3), and can revoke a Grant at any moment (spec §7). A Principal on your own did:web is registered only after your organization has started a claim on that domain, and its Grants pass the domain check only while the claim is verified; see Verify your domain. The SDK's delegus.org.create(), agent.create() and grant.create() cover that path (spec §15).

The four outcomes, step by step#

Take one order from one agent and watch Delegus Check answer it four ways. You mint a Grant and a Proof, and the first verify comes back ALLOW. Send the same Proof again and it's PROOF_REPLAYED. Mint an order over the limit and it's AMOUNT_EXCEEDS_AUTHORITY. Revoke the Grant, verify the first pair again, and it's AUTHORITY_REVOKED.

That last one is why revocation is checked at P6, before the replay write at T5. A revoked Grant denies as revoked even when its Proof was already used. To run these steps yourself, get a free sandbox key and follow the quickstart.