Your software said it worked.
Did it?

A function can execute, an API can return 200, and an agent can report "done" — without the intended outcome actually being true. DidWork independently verifies software outcomes.

import { did } from "@didwork/sdk";

const result = await did.verify({
  type: "stripe.refund",
  expected: { payment: "pi_123", amount: 4999 }
});

if (result.status === "verified") proceed();
Claimwhat your software asserts
Evidenceindependently gathered
VERIFIED FAILED UNKNOWN

Execution is not outcome

Modern software runs through agents, background jobs, third-party APIs, and async workflows. Every layer is a chance to believe something happened when it didn't.

The refund that wasn't

The API returned 200 — but the wrong amount was refunded, or it was refunded twice. stripe.refund checks the authoritative payment state.

The agent that said "done"

An agent's assertion is not evidence. DidWork checks the systems that can actually prove the outcome — the agent doesn't grade its own work.

Closed is not merged

A PR can close without merging. A workflow can complete without passing. github.pr_merged knows the difference.

Accepted is not delivered

The email provider took the message — that proves nothing about delivery. email.delivered waits for the terminal event, and says UNKNOWN until then.

Uncertainty over false certainty

Every verification ends in one of three verdicts. UNKNOWN is first-class: when evidence can't be gathered — provider down, record not visible, outcome not yet decidable — DidWork refuses to guess. When it says VERIFIED, that has to be true.

Claim typeVerifies
stripe.refundRefund exists, succeeded, right amount and currency, no duplicates
stripe.subscription_cancelledActually cancelled — scheduled-at-period-end fails
stripe.payment_succeededPayment succeeded for the right amount
github.pr_mergedMerged, not merely closed; optional merge-commit check
github.workflow_passedRun completed with success; in-progress is UNKNOWN
github.issue_closedIssue (not a PR) is closed
email.deliveredDelivered to the intended recipient; accepted ≠ delivered

Built for the way software fails now

One primitive

did.verify() — the same call whether the action came from an agent, a cron job, a webhook, or ordinary application code.

Async by default

Pass wait: false for a pending verification, then poll — or receive an HMAC-signed verification.completed webhook.

Evidence preserved

Claim, evidence, and verdict are stored separately on every verification — an audit trail for what your software actually did.

Read-only by design

Adapters only need read access to your providers. DidWork proves outcomes; it never needs the power to cause them.