Skip to content

First recipes

Each recipe is a whole program you can paste and run. None of them needs an account or an API key. Each one ends in a single yes-or-no decision, and shows what to do with every other answer.

You want to… Call Accept only
Accept a partner’s DID POST /v1/policies/evaluate PASS
Accept a credential POST /v1/credentials/verify requirements.met (VALID and every condition SATISFIED)
Allow an agent’s tool call POST /v1/agents/authorize ALLOW

The SDKs (@didis/client 0.2.4 and didis-py 0.2.4 or later) wait and retry automatically when the free rate limit answers 429, so these programs also work in a loop. With curl, wait for the number of seconds in Retry-After before sending again.

Task. A supplier gives you did:web:supplier.example. Accept it only if it is published from its own domain over a valid certificate and its website links back to it.

Terminal window
curl -s -X POST https://did.is/api/v1/policies/evaluate \
-H 'content-type: application/json' \
-d '{"did":"did:web:did.is","policy":{"name":"partner","rules":{"didResolution":"required","allowedMethods":["web","webvh"],"domainBinding":"required","tlsMinDaysRemaining":14}}}' \
| jq '{status: .evaluation.status, headline: .evaluation.headline, failed: [.evaluation.evaluations[] | select(.status != "PASS") | .message]}'

Replace did:web:did.is with your partner’s DID. A PASS shows the identifier is controlled from that domain; it does not show who owns the domain. More rules: Policies.

Task. A user presents a verifiable credential. Accept it only if the issuer’s key signed it, it is current and not revoked, and it states that the holder is over 18.

Terminal window
curl -s -X POST https://did.is/api/v1/credentials/verify \
-H 'content-type: application/json' \
-d '{"credential": "<JWT, SD-JWT VC or JSON credential>", "requiredClaims": [{"path": "/age_over_18", "equals": true}]}' \
| jq '{status, headline, met: .requirements.met, requirements: .requirements.results}'

NOT_DISCLOSED means the holder chose not to reveal that claim; ask again rather than reject outright. Claim values are never echoed back. Decide separately which issuers you accept. More: Credentials.

Task. An AI agent wants to call payments.refund. Allow it only if a chain of signed delegation receipts leads back to an organization you trust.

Terminal window
curl -s -X POST https://did.is/api/v1/agents/authorize \
-H 'content-type: application/json' \
-d '{"chain": ["<root receipt>", "<leaf receipt>"], "tool": "payments.refund", "trustedRoots": ["did:web:bank.example"]}' \
| jq '.authorization | {decision, reason}'

Call it before the tool runs and stop on anything other than ALLOW. An empty or broken chain is always denied with a reason. Delegation receipts are an experimental DID.is format. To wrap tools automatically, see Guard agent tools.

Every error is a problem object with a stable code. The SDKs raise DidisError; read status, problem.code and problem.detail. See Errors and rate limits for every code.