API reference

Read-only JSON API.

37 operations on 33 paths, generated from the OpenAPI 3.1 document on every build. No key. CORS open. Every response carries a provenance stamp.

Base URL
https://api.diditwork.org
Format
JSON; errors are JSON with an error code and a hint
Writes
None. The only POST routes are the MCP endpoint and a no-charge giving-intent deep link
Same rules as MCP
Every MCP tool calls the matching GET /v1/* handler. How to quote us applies to both

Three calls to start with

shell
curl -s https://api.diditwork.org/v1/meta
curl -s 'https://api.diditwork.org/v1/recommend?outcome=lives_saved&limit=3'
curl -s https://api.diditwork.org/v1/claims/eval_gw_amf__0

Contents

Service

GET/

API landing (name, version and where to go next) · Open

GET/health

Health and trust of the API surface · Open

GET/openapi.yaml

This OpenAPI document (machine-readable contract) · Open

POST/mcp

MCP endpoint (Streamable HTTP, JSON-RPC 2.0, read-only tools)

ParameterInRequiredNotes
MCP-Protocol-VersionheadernoOne of: 2026-07-28, 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05
Mcp-MethodheadernoRequired (and validated against the body) for protocol 2026-07-28.
Mcp-Nameheadernotools/call tool name; required for protocol 2026-07-28 (base64 sentinel accepted).

GET/mcp

GET is not supported (POST-only Streamable HTTP endpoint; no SSE stream) · Open

Meta and provenance

GET/v1/meta

API version, build time, catalog counts, and discovery links · Open

GET/v1/meta/snapshot

Reproducibility / audit snapshot (data + code identity) · Open

Organizations

GET/v1/orgs

List organizations / programs / funds · Open

ParameterInRequiredNotes
entity_typequerynoOne of: organization, program, fund, evaluator_vehicle
recommendation_tierqueryno
cause_idqueryno
qquerynoFree-text search over name, tags, summary (max 256; path traversal refused)
idsquerynoComma-separated org ids (empty → empty list; unknown → missing; never invent)
limitquerynoMax rows to return (1..500); oversized → 400

GET/v1/orgs/{id}

Get one org by stable id

ParameterInRequiredNotes
idpathyes e.g. org_against_malaria_foundation

Recommendations

GET/v1/recommend

Conviction-ranked orgs for an outcome family · Open

ParameterInRequiredNotes
values_profile_idquerynoLoad preset from data/values_profiles/{id}.json. e.g. vp_lives_no_deworm
outcomequerynolives_saved | wellbeing_wellbys | income (aliases accepted). e.g. lives_saved
outcome_preferencequerynoAlias for outcome (values-profile field name)
budget_usdqueryno e.g. 1000
riskquerynoOne of: low, medium, high
geographyqueryno e.g. Kenya
require_geographyqueryno
taxquerynoOne of: us_501c3_preferred, us_deductible, any
red_linesquerynoComma-separated cause ids or tags to exclude e.g. cause_deworming
non_cashquerynoPrefer orgs with non_cash_giving options
limitqueryno

POST/v1/recommend

Same as GET with optional inline values_profile

Compare

GET/v1/compare

Side-by-side claims, tiers, and trust for two or more orgs · Open

ParameterInRequiredNotes
idsqueryyes e.g. org_against_malaria_foundation,org_malaria_consortium

Outcomes

GET/v1/outcomes

Outcome families (separate boards; no cross-unit mix) · Open

ParameterInRequiredNotes
outcomequerynoOptional family filter (lives_saved | wellbeing_wellbys | income; aliases accepted). e.g. lives_saved
idsquerynoOptional comma-separated family ids. e.g. lives_saved,income

GET/v1/outcomes/{id}

Single outcome family by id

ParameterInRequiredNotes
idpathyesOutcome-family id (allowlisted) e.g. lives_saved

Leaderboards

GET/v1/leaderboards

Per-outcome-family frozen leaderboards · Open

ParameterInRequiredNotes
outcomequerynoOptional family filter (lives_saved | wellbeing_wellbys | income; aliases accepted). e.g. lives_saved

GET/v1/leaderboards/{id}

Single per-outcome-family leaderboard by board id

ParameterInRequiredNotes
idpathyesOutcome-family board id (allowlisted) e.g. lives_saved

Claims

GET/v1/claims

Read-only flat claims index · Open

ParameterInRequiredNotes
org_idqueryno e.g. org_against_malaria_foundation
evaluation_idqueryno e.g. eval_gw_amf
verifiedquerynoIf true/false, filter on claim.verified e.g. true

GET/v1/claims/{id}

Get one claim by claim_id

ParameterInRequiredNotes
idpathyes e.g. eval_gw_amf__0

Outcome ledger

GET/v1/ledger

Outcome ledger ("Did it work?") v0 — read-only, append-only, hash-chained · Open

ParameterInRequiredNotes
org_idqueryno e.g. org_against_malaria_foundation
evaluatorquerynoOne of: givewell, hli, ace, who, ihme
statusquerynoOne of: pending, confirmed, contradicted, unverifiable
intervention_idqueryno e.g. int_itn
record_kindquerynoOne of: claim_snapshot, follow_up_result

GET/v1/ledger/{id}

One outcome-ledger record (+ its follow-up results)

ParameterInRequiredNotes
idpathyes e.g. ldg_eval_gw_amf__0

Values profiles

GET/v1/values-profiles

Read-only values preset catalog · Open

GET/v1/values-profiles/{id}

Get one values preset by id

ParameterInRequiredNotes
idpathyes e.g. vp_lives_no_deworm

Impact estimates (modeled)

GET/v1/impact-estimate

Modeled gift outcomes (not guaranteed) · Open

ParameterInRequiredNotes
org_idqueryyes e.g. org_against_malaria_foundation
gift_usdqueryyes e.g. 1000

Portfolio (modeled)

GET/v1/portfolio/allocate

Suggest a conviction-weighted portfolio + modeled impact · Open

ParameterInRequiredNotes
budget_usdqueryyes e.g. 10000
outcomequeryyes e.g. lives_saved
top_nqueryno
methodqueryno
red_linesquerynoComma-separated cause ids/tags to exclude
riskqueryno
geographyqueryno
taxqueryno
include_fundsqueryno

POST/v1/portfolio/allocate

Same as GET with optional inline values_profile

Giving intents (no charge)

GET/v1/giving/intent

NO-CHARGE deep-link donate handoff · Open

ParameterInRequiredNotes
org_idqueryyes e.g. org_against_malaria_foundation
amount_usdqueryyes e.g. 100
vehiclequerynodirect_cash | daf | stock | crypto | qcd (non-cash handoffs)
values_profile_idqueryno
include_impactqueryno
intent_idqueryno

POST/v1/giving/intent

Same as GET with JSON body

Interventions

GET/v1/interventions

Interventions catalog (live only) · Open

ParameterInRequiredNotes
cause_idqueryno e.g. cause_malaria
idsqueryno
limitqueryno

GET/v1/interventions/{id}

Get one live intervention by id

ParameterInRequiredNotes
idpathyes e.g. int_smc

Evaluations

GET/v1/evaluations/{id}

Get one evaluation by id

ParameterInRequiredNotes
idpathyes e.g. eval_gw_amf

Trust

GET/v1/trust/{org_id}

Trust flags for an org

ParameterInRequiredNotes
org_idpathyes e.g. org_against_malaria_foundation

Causes

GET/v1/causes

Cause catalog (list) · Open

ParameterInRequiredNotes
phasequerynolive|active|future|all (default all)
idsquerynoComma-separated cause ids (allowlist cause_[a-z0-9_]+)
limitquerynoOptional positive slice; invalid/oversized ignored

GET/v1/causes/{id}

Cause detail by id

ParameterInRequiredNotes
idpathyes e.g. cause_malaria

Review queue

GET/v1/review/queue

Human exception-review queue (read-only) · Open

ParameterInRequiredNotes
statusquerynoopen|approved|rejected|all (default open when omitted; empty → 400)

GET/v1/review/queue/{id}

Single exception-review queue item (read-only)

ParameterInRequiredNotes
idpathyes e.g. exc_20261001_actra_donate

Tax status (not advice)

GET/v1/tax/{org_id}

Sanitized trust/tax-status summary (not tax advice)

ParameterInRequiredNotes
org_idpathyes e.g. org_against_malaria_foundation

More detail

Full request and response schemas are in the OpenAPI document. Worked examples: how to query the API and the agent playbook.