Skip to content

Charity Donations

Search vetted charities, record donations, and list donation history. The charity donations API is open to any app, not just Shopify. Sign up at app.thegoodapi.com and grab your API key. All endpoints use the base URL https://app.thegoodapi.com.

Use this checklist before you take donations in production.

  1. We collect via Stripe.
  2. Funds go through Our Change Foundation, a 501(c)(3) that grants to nonprofits. We name your platform in the grant info.
  3. We pay out monthly on the 28th. Nonprofit receive timing depends on grantor portal settings. Nonprofits get a dashboard and CA AB 488 reports.
  4. You get the tax receipt.

GoodAPI charges no donation processing fees and takes no cut of the donation. GoodAPI covers state fees, bonds, and filings.

  • Donation costs are the Lead plan at $49/month for API access, Stripe collection (about 2 to 3 percent for cards, or about 0.8 percent for ACH if set up), and the foundation’s 1.9 percent grant fee (to them, not GoodAPI).
  • Example: collect $100, receipt for $97 after card fees, nonprofit gets $95.10 after the grant fee.
  • Lead plan is $49/month for API access.
  • No minimum commitment and no cancellation limits.
  • Access is month-to-month under the Terms and Conditions.
  • No sales agreement is required unless you have custom requirements. Those go on a custom plan.
  • Request our compliance pack for registrations and filings.

GoodAPI acts as the commercial co-venturer for giving that runs through it.

  • All 50 states require an agreement between the for-profit and the nonprofit.
  • 39 require that agreement registered, and GoodAPI is registered in all 39.
  • 6 of those also require GoodAPI itself to register: Alabama, California, Hawaii, Massachusetts, Mississippi, and South Carolina. Those filings are done.
  • Brand Partners, including API platforms, are already covered by GoodAPI’s agreement with Our Change Foundation. They do not need to file separately for California or Hawaii. Our registrations cover Brand Partner obligations.
  • California public CCV profile

Each API call names a nonprofit by EIN or nonprofit ID from 1.3M+ verified 501(c)(3)s. Use ein or nonprofit_id on POST /charities/donate.

Show this copy next to the donation or behind an info icon:

Our donation platform, GoodAPI, partners with Our Change Foundation (EIN: 86-3353394), a nonprofit Section 501(c)(3) organization that makes grants to the nonprofits you suggest here. Learn more about how we process donations

All endpoints require an API key via the Authorization header:

Authorization: <your_api_key>

GET https://app.thegoodapi.com/charities/search

Search for charities by name or EIN, or fetch a single charity directly by nonprofit ID.

NameTypeRequiredDescription
namestringNoSearch by charity name
qstringNoAlias for name (used when name is not set)
idstringNoChange nonprofit ID (n_...) for direct lookup (detail mode)
einstringNoEmployer Identification Number
page_sizeintegerNoResults per page (1-20, default 20)
pageintegerNoPage number (minimum 1, default 1)
{
"total_items": 42,
"total_pages": 3,
"charities": [
{
"nonprofit_id": "n_abc123",
"name": "American Red Cross",
"ein": "53-0196605",
"description": "Prevents and alleviates human suffering",
"website": "https://www.redcross.org",
"icon_url": "https://example.com/redcross-icon.png"
}
]
}
FieldTypeDescription
nonprofit_idstringProvider-specific nonprofit ID
namestringCharity name
einstringEmployer Identification Number
descriptionstringCharity description or mission
websitestringCharity website URL
icon_urlstringCharity icon image URL

Pass id with a Change nonprofit ID (n_...) to fetch that charity directly instead of searching. This is how partners check a nonprofit’s written-consent status (direct / via_change), which paginated search results do not include. Direct lookup requires the Change provider (the default); PayPal-only accounts do not support it.

A name or q value that is itself a Change nonprofit ID (n_..., with no spaces) is also auto-detected as a direct lookup. An auto-detected ID that fails to resolve falls back to a normal free-text search; an explicitly requested id that fails does not fall back — it returns 502.

{
"mode": "detail",
"nonprofit": {
"nonprofit_id": "n_abc123",
"name": "American Red Cross",
"ein": "53-0196605",
"description": "Prevents and alleviates human suffering",
"website": "https://www.redcross.org",
"icon_url": "https://example.com/redcross-icon.png",
"logo_url": "https://example.com/redcross-logo.png",
"written_consent": {
"direct": true,
"via_change": true
}
},
"custom_logo_url": "https://example.com/redcross-custom-logo.png"
}

custom_logo_url is included only when GoodAPI has a custom logo on file for the nonprofit.

FieldTypeDescription
nonprofit_idstringProvider-specific nonprofit ID
namestringCharity name
einstringEmployer Identification Number
descriptionstringCharity description or mission
websitestringCharity website URL
icon_urlstringCharity icon image URL
logo_urlstringCharity logo image URL from the provider
written_consentobjectWritten consent state: direct and via_change booleans
StatusReason
403Invalid or missing API key
500Charity search failed / nonprofit response could not be parsed
501Direct lookup not supported by the configured charity provider (e.g. PayPal)
502Change API returned an error for an explicitly requested id
Terminal window
curl -H "Authorization: <your_api_key>" \
"https://app.thegoodapi.com/charities/search?name=red+cross"

Detail lookup by nonprofit ID:

Terminal window
curl -H "Authorization: <your_api_key>" \
"https://app.thegoodapi.com/charities/search?id=n_abc123"

POST https://app.thegoodapi.com/charities/subscribe

Provisions the Stripe subscription items for flat-rate and metered billing on your organization’s existing subscription. This must be called once before making any live donations.

{
"success": true,
"message": "Successfully activated donation subscription"
}
StatusReason
403Invalid or missing API key
500Internal server error / Stripe integration error
Terminal window
curl -X POST -H "Authorization: <your_api_key>" \
"https://app.thegoodapi.com/charities/subscribe"

POST https://app.thegoodapi.com/charities/donate

Record a charity donation for your organization.

{
"amount_cents": 5000,
"ein": "53-0196605",
"nonprofit_id": "n_abc123",
"charity_name": "American Red Cross",
"idempotency_key": "order-12345-donate",
"attribution": "checkout-flow",
"metadata": {
"order_id": "12345",
"customer_email": "customer@company.com"
}
}
FieldTypeRequiredDescription
amount_centsintegerYesDonation amount in cents (must be > 0)
einstring*Employer Identification Number of the charity
nonprofit_idstring*Provider-specific nonprofit identifier
charity_namestringNoHuman-readable charity name (auto-filled from search if omitted)
idempotency_keystringNoUnique key to prevent duplicate donations
attributionstringNoAttribution tag (e.g. checkout, campaign-xyz)
metadataobjectNoArbitrary key-value pairs for your records
{
"donation_id": "abc123def456",
"amount_cents": 5000,
"charity_name": "American Red Cross",
"ein": "53-0196605",
"nonprofit_id": "n_abc123",
"total_donations": 15,
"donation_details": [
{
"id": "abc123def456",
"amount_cents": 5000,
"currency": "USD",
"ein": "53-0196605",
"nonprofit_id": "n_abc123",
"charity_name": "American Red Cross",
"created_at": "2025-06-15T10:30:00Z",
"idempotency_key": "order-12345-donate",
"attribution": "checkout-flow",
"metadata": {
"order_id": "12345",
"customer_email": "customer@company.com"
},
"refunded": false
}
]
}
FieldTypeDescription
donation_idstringUnique ID of the created donation
amount_centsintegerDonation amount in cents
charity_namestringCharity name (auto-filled from search if omitted)
einstringEIN (if provided)
nonprofit_idstringNonprofit ID (if provided)
total_donationsintegerTotal non-refunded donations for your org
donation_detailsarrayArray containing the created donation record

When idempotency_key is provided and a donation with the same key already exists for your organization:

  • The existing donation is returned.
  • The response includes the header Idempotent-Replayed: true.
  • No new donation is created.

The provided ein or nonprofit_id is validated against the charity search provider. If no matching charity is found, the request is rejected with a 400 error. When a charity is found and charity_name was not provided, it’s automatically populated from the search result.

StatusReason
400Missing ein and nonprofit_id
400amount_cents is missing or <= 0
400Invalid request body
400No charity found for the provided ein
400No charity found for the provided nonprofit_id
400Donation subscription not active
403Invalid or missing API key
500Internal server error

Basic donation by EIN:

Terminal window
curl -X POST -H "Authorization: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{"amount_cents": 5000, "ein": "53-0196605"}' \
"https://app.thegoodapi.com/charities/donate"

Donation with idempotency and attribution:

Terminal window
curl -X POST -H "Authorization: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{
"amount_cents": 2500,
"nonprofit_id": "n_abc123",
"idempotency_key": "order-789-donate",
"attribution": "checkout",
"metadata": {"order_id": "789"}
}' \
"https://app.thegoodapi.com/charities/donate"

GET https://app.thegoodapi.com/charities/donations

Retrieve paginated donations for your organization with optional filtering.

NameTypeRequiredDescription
attributionstringNoFilter by attribution tag
metadata_keystringNoFilter by metadata key existence
metadata_valuestringNoFilter by metadata value (requires metadata_key)
start_datestringNoFilter on or after this date (YYYY-MM-DD)
end_datestringNoFilter on or before this date (YYYY-MM-DD)
pageintegerNoPage number (minimum 1, default 1)
page_sizeintegerNoResults per page (1-100, default 20)
{
"total_items": 50,
"total_pages": 5,
"page": 1,
"page_size": 10,
"donations": [
{
"id": "abc123def456",
"amount_cents": 5000,
"currency": "USD",
"ein": "53-0196605",
"nonprofit_id": "n_abc123",
"charity_name": "American Red Cross",
"created_at": "2025-06-15T10:30:00Z",
"idempotency_key": "order-12345-donate",
"attribution": "checkout-flow",
"metadata": {
"order_id": "12345"
},
"refunded": false
}
]
}
FieldTypeDescription
total_itemsintegerTotal number of matching donations
total_pagesintegerTotal number of pages (0 if no results)
pageintegerCurrent page number
page_sizeintegerNumber of items per page
donationsarrayArray of donation records
FieldTypeDescription
idstringUnique donation ID
amount_centsintegerDonation amount in cents
currencystringCurrency code (always USD)
einstringEIN of the charity
nonprofit_idstringProvider-specific nonprofit ID
charity_namestringHuman-readable charity name
created_atstringISO 8601 timestamp
idempotency_keystringIdempotency key (if provided)
attributionstringAttribution tag
metadataobjectArbitrary key-value pairs
refundedbooleanWhether the donation has been refunded
StatusReason
400Invalid date format
403Invalid or missing API key
500Internal server error

List all donations:

Terminal window
curl -H "Authorization: <your_api_key>" \
"https://app.thegoodapi.com/charities/donations"

Filter by attribution with pagination:

Terminal window
curl -H "Authorization: <your_api_key>" \
"https://app.thegoodapi.com/charities/donations?attribution=checkout&page=1&page_size=10"

Filter by date range:

Terminal window
curl -H "Authorization: <your_api_key>" \
"https://app.thegoodapi.com/charities/donations?start_date=2025-01-01&end_date=2025-06-30"

Filter by metadata:

Terminal window
curl -H "Authorization: <your_api_key>" \
"https://app.thegoodapi.com/charities/donations?metadata_key=order_id&metadata_value=12345"

POST https://app.thegoodapi.com/refund/donations

Refund a charity donation by setting its status to refunded.

{
"id": "don_abc123",
"reason": "Customer cancelled order",
"idempotency_key": "refund-order-12345",
"metadata": {
"refund_processed_by": "admin"
}
}
FieldTypeRequiredDescription
idstringYesThe unique donation ID to refund
reasonstringNoHuman-readable reason for the refund
idempotency_keystringNoUnique key to prevent duplicate refund processing
metadataobjectNoArbitrary key-value pairs stored with the refund
{
"refunded_amount_cents": 5000,
"total_donations": 14,
"refund_details": [
{
"id": "don_abc123",
"amount_cents": 5000,
"currency": "USD",
"ein": "53-0196605",
"nonprofit_id": "n_abc123",
"charity_name": "American Red Cross",
"created_at": "2025-06-15T10:30:00Z",
"idempotency_key": "order-12345-donate",
"attribution": "checkout-flow",
"metadata": {
"order_id": "12345",
"customer_email": "customer@company.com"
},
"refunded": true
}
],
"refund_id": "refund-don_abc123"
}
FieldTypeDescription
refunded_amount_centsintegerAmount refunded in cents
total_donationsintegerTotal non-refunded donations remaining for your organization
refund_detailsarrayArray containing the refunded donation record
refund_idstringUnique identifier for this refund (refund-<donation_id>)
StatusReason
400Missing id (donation ID)
400Invalid request body
403Invalid or missing API key
404Donation not found
500Internal server error
Terminal window
curl -X POST -H "Authorization: <your_api_key>" \
-H "Content-Type: application/json" \
-d '{"id": "don_abc123"}' \
"https://app.thegoodapi.com/refund/donations"

Yes. Pass attribution plus a metadata object on POST /charities/donate, then filter GET /charities/donations with attribution, metadata_key, and metadata_value.

Can we hold funds and release them at a milestone?

Section titled “Can we hold funds and release them at a milestone?”

No. Milestone or staged grant release is not supported. You must control timing on your end. Once funds go on the 28th, the foundation is required by law to start granting to the designated nonprofits.

If my company funds the gifts, can we send one donation per nonprofit?

Section titled “If my company funds the gifts, can we send one donation per nonprofit?”

Yes. If the company funds the donation, you may total contributions internally and send one donation per nonprofit periodically. The same compliance rules apply.

We name your platform in the grant info. You get the tax receipt.

See Fees. GoodAPI charges no donation processing fees and takes no cut of the donation. Donation costs are the Lead plan at $49/month for API access, Stripe collection (about 2 to 3 percent for cards, or about 0.8 percent for ACH if set up), and the foundation’s 1.9 percent grant fee (to them, not GoodAPI). Example: collect $100, receipt for $97 after card fees, nonprofit gets $95.10 after the grant fee.

Brand Partners, including API platforms, are already covered by GoodAPI’s agreement with Our Change Foundation. They do not need to file separately for California or Hawaii. Our registrations cover Brand Partner obligations.

How do I request registrations and filings?

Section titled “How do I request registrations and filings?”

Request our compliance pack. If you need something beyond the standard month-to-month Terms and Conditions, that is a custom plan.