A desk with two monitors showing donation records and reporting dashboards side by side

Zeffy API: Automate Donation Alerts and Thank-Yous

A $5,000 gift should create a personal moment, not just another payment row. Carly can thank the donor, alert the director with the relevant history, schedule the next touch, and keep the follow-up moving outside Zeffy. That is why even Zeffy’s small, read-only API can support useful donor work, recurring welcomes, reconciliation checks, and fundraiser briefs.

Zeffy’s API is free, you can generate a key yourself in about a minute, and it is read-only. Six endpoints, all GET, covering payments, contacts, and campaigns. There is exactly one webhook. Zeffy’s own API page still carries a Beta badge as of July 2026, and its FAQ answers the write question directly: “Not currently. The API is read-only.”

That’s a narrower surface than most nonprofit platforms, but it’s honest and it’s free — which for an organization on Zeffy specifically is the whole point. Here’s what’s actually in it.


What nonprofits actually automate with it

Read-only sounds limiting, and for some plans it is — but the jobs small nonprofits most want are almost all read-and-react:

  • Thank-yous that go out within the hour, in the donor’s name, rather than a batch someone runs at month end. For first-time donors this is the single biggest driver of whether they give again.
  • Large gifts flagged to the director immediately, so a $5,000 donation gets a personal call the same day instead of showing up in a report next week.
  • New recurring donors routed to a welcome sequence the moment they set it up.
  • Refunds and disputes caught in reconciliation — the one Zeffy won’t tell you about, covered below.

What you can’t do is write anything back into Zeffy. In practice that matters less than it sounds, because the work you want automated happens in email and your calendar, not inside Zeffy.


The complete endpoint list

This is not a summary. It is the entire API, taken from Zeffy’s OpenAPI spec:

GET /api/v1/payments        GET /api/v1/payments/{id}
GET /api/v1/contacts        GET /api/v1/contacts/{id}
GET /api/v1/campaigns       GET /api/v1/campaigns/{id}

No POST, no PATCH, no DELETE — anywhere in the spec. Sending POST https://api.zeffy.com/api/v1/payments returns a 404 Cannot POST, not a 403 or 405. The write route doesn’t exist to be forbidden.

The mechanics:

  • Base URL https://api.zeffy.com, paths under /api/v1/
  • Auth is a bearer token: Authorization: Bearer YOUR_API_KEY
  • Rate limit is 100 requests per minute per key
  • Pagination is cursor-based — pass next_cursor from the response back as starting_after
  • Errors come back as a typed envelope with type set to one of invalid_request_error, authentication_error, rate_limit_error, or api_error

Getting a key: one person per organization can do it

Log in, go to Settings → Integrations, answer a question or two about whether you want API or webhook access and what you’re building, then click Get my API key. Zeffy links straight to it at zeffy.com/o/settings?openIntegrations=true.

The catch is who “you” has to be. Zeffy’s spec says organization owner; the help center says admins — and adds that organizations on Zeffy only have one admin. Either way it resolves to a single privileged person per org. If you’re a consultant or a volunteer developer, you aren’t generating this key yourself. Someone with the admin seat does it and hands it over, or transfers the seat.

Access itself costs nothing. Zeffy states it plainly: free for every organization, no subscription, no per-request charges. That tracks with their model — Zeffy doesn’t charge nonprofits for the platform either.

One webhook, and the thing it won’t tell you

Zeffy fires exactly one event: payment.completed. It’s formally declared in the spec, and the payload carries the full Payment object — the same shape you’d get from GET /payments/{id} — wrapped with id, type, version, and an ISO 8601 dispatchedAt. Return a 2xx to acknowledge; a non-2xx gets retried.

For a read-only API, that one webhook is the entire automation story. Polling six GET endpoints tells you what happened eventually. The webhook is the only thing that tells you now.

Which makes the gap in it worth knowing about before you build.

Payments have no updated timestamp and no updated filter. Contacts and campaigns both expose updated plus an updated[gte] filter. Payments expose only created. But payments do change after the fact — the schema carries refund_status, refunds, and dispute.

So: a donation from March gets refunded in July. No webhook fires, because payment.completed is the only event there is. And it never surfaces in an incremental sync keyed on created, because its creation date is still March. If you’re reconciling Zeffy against your accounting, a created-date sync will quietly drift, and the drift is made of exactly the transactions you most need to catch. The fix is periodically re-polling historical payments by ID or full-scanning — neither elegant, both necessary.

Three smaller traps in the same spec:

  • Date filters take Unix timestamps, not ISO 8601 — even though the webhook’s own dispatchedAt is ISO 8601. Passing an ISO string to created[gte] returns a 400.
  • The currency filter accepts only cad and usd, despite Zeffy onboarding organizations in the UK, Ireland, and Australia. GBP, EUR, and AUD orgs have no filter value to pass.
  • Default page size is 10, not 100. A naive pagination loop burns ten times the requests you’d expect against a 100/minute ceiling.

Getting something to happen when a donation lands

A webhook only matters if something is listening. That’s the part people underestimate: payment.completed will fire reliably, but it fires into whatever you’ve built to catch it, and for most small nonprofits that’s nothing.

Reaching for an AI assistant here runs into a specific wall.

Scheduled work is no longer the dividing line — ChatGPT and Claude both run tasks on a timer without anyone watching. The line that still holds is event triggers. Nothing kicks off because something happened in one of your apps; it kicks off because the clock said so, which means anything time-sensitive waits for the next run.

So “summarize last month’s giving” is well within what ChatGPT or Claude will do with a Zeffy export. “Thank every donor within an hour of the gift” is not, because nothing on that side is watching for the gift.

That gap is what Carly is built for. It runs in the cloud and acts on events rather than waiting to be asked:

  • Fires on the donation itselfpayment.completed arrives, Carly acts, without your laptop being open
  • Runs the whole follow-up in one flow — read the payment, look up the contact, draft the acknowledgement, send it, log it
  • Actually sends — email through Gmail and Outlook, with attachments, not just drafts you have to send yourself
  • Handles the refund gap — a scheduled re-scan of historical payments is precisely the unglamorous job worth automating, since the API won’t tell you about it any other way

Because Zeffy exposes a public API, you can connect it natively to Carly from the Integrations tab with your API token. Carly can then use Zeffy in on-demand, recurring, and event-triggered workflows. AI agents start at $35/month, and workflow steps that don’t use AI run free.


Frequently Asked Questions

Can I write data back to Zeffy through the API?

No. All six endpoints are GET, and Zeffy’s own FAQ confirms the API is read-only. There’s no documented plan to change it. If you need records created in Zeffy, that happens through Zeffy’s own forms and campaigns.

Does the Zeffy API cost anything?

No. Zeffy states API access is free for every organization — no subscription, no per-request charge. Rate limiting is 100 requests per minute per key.

What webhooks does Zeffy support?

One: payment.completed. It carries the full payment object. There is no event for refunds, disputes, contact changes, or campaign updates, which is why refund reconciliation needs a periodic re-poll.

Who can generate a Zeffy API key?

Only the organization’s admin or owner, and Zeffy organizations have a single admin. Everyone else needs that person to generate the key or transfer the seat.

Is the Zeffy API still in beta?

Yes, per Zeffy’s own API page as of July 2026. The OpenAPI spec is labeled version 1.0 with no beta marker, so the two disagree slightly — but the customer-facing page and FAQ both say Beta.


More: AI agents for nonprofit directors · Best AI assistant for nonprofits · Bloomerang AI · Claude + Bloomerang

Ready to automate your busywork?

Carly schedules, researches, and briefs you—so you can focus on what matters.

See what people say

"Before Carly, I relied on a Calendly link, but the whole process felt impersonal and not very professional. Carly changed that by handling all the back-and-forth, so I'm no longer stuck in endless email threads trying to line up schedules.

Now Carly reaches out to candidates, shares my real-time availability, lets them pick a slot, then sends a Zoom link and drops it straight into my calendar. She sends reminders to both of us before each call, which has significantly reduced no-shows and last-minute confusion.

On top of scheduling, Carly acts like a full executive assistant, sending me my schedule the night before so I can prepare for each call. It reminds me of the old x.ai assistant, but Carly is noticeably smarter, faster, and better suited to my healthcare recruitment business."

Gus Ibrahim, Founder & Director, IHR