The organisation declared this destination. A human at the nonprofit affirmed it, verbatim, and that affirmation is stored in the file.
The nonprofit says where its money may go.
An AI agent asked to donate routes to whatever it can parse. Today that is structurally never the nonprofit. VGP is one file, on the one domain the organisation controls, saying where its money may go.
- 01 Draft it here. The generator fills in the structure and checks it against the schema as you type.
- 02 A human at the nonprofit authorises each destination. Typed verbatim, off the machine. This step has no tooling and cannot be automated.
- 03 Hand it to your developer, or your local AI. It is one static file, served at /giving.json on your own domain.
How an agent should see a donation page.
The same argument, watchable. What an agent finds on a donation page now, what it finds once the nonprofit has declared where its money may go, and why that call should be the nonprofit's.
Figure 01 · served from youtube-nocookie.com, which sets no tracking cookie until the video is played.
{
"vgp_version": "0.1",
"canonical_domain": "example.org",
"organization": {
"legal_name": "Example Foundation",
"ein": "12-3456789",
"country": "US"
},
"giving": {
"authorized_destinations": [{
"id": "direct-card",
"type": "credit_card",
"recipient": "Example Foundation",
"authorization": {
"status": "authorized",
"approved_by_role": "Executive Director",
"approved_at": "2026-08-26T00:00:00Z",
"statement": "Our organization authorizes
donations through this destination."
}
}]
},
"verification": {
"organization_approved": true
}
} Figure 02 · an approved declaration and the two states a consumer may report. Ink 3 marks authorisation and appears nowhere else in this system.
How an agent reaches it.
Once the file is served, nothing else has to be built. This is the whole path a donation takes when the agent can read what the nonprofit declared.
“Donate $50 to wildfire relief.”
nonprofit.org/giving.json
Anything the organisation did not declare is not there to route to.
And arrives as the nonprofit’s donor, not a stranger’s.
Figure 03 · the route a declared donation takes. Step 03 is the protocol; the rest is ordinary web.
Without a declaration, step 02 has nothing to read and the agent guesses. It lands on whatever it can parse — an outdated page, a form it cannot complete, or a third-party page raising money on a nonprofit’s behalf without its express permission. Those pages keep the donor: the name, the email, the relationship. The organisation gets a cheque months later, and never meets the person who gave.
Why this is the shipping container momentWhat an agent can actually read.
A real donation page: powerpoetry.org/donate. Nothing about it changes for a human. The difference is what an agent has to work with when it gets there.
<iframe src="https://givebutter.com
/embed/c/donate-power-poetry">
</iframe> A cross-origin payment widget. The agent cannot read inside it, cannot see what it charges, and cannot tell who receives the money. What is left is the prose around it, so the agent does what it always does: it guesses, or it leaves for a page it can parse — which may be one nobody at the nonprofit authorised.
giving_verify who this organisation is
giving_options destinations it authorized
giving_designations funds it accepts
giving_prepare builds a URL; never charges Four described, schema-typed tools the agent discovers automatically. It no longer reads a page; it asks a question and gets the organisation’s own answer. Two lines in the page’s HTML do this. The declaration was the hard part, and it is done.
Figure 04 · the same donate page before and after publishing a declaration. Ink 3 marks the side where an authorised destination exists to route to.
The tools fail closed. If the declaration is missing, unapproved, or served with the wrong media type, the page registers no giving tools at all — and the agent is told this site exposes no authorised giving pathway, rather than being handed a form it might use anyway. Absence is a much safer default than an ambiguous form.
It hands over a filled checkout, not a blank form.
An agent that has established the donor wants fifty dollars a month should not then produce an empty donation page. A destination may declare how to reach its checkout with those fields already set.
giving_prepare({
amount: 50,
frequency: "monthly"
}) {
"recipient": "To Be Heard Foundation Inc",
"authorized_url": "…/donate?amount=50
&frequency=monthly",
"prefill_applied": true,
"payment_completed": false,
"requires_human_payment_authorization": true
} Figure 05 · a real call against the Power Poetry declaration. The donor lands on the organisation’s own page with the amount and frequency set, and authorises the payment themselves.
The agent never learns the payment platform. Givebutter accepts frequency=monthly and silently ignores recurring; Classy, Bloomerang and Blackbaud each spell it their own way, and any of them may change it tomorrow. So the organisation declares the vocabulary and the consumer fills only what is declared — an undeclared field, a value outside the declared list, or a template pointing at another origin is refused outright. A guessed parameter fails where it costs most: the donor believes a monthly gift is set up when it is not.
Only one of these authorises anything.
| No. | Statement | Who makes it | Means | Authorises |
|---|---|---|---|---|
| 01 | benefits | Anyone | Proceeds from this go to Organization X. | |
| 02 | confirmed | A discovery process | Public evidence consistently identifies this destination. | |
| 03 | authorized | The organisation | We declare this an approved giving destination. |
No volume, quality, or agreement of evidence converts confirmed into authorized. Discovery may propose; only a human at the nonprofit may publish. The affirmation is compared as a constant. The tooling refuses a paraphrase.
Eight declared methods. Nothing else prints.
Every destination carries a numbered method, a named recipient, and an authorisation record. Each unit is cited by the same number in the specification, the generator, and the validator.
Figure 07 · the permitted method set. A ninth cell cannot be added by a consumer, a processor, or an agent.
An afternoon, in four operations.
| No. | Operation | Where it happens | Who does it |
|---|---|---|---|
| 01 | Draft the declaration | /generate | Developer |
| 02 | Authorise each destination | Off the machine | The nonprofit |
| 03 | Serve it | /giving.json | Developer |
| 04 | Register the agent tools | giving-tools.js | Developer |
Operation 02 is not automatable and has no tooling. A nonprofit administrator affirms, verbatim: “Our organization authorizes donations through this destination.” Everything else on this site exists to make the other three operations short.