Charity Verify API
One API call to check tax-deductible eligibility, revocation status, group exemptions, and OFAC sanctions screening for any U.S. nonprofit.
Overview
The Charity Verify API cross-references multiple IRS data sources and OFAC sanctions lists to give you a single, definitive answer on whether a nonprofit can receive tax-deductible donations.
Data sources checked on every request:
- IRS Exempt Organizations Business Master File (EO BMF)
- IRS Publication 78 (eligible donees)
- IRS Auto-Revocation List (with reinstatement detection)
- Group Exemption resolution (subordinate → parent lookup)
- OFAC SDN & Consolidated sanctions lists (fuzzy matching)
- Form 990 leadership screening against OFAC
Authentication
All API requests require an API key passed in the x-api-key header.
# Include your key in every request curl -H "x-api-key: YOUR_API_KEY" \ "https://api.givalgo.ai/v1/verify?ein=53-0196605"
To get an API key, contact support@givalgo.ai. Keys are scoped to a usage plan (Free, Basic, or Pro) which determines your rate limits.
Keep your API key secure. Do not expose it in client-side code or public repositories. If compromised, contact support for a key rotation.
Quickstart
Get up and running in 60 seconds.
cURL
# Verify American Red Cross curl -H "x-api-key: YOUR_API_KEY" \ "https://api.givalgo.ai/v1/verify?ein=53-0196605"
Python
import requests response = requests.get( "https://api.givalgo.ai/v1/verify", params={"ein": "53-0196605"}, headers={"x-api-key": "YOUR_API_KEY"} ) data = response.json() if data["deductible"]: print(f"{data['organization']['name']} is eligible!") else: print(f"Status: {data['status']} - {data['message']}")
JavaScript
const response = await fetch( "https://api.givalgo.ai/v1/verify?ein=53-0196605", { headers: { "x-api-key": "YOUR_API_KEY" } } ); const data = await response.json(); console.log(data.status, data.organization?.name);
Verify Endpoint
Returns a complete verification of the nonprofit identified by the given EIN, including tax-deductible eligibility, revocation history, group exemption status, OFAC sanctions screening, and California state compliance (when applicable).
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ein | string | Yes | Employer Identification Number. Accepts 13-1837418, 131837418, or 13 1837418. |
donor_state | string | No | Two-letter state code of the donor (e.g., CA). When set to CA, California AG + FTB compliance checks run even if the nonprofit is not CA-based. See California Compliance. |
ca_entity_id | string | No | California SOS/FTB entity number for direct lookup in the CA AG Registry and FTB Revocation list. Provides the highest coverage for California compliance checks. |
Response Fields
| Field | Type | Description |
|---|---|---|
status | string | Overall verification result (see Statuses) |
deductible | boolean | Whether donations are tax-deductible. null if not found. |
message | string | Human-readable explanation |
organization | object | IRS EO BMF data (name, city, state, subsection, foundation type, assets, income, NTEE code) |
pub78 | object | Publication 78 listing and deductibility type (PC, PF, POF, SO, etc.) |
revocation | object | Auto-revocation history and reinstatement status |
group_exemption | object | Present when ELIGIBLE via group exemption. Shows parent org details. Only applies to 501(c)(3) subordinates. |
sanctions_screening | object | OFAC screening results (see Sanctions Screening below for match object details) |
state_compliance | object | absent | Present only when California compliance checks are triggered. Contains california sub-object with AG registry and FTB status. See California Compliance. |
data_freshness | object | ISO dates showing when each source agency last published their data file (eo_bmf, pub78, revocation, ofac_sdn, ofac_cons) |
checked_at | string | ISO 8601 timestamp of this verification |
sanctions_screening object
| Field | Type | Description |
|---|---|---|
status | string | CLEAR, POTENTIAL_MATCH, STRONG_MATCH, or NOT_SCREENED |
organization_screening | object | Org name screened against OFAC entity entries |
.checked_name | string | Organization name that was screened |
.matches_found | integer | Number of OFAC matches |
.matches[] | array | Array of match objects (see below) |
leadership_screening | object | Form 990 officers/directors screened against OFAC individuals |
.people_data_tax_year | integer | null | Tax year of the Form 990 people data used for screening (e.g., 2023). Null if no people data found. |
.people_checked | integer | Number of people screened from Form 990 |
.people_screened[] | array | List of officers/directors/key employees screened, each with name and title |
.name | string | Person's name as reported on Form 990 |
.title | string | Person's title/role (e.g., "EXECUTIVE DIRECTOR", "BOARD PRESIDENT") |
.matches_found | integer | Number of OFAC matches |
.matches[] | array | Array of match objects (see below) |
checked_against | array | ["OFAC SDN", "OFAC Consolidated"] |
screened_at | string | ISO 8601 timestamp of screening |
Match object (within matches[])
| Field | Type | Description |
|---|---|---|
source | string | "OFAC SDN" or "OFAC Consolidated" |
matched_name | string | Name from OFAC list that matched |
matched_via | string | "primary_name" or "alias (a.k.a. ...)" |
primary_name | string | Primary OFAC name (only present for alias matches) |
similarity_score | number | Fuzzy match score (0.7–1.0). ≥0.9 = STRONG, ≥0.7 = POTENTIAL |
match_strength | string | "STRONG" or "POTENTIAL" |
sdn_type | string | OFAC entity type ("individual", "N" for entity/org) |
program | string | OFAC sanctions program (e.g., "SDGT", "IRAN") |
entry_id | integer | OFAC entry number |
remarks | string | OFAC remarks — often contains date of birth, nationality, passport numbers, and other identifying information. Key for false positive disambiguation. |
addresses | array | Known addresses for this OFAC entry. Each has address, city_state_zip, and country fields. |
Verification Statuses
| Status | Deductible | Meaning |
|---|---|---|
ELIGIBLE | true | Listed in IRS Pub 78 (directly or via group exemption for 501(c)(3) subordinates). Eligible for tax-deductible donations. |
NOT_DEDUCTIBLE | false | In IRS records but not tax-deductible (e.g., 501(c)(4), 501(c)(6)). |
REVOKED | false | Tax-exempt status auto-revoked by the IRS for non-filing. May appear even if the organization has dropped off the Business Master File. |
CAUTION | null | Federally eligible but flagged for review. Possible reasons: (1) In IRS master file as 501(c)(3) but not yet in Pub 78, or (2) California state compliance issue — the organization is delinquent, revoked, or suspended with the CA Attorney General or Franchise Tax Board. Check the message and state_compliance fields for specifics. |
NOT_FOUND | null | Not in IRS records and not on the revocation list. Churches and self-declared orgs may not appear. |
Sanctions Screening
Every verification includes an automated OFAC screening of the organization name and its leadership (officers, directors, key employees from Form 990). Matches are checked against both SDN and Consolidated lists, including primary names and aliases.
Overall status
| Status | Meaning |
|---|---|
CLEAR | No OFAC matches found for the organization or its leadership. |
POTENTIAL_MATCH | Fuzzy match with 70–89% similarity. Manual review recommended. |
STRONG_MATCH | Fuzzy match with 90%+ similarity. Very likely the same entity. |
NOT_SCREENED | OFAC screening was not performed (e.g., organization not found in IRS database). See the reason field for details. |
Disambiguation fields
When matches are found, each match object includes remarks and addresses to help you distinguish true positives from false positives:
remarks— OFAC remarks field containing date of birth, nationality, passport numbers, and other identifying informationaddresses— known addresses for the matched OFAC entry (street, city/state/zip, country)
Example match object
{
"source": "OFAC SDN",
"matched_name": "SMITH, John A.",
"matched_via": "primary_name",
"similarity_score": 0.912,
"match_strength": "STRONG",
"sdn_type": "individual",
"program": "SDGT",
"entry_id": 12345,
"remarks": "DOB 15 Mar 1970; nationality Iran; Passport A1234567",
"addresses": [
{
"address": "123 Example St",
"city_state_zip": "Tehran",
"country": "Iran"
}
]
}In this example, a board member named "John Smith" matched an OFAC entry — but the remarks show an Iranian DOB/passport, and the addresses show Tehran. If your board member is based in Ohio with a different DOB, this is a false positive you can confidently dismiss.
California Compliance
California AB 488 requires fundraising platforms to verify that nonprofits are in good standing with three authorities before facilitating donations involving a California donor or a California-based nonprofit:
- IRS — federal tax-exempt status (always checked)
- CA Attorney General — Registry of Charitable Trusts registration status
- CA Franchise Tax Board — state tax-exempt status (revocation check)
The API automatically runs California checks when the nonprofit is based in CA (per IRS records) or when you provide donor_state=CA. You can also provide ca_entity_id to trigger checks directly.
When do CA checks run?
| Nonprofit State | donor_state | CA Checks? |
|---|---|---|
| CA | (blank) | Yes — nonprofit is CA-based |
| Non-CA | (blank) | No |
| Any | CA | Yes — donor is in CA |
| Any | Non-CA | Only if nonprofit is CA-based |
| Any | Any | Yes — if ca_entity_id is provided |
Lookup cascade
The API uses a three-tier lookup to maximize coverage across the CA AG Registry (556K records):
ca_entity_id— direct SOS/FTB# lookup (97% of AG records have this)- FEIN — federal EIN match (covers ~58% of AG records)
- Name + city — fuzzy match fallback using trigram similarity (≥0.65 threshold with city filter, ≥0.80 without)
The match_method field in the response tells you which tier was used: ca_entity_id, fein, or name_match.
state_compliance.california object
| Field | Type | Description |
|---|---|---|
trigger | string | Why CA checks ran: nonprofit_based_in_ca, donor_state_ca, or ca_entity_id_provided |
ag_registry | object | CA Attorney General Registry result |
.status | string | REGISTERED, EXEMPT, DELINQUENT, REVOKED, SUSPENDED, CLOSED, NOT_REGISTERED, NON_COMPLIANT, or NOT_FOUND |
.registry_status | string | Raw status from CA AG (e.g., "Current", "Delinquent", "Exempt - Religious") |
.reg_number | string | State charity registration number (e.g., CT0252232) |
.match_method | string | ca_entity_id, fein, or name_match |
.matched_name | string | Present for name_match — the CA AG name that matched |
.name_similarity | number | Present for name_match — similarity score (0.65–1.0) |
ftb | object | CA Franchise Tax Board revocation result |
.status | string | CLEAR or REVOKED |
.revocation_date | string | Date of FTB revocation (if revoked) |
state_status | string | Roll-up: COMPLIANT, NON_COMPLIANT, REVOKED, or UNKNOWN |
Impact on overall status
| AG Registry | FTB | state_status | Overall status |
|---|---|---|---|
| REGISTERED / EXEMPT | CLEAR | COMPLIANT | No change |
| DELINQUENT / REVOKED / SUSPENDED | CLEAR | NON_COMPLIANT | ELIGIBLE → CAUTION |
| Any | REVOKED | REVOKED | ELIGIBLE → CAUTION |
| NOT_FOUND | CLEAR | UNKNOWN | No change |
Note: UNKNOWN (organization not found in CA AG) does not penalize the overall status. This may indicate the organization is exempt from CA registration (churches, schools, hospitals, or organizations receiving under $25,000 annually).
Example response
{
"status": "CAUTION",
"message": "This organization is listed in IRS Publication 78 ... However, California state compliance checks indicate that the organization's California Attorney General registration status is 'Delinquent'. Under California AB 488, fundraising platforms must verify state-level good standing before facilitating donations.",
"state_compliance": {
"california": {
"trigger": "nonprofit_based_in_ca",
"ag_registry": {
"status": "DELINQUENT",
"registry_status": "Delinquent",
"reg_number": "CT0252232",
"last_renewal_date": "2018-05-01",
"date_status_set": "2020-02-21",
"match_method": "fein"
},
"ftb": {
"status": "CLEAR"
},
"state_status": "NON_COMPLIANT"
}
}
}Rate Limits
Rate limits are applied per API key based on your plan tier.
| Plan | Requests / day | Burst | Rate |
|---|---|---|---|
| Free | 5 | 2/sec | 1/sec |
| Basic | 1,000 | 10/sec | 5/sec |
| Pro | 10,000 | 50/sec | 25/sec |
When you exceed your rate limit, the API returns 429 Too Many Requests. The response includes a Retry-After header indicating when you can retry.
Playground
Test the API directly from your browser. Enter your API key and an EIN to see a live response.
Try it now
Bulk Verify API
Verify hundreds or thousands of EINs in a single async request. Same 5-step verification, delivered at scale.
Overview
The Bulk Verify API accepts up to 250 EINs (semicolon-separated) or 20,000 EINs (CSV upload), processes them asynchronously via background workers, and delivers results via polling endpoint, webhook callback, or CSV download.
Each EIN goes through the same verification as the single Verify endpoint — IRS data cross-referencing, group exemption resolution, and OFAC sanctions screening.
How it works
- Submit — POST your EINs to
/v1/bulk-verify. Get back ajob_idimmediately (202 Accepted). - Process — EINs are split into batches of 10 and verified in parallel by background workers.
- Retrieve — Poll
GET /v1/bulk-verify/{job_id}for progress and results, or receive a webhook callback on completion.
| Input Method | Max EINs | Format |
|---|---|---|
| JSON body (semicolon-separated) | 250 | application/json |
| CSV file upload | 20,000 | multipart/form-data |
Authentication
All API requests require an API key passed in the x-api-key header — the same key used for the single Verify endpoint.
# Include your key in every request curl -X POST "https://api.givalgo.ai/v1/bulk-verify" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"eins": "13-1837418;53-0196605"}'
To get an API key, contact support@givalgo.ai. Keys are scoped to a usage plan (Free, Basic, or Pro) which determines your rate limits and max EINs per job.
Job ownership: Jobs are scoped to your API key. You can only view the status and results of jobs you created.
Quickstart
Submit a bulk job and poll for results in under a minute.
cURL — Submit + Poll
# 1. Submit a bulk job curl -X POST "https://api.givalgo.ai/v1/bulk-verify" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "eins": "13-1837418;53-0196605;06-0646973", "format": "both" }' # Response: {"job_id": "bulk_abc123", "status": "PROCESSING", ...} # 2. Poll for results curl -H "x-api-key: YOUR_API_KEY" \ "https://api.givalgo.ai/v1/bulk-verify/bulk_abc123"
Python
import requests, time # Submit bulk job resp = requests.post( "https://api.givalgo.ai/v1/bulk-verify", headers={"x-api-key": "YOUR_API_KEY"}, json={ "eins": "13-1837418;53-0196605;06-0646973", "format": "both" } ) job = resp.json() job_id = job["job_id"] # Poll until complete while True: status = requests.get( f"https://api.givalgo.ai/v1/bulk-verify/{job_id}", headers={"x-api-key": "YOUR_API_KEY"} ).json() if status["status"] == "COMPLETED": print(f"Done! {status['summary']}") break time.sleep(2)
JavaScript
// Submit bulk job const resp = await fetch("https://api.givalgo.ai/v1/bulk-verify", { method: "POST", headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json" }, body: JSON.stringify({ eins: "13-1837418;53-0196605;06-0646973", format: "both" }) }); const { job_id } = await resp.json(); // Poll until complete const poll = async () => { const res = await fetch( `https://api.givalgo.ai/v1/bulk-verify/${job_id}`, { headers: { "x-api-key": "YOUR_API_KEY" } } ); const data = await res.json(); if (data.status === "COMPLETED") return data; await new Promise(r => setTimeout(r, 2000)); return poll(); }; const results = await poll();
Submit Bulk Job
Submit EINs for bulk verification. Returns 202 Accepted with a job_id for tracking.
JSON body (semicolon-separated EINs)
curl -X POST "https://api.givalgo.ai/v1/bulk-verify" \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "eins": "13-1837418;53-0196605;06-0646973", "webhook_url": "https://your-server.com/hook", "format": "both" }'
CSV file upload
curl -X POST "https://api.givalgo.ai/v1/bulk-verify" \ -H "x-api-key: YOUR_API_KEY" \ -F "file=@organizations.csv" \ -F "webhook_url=https://your-server.com/hook"
CSV must have an ein column header (case-insensitive). Falls back to the first column if no header match.
Request body fields
| Field | Type | Required | Description |
|---|---|---|---|
eins | string | Yes* | Semicolon-separated EINs. *Not needed for CSV upload. |
webhook_url | string | No | URL to POST results to on job completion. |
format | string | No | Result format: "json", "csv", or "both" (default). |
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
skip_invalid | boolean | false | If true, skip invalid EINs and process only valid ones. If false, return a 400 error listing all invalid EINs. |
Response (202 Accepted)
{
"job_id": "bulk_a1b2c3d4e5f6",
"status": "PROCESSING",
"total_eins": 247,
"duplicates_removed": 3,
"estimated_seconds": 8,
"poll_url": "/v1/bulk-verify/bulk_a1b2c3d4e5f6",
"created_at": "2026-03-25T14:30:00Z"
}Validation error (400)
If any EINs fail validation (and skip_invalid is not set), you get a 400 with details:
{
"error": "VALIDATION_ERROR",
"message": "3 EINs failed validation",
"invalid_eins": [
{ "ein": "123", "error": "EIN must be exactly 9 digits" }
],
"valid_count": 247,
"hint": "Add ?skip_invalid=true to process only valid EINs."
}Poll Job Status
Check the progress and retrieve results of a bulk verification job. Jobs are scoped to your API key — you can only access jobs you created.
In progress
{
"job_id": "bulk_a1b2c3d4e5f6",
"status": "PROCESSING",
"progress": {
"total": 247,
"completed": 180,
"failed": 2,
"percent_complete": 73.7
}
}Completed
For jobs with 1,000 or fewer EINs, results are included inline. Larger jobs return a csv_download_url only. Each result in the array is a full single-verify response — identical to what you'd get from the /v1/verify endpoint, including organization details, Pub78, revocation history, and OFAC sanctions screening.
{
"job_id": "bulk_a1b2c3d4e5f6",
"status": "COMPLETED",
"summary": {
"eligible": 200,
"not_deductible": 30,
"revoked": 5,
"not_found": 8,
"ofac_flags": 3
},
"results": [
{
"ein": "13-1837418",
"ein_raw": "131837418",
"status": "ELIGIBLE",
"deductible": true,
"message": "Organization is eligible to receive tax-deductible donations.",
"organization": { /* full org details: name, city, state, NTEE, assets, ... */ },
"pub78": { /* listed, deductibility_code, description */ },
"revocation": { /* ever_revoked, currently_revoked, dates */ },
"sanctions_screening": { /* status, org & leadership screening, matches */ },
"checked_at": "2026-03-25T23:11:10Z",
"api_version": "v1"
},
// ... one entry per EIN, same structure as single /v1/verify response
],
"csv_download_url": "https://...presigned...",
"completed_at": "2026-03-25T14:30:07Z"
}CSV download
The csv_download_url (pre-signed S3 URL, valid 1 hour) contains a flattened version of the full results with 37 columns covering organization details, Pub78 status, revocation history, and OFAC screening. Column headers:
ein, status, deductible, message, org_name, org_city, org_state, subsection_code, subsection_label, deductibility_code, deductibility_label, foundation_code, foundation_label, status_code, status_label, affiliation_code, affiliation_label, group_exemption_number, ruling_date, ntee_code, asset_amount, income_amount, revenue_amount, pub78_listed, pub78_deductibility_code, pub78_deductibility_description, pub78_via_group_exemption, ever_revoked, currently_revoked, revocation_date, revocation_posting_date, reinstatement_date, sanctions_status, ofac_org_matches_found, ofac_leadership_matches_found, screened_at, error_message, checked_at
Job statuses
| Status | Meaning |
|---|---|
PROCESSING | Job is actively being processed by background workers. |
COMPLETED | All EINs have been verified. Results are available. |
Webhooks
If you provide a webhook_url when submitting a bulk job, we'll POST a notification when the job completes. This is the recommended approach for large jobs instead of polling.
Webhook payload
# POST to your webhook_url # Headers: # Content-Type: application/json # User-Agent: Givalgo-Webhook/1.0 # X-Givalgo-Event: bulk_verify.completed # X-Givalgo-Job-Id: bulk_a1b2c3d4e5f6 { "event": "bulk_verify.completed", "job_id": "bulk_a1b2c3d4e5f6", "status": "COMPLETED", "total_eins": 247, "completed": 245, "failed": 2, "summary": { "eligible": 200, "not_deductible": 30, "ofac_flags": 3 }, "csv_download_url": "https://...presigned-url...24hr-expiry...", "poll_url": "/v1/bulk-verify/bulk_a1b2c3d4e5f6" }
Retry policy
Webhook delivery is attempted up to 3 times with exponential backoff (1s, 5s delays). If your endpoint returns a 2xx status, delivery is marked as successful. The csv_download_url is a pre-signed S3 URL valid for 24 hours.
Throughput
| EINs | Estimated Time |
|---|---|
| 10 | ~5 seconds |
| 50 | ~15 seconds |
| 250 | ~30 seconds |
| 1,000 | ~2 minutes |
| 20,000 | ~40 minutes |
Job Statuses
A bulk job progresses through these statuses:
| Status | Meaning |
|---|---|
PROCESSING | Job is queued and actively being processed by background workers. Poll for progress updates. |
COMPLETED | All EINs have been verified. Results are available inline (for jobs ≤ 1,000 EINs) and via CSV download URL. |
Verification Statuses
Each EIN in a bulk job receives the same verification statuses as the single Verify endpoint:
| Status | Deductible | Meaning |
|---|---|---|
ELIGIBLE | true | Listed in IRS Pub 78 (directly or via group exemption). Eligible for tax-deductible donations. |
NOT_DEDUCTIBLE | false | In IRS records but not tax-deductible (e.g., 501(c)(4), 501(c)(6)). |
REVOKED | false | Tax-exempt status auto-revoked by the IRS for non-filing. May appear even if the organization has dropped off the Business Master File. |
CAUTION | null | In IRS master file as 501(c)(3) but NOT in Pub 78. May be a data timing lag — verify via the IRS Tax Exempt Organization Search. |
NOT_FOUND | null | Not in IRS records and not on the revocation list. Churches and self-declared orgs may not appear. |
Limits & Throughput
Bulk job limits are applied per API key based on your plan tier.
| Limit | Value |
|---|---|
| Max EINs (JSON body) | 250 |
| Max EINs (CSV upload) | 20,000 |
| Max concurrent jobs | 5 per API key |
| Result retention | 30 days |
| CSV download URL expiry | 24 hours |
Estimated processing times
| EINs | Estimated Time |
|---|---|
| 10 | ~5 seconds |
| 50 | ~15 seconds |
| 250 | ~30 seconds |
| 1,000 | ~2 minutes |
| 20,000 | ~40 minutes |
Processing time depends on current load and Lambda warm-start state. For time-sensitive workloads, use a webhook for instant notification on completion.
Report API
Generate professional, branded PDF verification reports for any U.S. nonprofit — ready to share with donors, board members, or compliance teams.
Overview
The Report API takes an EIN and returns a multi-page PDF document containing the same verification data as the Verify endpoint — presented in a polished, print-ready format with Givalgo branding.
Each report includes a cover page, verification outcome with status badge, IRS data breakdown, OFAC sanctions screening results, financial snapshot, and a branded back page.
application/pdf
Authentication
The Report API uses the same API key authentication as the Verify and Bulk Verify endpoints. Include your key in the x-api-key header:
curl -H "x-api-key: YOUR_API_KEY" \ -H "Accept: application/pdf" \ "https://api.givalgo.ai/v1/report?ein=13-1837418" \ -o report.pdf
Quickstart
Generate your first PDF report in seconds:
# Download a verification report for Candid (EIN 13-1837418) curl -H "x-api-key: YOUR_API_KEY" \ -H "Accept: application/pdf" \ "https://api.givalgo.ai/v1/report?ein=13-1837418" \ -o candid-verification.pdf # Open the PDF open candid-verification.pdf
Tip: Include the Accept: application/pdf header to receive decoded binary PDF.
In Postman, use Send and Download (dropdown next to Send) to save the file.
Report Endpoint
Takes an EIN and returns a professionally formatted PDF verification report. The underlying data is identical to the /v1/verify endpoint — the Report API simply renders it into a branded, multi-page PDF document.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ein | string | Yes | Employer Identification Number. Accepts 13-1837418, 131837418, or 13 1837418. |
Headers
| Header | Required | Description |
|---|---|---|
x-api-key | Yes | Your API key |
Accept | Recommended | Set to application/pdf for decoded binary response |
Success Response
| Property | Value |
|---|---|
| Status Code | 200 OK |
| Content-Type | application/pdf |
| Content-Disposition | inline; filename="npo-verify-{ein}.pdf" |
Error Responses
Error responses are returned as JSON (not PDF):
| Status | Error Code | Description |
|---|---|---|
400 | MISSING_EIN | The ein query parameter was not provided |
400 | INVALID_EIN | EIN format is invalid (not 9 digits) |
403 | Forbidden | Missing or invalid API key |
500 | INTERNAL_ERROR | Server-side error during PDF generation |
Note: All valid verification statuses (ELIGIBLE, REVOKED, NOT_FOUND, CAUTION, NOT_DEDUCTIBLE) return a 200 with a PDF. Only auth or input errors return JSON.
Report Sections
Each generated PDF contains the following pages:
| Page | Section | Content |
|---|---|---|
| 1 | Cover Page | Givalgo branding, organization name, EIN, report generation date |
| 2 | Outcome & Details | Large status badge (color-coded), deductibility verdict, organization details (city, state, subsection, NTEE code, ruling date) |
| 3 | IRS Status Breakdown | EO BMF status & deductibility, Pub 78 listing, group exemption details, revocation history with dates |
| 4 | OFAC Screening | Organization & leadership sanctions screening status, match details (if any), data source year |
| 5 | Financial Snapshot | Total assets, annual income, annual revenue (from IRS BMF data) |
| 6 | Back Page | Disclaimer, API version, generation timestamp, contact info |
Verification Statuses
The report displays the same verification statuses as the Verify endpoint, rendered as color-coded badges:
| Status | Badge Color | Deductible | Meaning |
|---|---|---|---|
ELIGIBLE | ● Green | Yes | Listed in IRS Pub 78. Eligible for tax-deductible donations. |
NOT_DEDUCTIBLE | ● Orange | No | In IRS records but not tax-deductible. |
REVOKED | ● Red | No | Tax-exempt status auto-revoked by the IRS. |
CAUTION | ● Yellow | Unconfirmed | In IRS master file as 501(c)(3) but not in Pub 78. |
NOT_FOUND | ● Gray | Unknown | Not in IRS records. Churches and self-declared orgs may not appear. |
Important Notes
Response Time
PDF generation typically takes 2–4 seconds (cold start may add 3–5 seconds on first request). The API Gateway timeout is 29 seconds.
Data Source
Reports contain the same data as the /v1/verify endpoint. The PDF is generated on-the-fly from live verification data — it is not cached. Each request produces a fresh report with the current timestamp.
File Size
Reports are typically 115–130 KB depending on the amount of data (e.g., OFAC matches increase size slightly).
Disclaimer
Each report includes a footer disclaimer: "This report is generated from publicly available IRS data and OFAC sanctions lists. It does not constitute legal or tax advice."
Data API
Structured access to every meaningful number, ratio, and peer benchmark from U.S. nonprofit Form 990 filings — for 3.3M+ filings covering 1.9M+ unique organizations.
Overview
The Data API turns raw IRS e-file XML into a clean JSON response covering financials, compensation, programs, governance, fundraising, liquidity, expense composition, related organizations, foreign activity, and more. Every core ratio is benchmarked against peer cohorts (NTEE major group × revenue band × state), so you see not just the number but where it sits in its sector.
Two tiers share the same endpoint family:
/v1/dataBase — ~150 fields, all core sections, all peer benchmarks/v1/data-proPro — base + three deep-detail attachments (~410 fields total)
Tiers: Data vs Data Pro
Tier is determined entirely by the endpoint path — there is no public include= parameter. Both tiers accept the same query parameters (ein, tax_year) and require the same x-api-key header.
| Section | /v1/data Base | /v1/data-pro Pro |
|---|---|---|
organization — identity, NTEE, mission | ✓ | ✓ |
financials — revenue, expenses, balance sheet | ✓ | ✓ |
trends — 6-year annual series + CAGR + trend labels | ✓ | ✓ |
compensation — officers, by_role, peer benchmarks | ✓ | ✓ |
funding_sources — grantmakers received from | ✓ | ✓ |
programs — program descriptions + expenses | ✓ | ✓ |
governance — board + policies | ✓ | ✓ |
fundraising — events, professional fundraisers | ✓ | ✓ |
financial_profile — liquidity, HHI, expense composition New | ✓ | ✓ |
related_organizations | ✓ | ✓ |
foreign_activities, lobbying_and_political, donor_advised_funds | ✓ | ✓ |
data_freshness | ✓ | ✓ |
financials_detail — full Schedule A-D line items Pro | – | ✓ |
governance_detail — full board roster, policies, minutes | – | ✓ |
registration — Schedule R + B + state-level filings | – | ✓ |
New indicates fields added in the April 2026 release.
Authentication
All requests require an API key passed in the x-api-key header. Keys are scoped to a usage plan (Free, Base, Pro) which determines rate limits and tier access.
# Base tier curl -H "x-api-key: YOUR_API_KEY" \ "https://api.givalgo.ai/v1/data?ein=53-0196605" # Pro tier curl -H "x-api-key: YOUR_API_KEY" \ "https://api.givalgo.ai/v1/data-pro?ein=53-0196605"
To upgrade to Pro or request a trial key, contact support@givalgo.ai.
Quickstart
cURL — most recent filing
curl -H "x-api-key: YOUR_API_KEY" \ "https://api.givalgo.ai/v1/data?ein=53-0196605"
cURL — specific tax year
curl -H "x-api-key: YOUR_API_KEY" \ "https://api.givalgo.ai/v1/data?ein=53-0196605&tax_year=2022"
Python
import requests r = requests.get( "https://api.givalgo.ai/v1/data-pro", params={"ein": "53-0196605"}, headers={"x-api-key": "YOUR_API_KEY"}, ) data = r.json() name = data["organization"]["name"] prog_pct = data["financial_profile"]["expense_composition"]["program_expense_ratio"] peer_median = data["financial_profile"]["expense_composition"] \ ["peer_benchmarks_by_metric"]["program_expense_ratio"] \ ["by_ntee_and_revenue_band_and_state"]["median"] print(f"{name}: program = {prog_pct:.0%}, peer median = {peer_median:.0%}")
JavaScript
const r = await fetch( "https://api.givalgo.ai/v1/data?ein=53-0196605", { headers: { "x-api-key": "YOUR_API_KEY" } } ); const data = await r.json(); console.log(data.organization.name, data.trends.computed.revenue_trend);
Endpoints
Returns base sections (~150 fields): organization, financials, trends, compensation, funding_sources, programs, governance, fundraising, financial_profile, related_organizations, foreign_activities, lobbying_and_political, contributor_summary, donor_advised_funds, data_freshness.
Returns the base shape plus three detail attachments (~410 fields total): financials_detail, governance_detail, registration.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
ein | string | Yes | Employer Identification Number. Accepts 53-0196605, 530196605, or 53 0196605. |
tax_year | integer | No | 4-digit fiscal year (e.g. 2022). Omit to get the most recent filing. If the requested year has no filing, the response is a 404 with a years_available array. |
Response Top-Level
| Field | Type | Description |
|---|---|---|
ein | string | Hyphenated EIN (e.g. "53-0196605"). |
tax_year | integer | Fiscal year of the filing returned. |
return_type | string | "990", "990EZ", or "990PF". |
filing_date | string (ISO date) | Date IRS received the filing. |
organization | object | Identity, address, NTEE code, mission, formation year, total employees/volunteers. |
financials | object | Summary, revenue breakdown, expenses, balance sheet, and (Pro only) detail sub-object. |
trends | object | Up to 6 years of annual data + computed CAGRs + trend labels. |
compensation | object | People array, by-role highlights, per-employee average, peer benchmark cubes. |
funding_sources | object | Grants received: total_unique_grantmakers, grantmakers[], annual_totals[]. |
grants_made | object[] | Outbound grants (Schedule I), top 50 for the year. Gated by ?include=funding. |
programs | object[] | Program service accomplishments. |
governance | object | Board structure, policies, meeting minutes flags. |
fundraising | object | metrics, events[], contractors[], activity_methods, licensed_states. |
financial_profile | object | Liquidity, revenue concentration (HHI), operating sustainability, expense composition New. All with peer benchmarks. |
related_organizations | object[] | Schedule R-style related entities. |
foreign_activities | object[] | Schedule F Part I region-level summary. |
lobbying_and_political | object | Schedule C summary. |
contributor_summary | object | Schedule B contributor aggregates. |
donor_advised_funds | object | null | DAF flags + balances (if Schedule D.I present). |
conservation_easements New | object | Schedule D Part II. Always-on; present only when held. |
art_collections New | object | Schedule D Part III. Always-on; present only when held. |
private_foundation New | object | Form 990-PF metrics. Always-on; 990-PF filers only. |
hospitals New | object | Schedule H. Gated by ?include=hospitals; 501(c)(3) hospital filers only. |
disclosures Pro | object | Schedules K/L/M/N/F/A/O. Gated by ?include=disclosures. |
registration Pro | object | Registration and state-level filings detail. |
data_freshness | object | filing_source, most_recent_tax_year, filing_date, last_filing_date, years_available[], includes_applied[]. |
organization
| Field | Type | Description |
|---|---|---|
name | string | Legal name on the filing. |
legal_name New | string | null | Candid-parity IRS-filed legal name. Same source as name — kept as a distinct key for path-compat with platforms that split popular-name vs. registered-name. |
also_known_as | string | null | DBA, if present. |
address_type New | string | Always "PRIMARY" on the main organization address. Distinguishes from operations.books_in_care_of.address_type which is "BOOKS_IN_CARE_OF". |
address, city, state, zip | string | Mailing address. |
address_line_2 New | string | null | Second address line from the Form 990 filing header. Often null; filers usually pack everything into address. |
phone, website | string | null | Contact info. |
formation_year | integer | Year of formation. |
mission | string | Mission statement text. |
principal_officer | string | null | Name of principal officer from Form 990 header. |
ntee_code | string | Full NTEE code (e.g. "P210"). |
ntee_description | string | Human-readable NTEE major group (e.g. "Human Services"). |
ntee_codes.primary_code New | string | null | Single-letter NTEE major code (A–Z). E.g. "E" for Health Care. |
ntee_codes.primary_description New | string | null | Description of major code. E.g. "Health Care". |
ntee_codes.sub_code New | string | null | 3- or 4-char NTEE sub-classification from the NCCS taxonomy lookup. E.g. "E21". |
ntee_codes.sub_description New | string | null | Description of the sub-code. E.g. "Community Health Systems". |
is_national_hq New | boolean | True when BMF affiliation code = 1 or 6 (central parent of a group ruling). False otherwise. |
is_non_bmf_org New | boolean | True when no row exists in eo_bmf for this EIN. Very rare — would suggest filing without IRS BMF registration. |
ruling_year | integer | null | Year IRS granted tax-exempt status. |
total_employees, total_volunteers | integer | As reported on the filing. |
financials
| Field | Type | Description |
|---|---|---|
accounting_method New | string | null | "Accrual", "Cash", or null. From Form 990 Part XII Line 1 (MethodOfAccountingAccrualInd). Applies to all return types. |
summary | object | total_revenue, total_expenses, revenue_less_expenses, total_assets_eoy, total_liabilities_eoy, net_assets_eoy. |
revenue | object | contributions_and_grants, program_service_revenue, investment_income, other_revenue, total. |
revenue.gross_sales New | integer | null | 990-EZ Part I Line 7a — gross sales of inventory. Null on full 990 / 990-PF. |
revenue.cost_goods New | integer | null | 990-EZ Part I Line 7b — cost of goods sold. Null on full 990 / 990-PF. |
revenue.gross_profit New | integer | null | 990-EZ Part I Line 7c (gross_sales − cost_goods). Null on full 990 / 990-PF. |
revenue.revenue_sales New | integer | null | Net gain/(loss) on sales of assets (Part VIII Line 7d). Candid-parity alias for net_gain_loss_assets. |
revenue.part_viii_line_detail Pro | object | null | Form 990 Part VIII columnar line splits (full-990 only). Nested: investment_income_bond_proceeds (Line 4); rental {gross_rents / rental_expenses / net_rental_income × real & personal, Lines 6a–6c}; sales_of_assets {gross_amount / cost_basis / gain_loss × securities & other, Lines 7a–7c}; gaming_direct_expenses (Line 9b). Gated by ?include=financials_detail. |
expenses | object | program_services, management_and_general, fundraising, total, and allocation (program_pct, fundraising_pct). |
expenses.professional_fees New | integer | null | Part IX Lines 11a–11g sum. Promoted from financial_profile.expense_composition for response-shape clarity. |
expenses.other_expenses New | integer | null | Part IX Line 24e — "Other Expenses" rollup. 990-EZ Part I Line 16 maps directly. |
expenses.total_expense_disbursements New | integer | null | 990-PF Part I col D total charitable disbursements (Line 26). PF-only; null on 990 / 990-EZ. |
expenses.expense_operating_admin New | integer | null | Candid-parity field. On 990 / 990-EZ aliases management_and_general; on 990-PF derived as total_expenses − pf_disb_charitable_total (approximates PF Part I Line 24). |
expenses.expense_operating_admin_is_derived_for_pf New | boolean | True on PF returns where the value is derived (not directly reported). False on 990 / 990-EZ. |
expenses.joint_costs_indicator New | boolean | null | Part IX Line 26 — whether the org reported joint costs from a combined educational-campaign + fundraising solicitation. The IRS e-file schema carries only this boolean, not the 4-column dollar split. |
balance_sheet | object | Cash, investments, PP&E, assets, liabilities, net assets (with unrestricted split). |
balance_sheet.investments_us_government New | integer | null | 990-PF Part II Line 10a FMV — US Government obligations. PF-only. |
balance_sheet.investments_stock New | integer | null | 990-PF Part II Line 10b FMV — corporate stock. PF-only. |
balance_sheet.investments_bonds New | integer | null | 990-PF Part II Line 10c FMV — corporate bonds. PF-only. |
balance_sheet.investments_other New | integer | null | 990-PF Part II Line 13 FMV — other investments. PF-only. |
balance_sheet.capital_stock_trust_principal_boy / _eoy New | integer | null | Part X Line 30 (BOY/EOY) — capital stock or trust principal, or current funds. Populated only for the ~5% of orgs using the stock-corporation / trust-principal framework instead of net assets; null otherwise. |
balance_sheet.paid_in_capital_surplus_boy / _eoy New | integer | null | Part X Line 31 (BOY/EOY) — paid-in or capital surplus, or land/building/equipment fund. Stock-corp framework only. |
balance_sheet.retained_earnings_boy / _eoy New | integer | null | Part X Line 32 (BOY/EOY) — retained earnings, endowment, accumulated income, or other funds. Stock-corp framework only. |
prior_year New | object | null | Prior-year revenue/expense figures the org self-reported in the "Prior Year" column of this return — a one-line YoY comparison without a second request for tax_year−1. Present only when ≥1 prior-year value is non-null; absent for first-year filers and 990-PF returns. Sub-objects: tax_year (string); summary {total_revenue, total_expenses, revenue_less_expenses}; revenue {contributions_and_grants, program_service_revenue, investment_income, other_revenue, total}; expenses {salaries_and_benefits, grants_paid, total}. Form 990 carries prior-year figures for the summary lines only (no prior-year balance sheet). |
expense_detail_ez New | object | null | 990-EZ Part I expense line items (Lines 10–18) for the flatter EZ expense structure: benefits_paid_to_members (L10), professional_fees (L13, independent contractors), occupancy_rent_utilities (L14), printing_publications_postage (L15), excess_or_deficit_for_year (L18). Present only on 990-EZ returns with ≥1 non-null value; null on full-990 and 990-PF. (EZ revenue gross/cost/profit live under revenue.) |
detail Pro | object | null | Full Part VIII / Part IX / Schedule D line-by-line breakdown. null on base tier. |
financial_documents New
Candid-parity filing-document links. Synthesized from EIN + object_id + return_type via ProPublica Nonprofit Explorer (we don't host PDFs directly; ProPublica's open viewer is the de-facto public equivalent).
| Field | Type | Description |
|---|---|---|
form990_url | string | null | ProPublica Nonprofit Explorer URL for the filing. Form-type segment maps as 990 → /IRS990, 990-EZ → /IRS990EZ, 990-PF → /IRS990PF. Null when EIN or object_id is missing. |
trends
| Field | Type | Description |
|---|---|---|
years_available | integer[] | All tax years on file for this EIN. |
annual[] | object[] | Per-year rollup: total_revenue, total_expenses, total_assets_eoy, net_assets_eoy, contributions, program_service_revenue, investment_income, program_expense_ratio, fundraising_expense_ratio, months_of_cash, total_employees, top_officer_comp. |
computed.years_of_data | integer | Count of annual entries returned. |
computed.revenue_cagr_pct | number | Compound annual growth rate of revenue. |
computed.expense_cagr_pct | number | CAGR of expenses. |
computed.asset_cagr_pct | number | CAGR of net assets. |
computed.revenue_trend | string | Label: GROWING (>3% CAGR), STABLE, or DECLINING (<−3%). |
computed.expense_trend New | string | Matching label for expense CAGR. |
computed.asset_trend New | string | Matching label for asset CAGR. |
compensation
Top-level scalars are drawn from Form 990 Part VII (officers, key employees, highest-paid) and Part IX (salaries & benefits aggregate).
Top-level fields
| Field | Type | Description |
|---|---|---|
tax_year | integer | Fiscal year this compensation data belongs to. |
people_count | integer | Number of people in the people[] array. |
employees_over_100k New | integer | null | Schedule J Part I Line 1 — total count of individuals receiving > $100K in reportable compensation. Org-wide count from the filing; distinct from people_count (the number of Part VII Section A people listed individually). null when Schedule J is not filed. |
people[] | object[] | Array of Part VII persons with name, title, hours_per_week, is_officer, is_key_employee, is_director, is_highest_paid, reportable_comp_org, reportable_comp_related, other_compensation, total_compensation. |
highest_paid_person | string | Name of the highest-paid person in the list. |
highest_compensation | integer | Dollar amount. |
comp_to_expense_pct | number | Sum of Part VII compensation ÷ total expenses, as a percent. |
top_officer_comp_to_revenue_pct New | number | Top officer total comp ÷ total revenue, as a percent. Scale-normalized so small and large orgs can be compared fairly. |
avg_compensation_per_employee New | integer | Whole-org payroll ÷ total employees, in dollars. Sourced from Form 990 Part IX Lines 5-10 (salaries + benefits + pension + payroll tax). Populated for ~29% of filings where both fields are non-zero. |
by_role New
Highest-paid person whose title matches common patterns for each role. null per role if no match.
| Field | Type | Description |
|---|---|---|
by_role.ceo | object | null | {title, total_compensation}. Matches titles like Executive Director, Chief Executive, President, CEO. |
by_role.cfo | object | null | Matches titles like Chief Financial Officer, CFO, Treasurer, Director of Finance, VP Finance. |
by_role.development_director | object | null | Matches Chief Development Officer, Development Director, VP Development, Chief Advancement Officer. |
peer_benchmarks_by_metric New
One cube per metric — see How Cubes Work. Metrics with no peer data (e.g. small revenue bands) are omitted.
top_officer_comp— absolute top-officer dollar amountstop_officer_comp_to_revenue_pct— scale-normalizedceo_comp,cfo_comp,dev_director_comp— role-specific benchmarksavg_compensation_per_employee— whole-org payroll per FTE
The legacy key peer_benchmarks (top-level, not nested) remains for backwards compatibility and mirrors peer_benchmarks_by_metric.top_officer_comp.
schedule_j_supplemental New
Best-effort parse of the Schedule J Part III narrative (Part I Lines 4A/4B free text). Present only when the filing has Schedule J narrative text.
| Field | Type | Description |
|---|---|---|
severance_payments[] | object[] | Each {person_name, amount}. Severance paid during the year. |
accrued_severance_unpaid[] | object[] | Each {person_name, amount}. Severance accrued but not yet paid. |
retirement_plan_changes[] | object[] | Each {person_name, amount}. Supplemental retirement / deferred-comp amounts. |
raw_narrative[] | object[] | Each {reference, explanation} — the unparsed Schedule J narrative entries. |
Note: each individual compensation_breakdown object in people[] also carries the Schedule J Part II base/bonus/deferred/nontaxable split (filing_org + related_orgs) for people listed on Schedule J.
funding_sources
Aggregated from Schedule I of grantmakers that reported this EIN as a grant recipient.
| Field | Type | Description |
|---|---|---|
total_unique_grantmakers | integer | Count of distinct grantmakers returned in grantmakers[]. |
grantmakers[] | object[] | Up to 50 grantmakers (by total awarded): grantmaker_ein, grantmaker_name, grants_count, total_awarded, most_recent_year, most_recent_amount, purpose. |
annual_totals[] | object[] | Per-year: tax_year, grants_received, unique_grantmakers. |
programs & grants
| Field | Type | Description |
|---|---|---|
programs[] | object[] | Program service accomplishments: sequence, description, expenses, grants_included, revenue, beneficiaries. |
grants_made[] | object[] | Top-level outbound grants (Schedule I), top 50 by amount for the current year: recipient_name, recipient_ein, recipient_address, recipient_city, recipient_state, recipient_zip, irc_section, relationship, purpose, cash_amount, noncash_amount, noncash_description. Gated by ?include=funding. |
governance
| Field | Type | Description |
|---|---|---|
voting_board_members | integer | Total voting members. |
independent_board_pct | number | Percent independent. |
has_conflict_of_interest_policy | boolean | Part VI Line 12. |
has_whistleblower_policy, has_document_retention_policy | boolean | Part VI Lines 13-14. |
detail Pro | object | null | Full board roster + minutes-kept flags + compensation review process. null on base tier. |
fundraising
| Field | Type | Description |
|---|---|---|
metrics | object | cost_to_raise_a_dollar, fundraising_roi, fundraising_expense_pct. |
events[] | object[] | Schedule G Part II: event_name, gross_receipts, charitable_contributions, gross_revenue, direct_expenses, direct_expense_breakdown (6 sub-fields), net_income. |
activity_methods New | object | null | Schedule G Part I solicitation-method booleans: mail_solicitations, email_solicitations, phone_solicitations, in_person_solicitations, solicitation_of_non_govt_grants, solicitation_of_govt_grants, special_fundraising_events. null when no flags are populated. |
licensed_states New | string | null | Schedule G Part I — states where the org is registered/licensed to solicit contributions (raw filing value). |
contractors[] New
Schedule G Part I — paid fundraising contractors. Always-on (no include gate). Distinct from operations.contractors[] (Form 990 Part VII Section B top-5 highest-paid independent contractors).
| Field | Type | Description |
|---|---|---|
name | string | Contractor / firm name. |
activity_description | string | Description of fundraising activity. |
is_fundraiser | boolean | True when this entity is identified as a professional fundraiser (vs. another activity type). |
has_custody_of_funds | boolean | True when the contractor has custody / control of contributions. |
gross_receipts | integer | Gross receipts from the activity. |
amount_paid_to_org | integer | Amount retained by the org (net of contractor share). |
amount_paid_to_fundraiser | integer | Amount paid to or retained by the contractor. |
financial_profile
Our headline analytics section — every ratio here comes with a peer benchmark cube.
liquidity
| Field | Type | Description |
|---|---|---|
months_of_cash | number | Cash & savings ÷ monthly expenses. |
months_of_liquid_assets | number | Cash + savings + publicly traded investments, over monthly expenses. |
operating_reserve_months New | number | Unrestricted net assets ÷ monthly expenses. The standard donor-facing operating-reserve figure. |
peer_benchmarks | object | Legacy: 7-cut cube for months_of_cash. |
peer_benchmarks_by_metric New | object | Cubes for months_of_cash and operating_reserve_months. |
revenue_concentration
| Field | Type | Description |
|---|---|---|
herfindahl_index | number | HHI computed across 5 revenue buckets (contributions, program service, investment, fundraising events, other). Lower = more diversified. |
diversification_level | string | DIVERSIFIED (HHI < 0.30), MODERATE (0.30–0.55), or CONCENTRATED (≥ 0.55). Thresholds rebased April 2026 to match the real HHI floor of 0.20 (5 equal buckets). |
diversification_description New | string | Plain-English explanation of the bucket. |
index_range New | object | {min: 0.20, max: 1.00, buckets: 5, note: ...} — so consumers know how to interpret the scalar. |
operating_sustainability
| Field | Type | Description |
|---|---|---|
operating_margin_pct | number | (Revenue − expenses) ÷ |revenue|, percent. |
operating_reserve_months | number | Same as liquidity. |
peer_benchmarks_by_metric New | object | Cubes for both metrics. |
expense_composition New
Two views of where the dollars go — the functional split Charity Navigator uses, plus the FASB-required natural-category split from Form 990 Part IX.
Functional view (program / admin / fundraising)
| Field | Type | Description |
|---|---|---|
program_expense_ratio | number | Program services ÷ total expenses × 100. The traditional "how much goes to mission" ratio. |
admin_expense_ratio | number | Management & general ÷ total expenses × 100. |
fundraising_expense_ratio | number | Fundraising ÷ total expenses × 100. |
cost_to_raise_a_dollar | number | Fundraising expense ÷ contributions. Lower is more efficient. |
comp_to_expense_pct | number | Top-N compensation as percent of total expenses. |
Natural view (FTA — Part IX line items) New
| Field | Type | Description |
|---|---|---|
salaries_benefits_ratio | number | Part IX lines 5–10 ÷ total expenses × 100. Labor intensity — service-delivery orgs run 60–80%; grant-makers much lower. |
professional_fees_ratio | number | Part IX lines 11a–11g ÷ total expenses × 100. High values can flag heavy consultant / outside-fundraiser reliance. |
occupancy_ratio | number | Part IX line 16 ÷ total expenses × 100. Real-estate-heavy orgs (museums, hospitals) run higher. |
travel_ratio | number | Part IX line 17 ÷ total expenses × 100. |
grants_paid_ratio | number | Part IX lines 1–3 ÷ total expenses × 100. Grant-making foundations run very high; direct-service orgs near zero. |
salaries_benefits · professional_fees · occupancy · travel · grants_paid | integer | Raw Part IX dollar amounts — for callers that want their own cut (e.g. $/employee, $/beneficiary). |
peer_benchmarks_by_metric | object | Percentile cubes for the functional ratios + the two most universally benchmarkable FTA ratios (salaries_benefits_ratio, professional_fees_ratio). Occupancy / travel / grants_paid vary too much by org type to percentile meaningfully. |
total_expenses_before_depreciation New | integer | null | Candid-parity. Derived: total_expenses − depreciation. Falls back to total_expenses unchanged when depreciation is unreported. |
total_expenses_percent_change_over_prior_year New | number | null | Candid-parity YoY % change in total_expenses. NULL when no prior-year filing exists for this EIN. |
Note: absolute third-party thresholds (Charity Navigator's 70% program benchmark, BBB Wise Giving's 65%, etc.) are deliberately NOT returned. Peer percentiles already place the org in its cohort, and absolute thresholds often penalize nonprofits for legitimate sector differences.
profitability New
Candid-parity profitability derivations from financial_trends_analysis.business_model_indicators. Always-on under financial_profile (no include gate).
| Field | Type | Description |
|---|---|---|
unrestricted_surplus_before_depreciation | integer | null | total_revenue − (total_expenses − depreciation). Falls back to total_revenue − total_expenses when depreciation is unreported. |
surplus_as_percent_of_expenses_before_depreciation | number | null | surplus_before_dep / expenses_before_dep × 100. |
total_revenue_percent_change_over_prior_year | number | null | YoY % change in total_revenue. NULL when no prior-year row exists. |
_inputs | object | Debug/audit trail: total_revenue, total_expenses, depreciation, prior_total_revenue, prior_total_expenses. Exposed so callers can verify and reproduce the math. |
full_cost_components New
Candid-parity "true cost of operating" composite. PARTIAL today — includes only the IRS-derivable components (expenses + depreciation). Does NOT include debt_principal_payment + fixed_asset_additions, which come from audited financials (not on the 990).
| Field | Type | Description |
|---|---|---|
one_month_of_savings | number | null | total_expenses / 12 — the dollar value of one month of operating runway. |
total_full_costs_estimated | integer | null | Partial composite: total_expenses + depreciation. Under-estimates Candid's full figure (which also includes audited-FS components). |
total_full_costs_is_partial | boolean | null | Always true until the audited-FS components surface. Flag so consumers don't mistake the partial sum for the full figure. |
total_full_costs_missing_components | string[] | null | Names of the components not included in the partial sum: ["debt_principal_payment", "fixed_asset_additions"]. |
balance_sheet_composition New
Candid-parity land/buildings/equipment basis + ratios. Sourced from Schedule D Part VI line rollups. NULL when filing has no Schedule D Part VI.
| Field | Type | Description |
|---|---|---|
gross_land_buildings_and_equipment_lbe | integer | null | Sum of Schedule D Part VI cost_or_basis_invest + cost_or_basis_other. NULL when filing has no Schedule D Part VI. |
less_accumulated_depreciation | integer | null | Sum of Schedule D Part VI accumulated_depreciation. |
accumulated_depreciation_as_percent_of_lbe | number | null | accumulated_dep / gross_lbe × 100. |
liabilities_as_percent_of_net_assets | number | null | total_liabilities / net_assets × 100. |
accounting_ratios New
Candid-parity liquidity ratio. IRS Form 990 does NOT break out current vs. non-current liabilities — we approximate "current liabilities" as Accounts Payable + Grants Payable + Deferred Revenue (Part X Lines 17+18+19).
| Field | Type | Description |
|---|---|---|
liquidity | number | null | cash_and_savings_eoy / current_liabilities_proxy. NULL when the proxy is zero or none of the three proxy components are populated. |
_inputs | object | Debug/audit trail: cash_and_savings_eoy, current_liabilities_proxy, components (AP / GP / DR), and a note explaining the proxy choice. |
operations New
Filing-level operations metadata. Always-on (no include gate).
contractors[] New
Top-5 highest-paid Form 990 Part VII Section B independent contractors. Distinct from fundraising.contractors[] (Schedule G Part I).
| Field | Type | Description |
|---|---|---|
name | string | Contractor / firm name. |
services | string | Description of services provided. |
compensation | integer | Annual compensation paid to the contractor. |
address New | string | null | Contractor business address line 1 (Part VII Section B). null when the filing does not list an address for the contractor. |
books_in_care_of New
Form 990 Part VI Line 20 — record-keeper contact (the person/firm responsible for keeping the books). Object emitted when at least one of the 5 fields is populated.
| Field | Type | Description |
|---|---|---|
address_type New | string | Always "BOOKS_IN_CARE_OF" when this block is present. Distinguishes from organization.address_type = "PRIMARY". |
name | string | Records-custodian name. |
city | string | City of records-custodian address. |
state | string | 2-letter state code. |
zip | string | ZIP code. |
phone | string | Phone number. |
Board / co-leader name fields New
Candid-parity board-leadership names derived from a title-text heuristic over the Part VII Section A people roster. Documented as a heuristic — not a structured IRS field. Each key is emitted only when a match is found.
| Field | Type | Description |
|---|---|---|
board_chair_name | string | null | First person whose title matches /chair|chairman|chairwoman|chairperson/i AND does NOT match /vice/i and was not already classified as co-chair. |
board_co_chair_name | string | null | First person whose title matches /co-chair|co chair|co-chairperson/i. |
co_leader_name | string | null | First person whose title matches /co-ceo|co ceo|co-president|co-executive director/i AND is_officer = true. |
disclosures New Pro
Schedule-shaped disclosure data — tax-exempt bonds, non-cash contributions, significant dispositions, foreign individual grants, and interested-person transactions. Gated by ?include=disclosures on /v1/data-pro.
Bug fix: ?include=disclosures is now self-sufficient. Previously this include was implicitly gated by ?include=governance, so callers asking only for disclosures got an empty section. Schedule L still appears when both includes are requested.
schedule_k.bonds[] New
Tax-exempt bond issues from Schedule K Parts I + IV. One row per bond.
| Field | Type | Description |
|---|---|---|
bond_ref_num | string | Issuer-supplied bond reference letter (A/B/C/D). |
issuer_name | string | Name of the issuing authority. |
issuer_ein | string | EIN of the issuer. |
cusip_number | string | CUSIP identifier for the bond issue. |
date_issued | string (date) | Date the bond was issued. |
issue_price_amt | integer | Issue price. |
issue_description | string | Description of the bond purpose. |
term_of_bond_yr | number | Term in years. |
maturity_date | string (date) | Maturity date. |
variable_rate_ind | boolean | True if variable-rate bond. |
deferred_issuance_costs_amt | integer | Deferred issuance costs. |
on_behalf_of_issuer_ind | boolean | True when the issuer was issued on behalf of the org. |
pooled_financing_ind | boolean | True for pooled-financing arrangements. |
private_loan_ind | boolean | True if proceeds funded a private loan. |
unspent_proceeds_amt | integer | Unspent bond proceeds remaining. |
acquired_bonds_amt | integer | Acquired bonds amount. |
nonqualified_bonds_outstanding | boolean | True when non-qualified bonds remain outstanding. |
arbitrage_yield | number | Arbitrage yield percentage. |
escrow_established_ind | boolean | True when defeasance escrow was established. |
defeasance_ind | boolean | True when bonds have been defeased. |
qualified_hedge_date | string (date) | Date of qualified hedge identification. |
no_private_biz_use_ind | boolean | True when no private business use is reported. |
voluntary_closing_agreement_ind | boolean | True when a voluntary closing agreement is in place. |
schedule_n.dispositions[] New
Significant disposition / liquidation detail (Schedule N). Only emitted when array is non-empty. Distinct from the top-level dissolution block (whole-org liquidation signal).
| Field | Type | Description |
|---|---|---|
description | string | Description of the asset / activity disposed. |
date | string (date) | Date of disposition. |
amount | integer | Amount of the disposition. |
acquirer | string | Name of acquirer / recipient. |
schedule_m.contributions[] New
Non-cash contribution types received during the tax year (Schedule M).
| Field | Type | Description |
|---|---|---|
type | string | Contribution-type label (e.g. Publicly-Traded Securities, Art, Vehicles). |
count | integer | Number of contributions of this type. |
revenue_amt | integer | Reported revenue amount. |
valuation_method | string | Method used to determine value (e.g. fair market value, appraisal). |
schedule_f New
Schedule F — foreign grants & activities. Distinct from the top-level foreign_activities[] (Part I region-level).
| Field | Type | Description |
|---|---|---|
individual_grants[] | object[] | Part III — grants to foreign individuals: region, purpose, recipient_count, cash_amount, disbursement_method, noncash_amount, noncash_desc. |
organization_grants[] | object[] | Part II — grants to foreign organizations: recipient_name, recipient_irc_section, recipient_ein, region, purpose, cash_amount, disbursement_method, noncash_amount, noncash_desc, valuation_method. |
metadata | object | null | Part II counts (irs_recognized_charity_count, other_organization_count, maintains_grant_records) + Part IV forms_required flags (form_926/3520/5471/8621/8865/5713). |
schedule_l New
Schedule L — transactions with interested persons. indicators / transactions carry the Part IV checklist flags + 990-PF self-dealing rows; the four named arrays carry Form 990 Parts I–IV grouped by type (each present only when it has rows). All transaction objects share the same leaf set: person_name, relationship, description, amount, in_default, corrected, excess_benefit_date, uncorrected_amt, loan_from_org_ind, loan_written_agreement, grant_recipient_rel, grant_type_desc.
| Field | Type | Description |
|---|---|---|
excess_benefit_transactions[] | object[] | Part I — excess benefit transactions. |
loans_with_interested_persons[] | object[] | Part II — loans to/from interested persons. |
grants_to_interested_persons[] | object[] | Part III — grants/assistance benefiting interested persons. |
business_transactions[] | object[] | Part IV — business transactions involving interested persons. |
schedule_a New
Schedule A — public charity status & public support test. Present only when the filing has a public-support block.
| Field | Type | Description |
|---|---|---|
public_charity_status | string | Public-charity classification (e.g. 170(b)(1)(A)(vi)). |
public_support_pct | number | Public-support percentage. |
section_509a2 | object | 509(a)(2) figures: public_support_amt, total_support_amt, investment_income_amt, public_support_cy_pct, thirty_three_pct_test_passed. |
supporting_org | object | 509(a)(3) metadata: type, supported_org_count, all_supported_orgs_listed, notifies_supported_orgs, is_type3_functionally_integrated, is_type3_non_functionally_integrated, controlled_by_supported_orgs. |
supplemental_narrative[] | object[] | null | Part VI narrative entries: {reference, explanation}. |
schedule_o New
Schedule O — supplemental narrative explanations. Flat array; each entry is {form_section, reference, explanation}.
dissolution New
Top-level block. Emitted ONLY when the org liquidated or ceased operations during the tax year (i.e. liquidation_date or cessation_of_operations_date is populated on the filing). Absent otherwise. Always-on.
| Field | Type | Description |
|---|---|---|
date | string (date) | Date of liquidation or cessation. |
type | string | LIQUIDATION or CESSATION_OF_OPERATIONS — reflects which underlying date column was populated. |
conservation_easements / art_collections / private_foundation New
Three top-level always-on blocks (no include gate). Each is present only when the org has the relevant data; absent otherwise.
conservation_easements
Schedule D Part II.
| Field | Type | Description |
|---|---|---|
held_at_eoy_count | integer | Easements held at end of year. |
total_acreage | number | Total acreage under easement. |
modifications_count | integer | Easements modified, transferred, released, extinguished, or terminated during the year. |
violations_count | integer | Easement violations identified during the year. |
art_collections
Schedule D Part III — art / historical-treasure collection policies (booleans).
| Field | Type | Description |
|---|---|---|
uses_revenue_for_public_purpose | boolean | Collection revenue is used for a public service purpose. |
loans_to_public | boolean | Collection items are loaned for public exhibition. |
accession_not_for_financial_gain | boolean | Items are accessioned for purposes other than financial gain. |
private_foundation 990-PF only
Form 990-PF metrics. Present ONLY on 990-PF filers; absent for public charities (990 / 990-EZ). Five top-level rollup scalars plus nested Part I col B/C/D walkers, Part II FMV breakdown, Part III changes-in-net-assets, and Part XII qualifying-distributions detail. Empty nested objects mean “section not filed”.
| Field | Type | Description |
|---|---|---|
total_assets_fmv | integer | Total assets at fair market value. |
qualifying_distributions | integer | Qualifying distributions (Part XII). |
distributable_amount | integer | Distributable amount (Part XI). |
min_investment_return | integer | Minimum investment return (Part X). |
excise_tax | integer | Excise tax on net investment income. |
net_investment_income | object | Part I col B walker: total, interest, dividends, capital_gain, other_income, total_expenses. |
adjusted_net_income, charitable_disbursements, … | object | Additional Part I col C/D walkers + Part II FMV breakdown, Part III rollforward, Part XII components. |
hospitals New
Schedule H data. Present ONLY for 501(c)(3) hospital filers that report at least one hospital facility. Gated by ?include=hospitals.
filing_summary
Org-wide Schedule H scalars (Parts I–III).
| Field | Type | Description |
|---|---|---|
has_financial_assistance_policy | boolean | Org has a written financial-assistance (charity-care) policy. |
total_community_benefit_at_cost | integer | Total community benefit at cost (Part I). |
direct_offsetting_revenue | integer | Direct offsetting revenue. |
net_community_benefit | integer | Net community benefit expense. |
community_benefit_pct_of_expenses | number | Net community benefit as a percent of total expenses. |
bad_debt_expense | integer | Bad debt expense (Part III Section A). |
medicare_revenue | integer | Medicare allowable revenue (Part III Section B). |
medicare_allowable_cost | integer | Medicare allowable cost. |
medicare_surplus_or_shortfall | integer | Medicare surplus (positive) or shortfall (negative). |
has_written_collection_policy | boolean | Org has a written debt-collection policy. |
hospital_facilities_count | integer | Number of hospital facilities reported. |
other_facilities_count | integer | Number of non-hospital health-care facilities. |
facilities[] · facility_policies[] · other_facilities[] · joint_ventures[] · community_benefit_by_category[]
| Field | Type | Description |
|---|---|---|
facilities[] | object[] | Part V Section A: facility_num, name, address_line1, city, state, zip, website, state_license, facility_types[] (tags: licensed_hospital, general_medical_surgical, childrens_hospital, teaching_hospital, critical_access, research_facility, er_24_hours, er_other), reporting_group, other_facility_desc. |
facility_policies[] | object[] | Part V Section B per facility: reporting_group, facility_name, chna (CHNA flags + years), fap (financial-assistance policy thresholds + flags), billing_and_collection (collection-activity flags). |
other_facilities[] | object[] | Part V Section D: facility_num, name, address_line1, city, state, zip, facility_type. |
joint_ventures[] | object[] | Part IV: entity_name, primary_activities, org_ownership_pct, officers_ownership_pct, physicians_ownership_pct. |
community_benefit_by_category[] | object[] | Part I by category: section, category, activities_or_programs_count, persons_served, total_community_benefit_expense, direct_offsetting_revenue, net_community_benefit_expense, expense_pct_of_total. |
related_organizations / foreign_activities / lobbying / DAFs
| Section | Source | Description |
|---|---|---|
related_organizations | Schedule R | Disregarded entities, related tax-exempt orgs, related taxable partnerships/corps. Counts + optionally names (Pro). |
related_organization_transactions New | Schedule R Part V | Inter-organization transaction ledger. Top-level flat array, sibling to related_organizations. Each row: related_org_name, transaction_type (Part V Line 1 code a–s), transaction_amt. Always-on. |
foreign_activities | Schedule F | Regions, activity types, revenue & expenditures abroad, foreign grants. |
lobbying_and_political | Schedule C | Lobbying expenditures (direct & grassroots), 501(h) election, political campaign expenditures. |
contributor_summary | Schedule B | Aggregate contributor counts + total contributions. Individual contributor names are never returned (IRS redaction). |
donor_advised_funds | Schedule D.I | Funds held, aggregate balance, contributions during year. |
filing_meta New
Filing-level metadata for the response year, drawn from the Form 990 return header. Always-on (no include gate).
| Field | Type | Description |
|---|---|---|
tax_period_begin | string | null | Start of the tax period (YYYY-MM-DD). |
tax_period_end | string | null | End of the tax period (YYYY-MM-DD). |
schema_version | string | null | IRS e-file schema version of the filing. |
preparer_firm | string | null | Paid-preparer firm name. |
preparer_firm_address New | string | null | Paid-preparer firm street address (return header). |
preparer_firm_city New | string | null | Preparer firm city. |
preparer_firm_state New | string | null | Preparer firm 2-letter state code. |
preparer_firm_zip New | string | null | Preparer firm ZIP (first 5 digits). |
preparer_firm_ein New | string | null | Preparer firm EIN. |
preparer_phone New | string | null | Preparer phone number. Note: the IRS schema attaches the phone to the preparer person, not the firm — there is no firm-phone element. |
tax_status_type | string | null | 501(c) / 4947(a) tax-status type from the return header. |
data_freshness
| Field | Type | Description |
|---|---|---|
filing_source | string | Always "IRS TEOS e-file". |
most_recent_tax_year | integer | Latest filing year ingested for this EIN. |
filing_date | string | Filing date of the response year. |
last_filing_date | string | Most recent filing date for this EIN overall. |
years_available | integer[] | All tax years on file. |
includes_applied | string[] | Diagnostic — which internal bundles applied to this response (empty on base). |
Peer Benchmarks: How Cubes Work
Every ratio in compensation.peer_benchmarks_by_metric and financial_profile.*.peer_benchmarks_by_metric returns a cube: the same metric sliced across seven peer-group dimensions, each with the same six percentile stats.
Shape of a single cube
{
"by_ntee": { ...PeerStats },
"by_revenue_band": { ...PeerStats },
"by_state": { ...PeerStats },
"by_ntee_and_revenue_band": { ...PeerStats },
"by_ntee_and_state": { ...PeerStats },
"by_revenue_band_and_state": { ...PeerStats },
"by_ntee_and_revenue_band_and_state": { ...PeerStats }
}PeerStats
| Field | Type | Description |
|---|---|---|
peer_group | string | Human label, e.g. "P – Human Services ∩ $100M+ ∩ DC". |
peer_count | integer | Number of orgs in the cohort for that tax year. |
p10, p25, median, p75, p90, mean | number | Distribution statistics for the metric in that cohort. |
note | string (optional) | Appears when peer_count < 10: "Small peer group — interpret with caution". |
Peer Benchmarks: 7 Dimensional Cuts
Each cube is the same metric sliced seven ways. The intersection cuts (triple) are the narrowest and usually most meaningful, but may have small cohorts.
NTEE major group
A–Z first letter of the IRS National Taxonomy of Exempt Entities code. Examples: A Arts & Culture, B Education, E Health, P Human Services.
Revenue band
Eight bands based on total revenue: 1 <$100K, 2 <$500K, 3 <$1M, 4 <$5M, 5 <$10M, 6 <$50M, 7 <$100M, 8 $100M+.
State
Two-letter state code from the organization's mailing address.
Intersections
4 compound cuts: ntee ∩ revenue_band, ntee ∩ state, revenue_band ∩ state, and the triple ntee ∩ revenue_band ∩ state.
Peer Benchmarks: Metrics Covered
17 metrics currently ship with peer-benchmark cubes. New metrics are added as underlying data coverage grows.
| Metric | Surfaced at |
|---|---|
total_revenue | (internal reference) |
top_officer_comp | compensation.peer_benchmarks, compensation.peer_benchmarks_by_metric |
top_officer_comp_to_revenue_pct New | compensation.peer_benchmarks_by_metric |
ceo_comp New | compensation.peer_benchmarks_by_metric |
cfo_comp New | compensation.peer_benchmarks_by_metric |
dev_director_comp New | compensation.peer_benchmarks_by_metric |
avg_compensation_per_employee New | compensation.peer_benchmarks_by_metric |
program_expense_ratio | financial_profile.expense_composition.peer_benchmarks_by_metric |
admin_expense_ratio New | financial_profile.expense_composition.peer_benchmarks_by_metric |
fundraising_expense_ratio New | financial_profile.expense_composition.peer_benchmarks_by_metric |
cost_to_raise_a_dollar New | financial_profile.expense_composition.peer_benchmarks_by_metric |
comp_to_expense_pct | financial_profile.expense_composition.peer_benchmarks_by_metric |
salaries_benefits_ratio New | financial_profile.expense_composition.peer_benchmarks_by_metric |
professional_fees_ratio New | financial_profile.expense_composition.peer_benchmarks_by_metric |
months_of_cash | financial_profile.liquidity.peer_benchmarks, financial_profile.liquidity.peer_benchmarks_by_metric |
operating_reserve_months New | financial_profile.liquidity + operating_sustainability |
operating_margin_pct | financial_profile.operating_sustainability.peer_benchmarks_by_metric |
Pro-Only Attachments Pro
Calling /v1/data-pro attaches four extra sections on top of the base shape.
financials_detail
Line-by-line Part VIII (revenue) and Part IX (expenses) breakdowns plus Schedule A (public charity status), Schedule B (contributors summary), Schedule D (supplemental financials) highlights, Schedule O (narratives).
Newly surfaced child-table arrays New
| Field | Type | Description |
|---|---|---|
part_8_revenue.programs[] | object[] | Form 990 Part VIII Line 2a–2f program-service revenue rows. Each: description, business_code, total_revenue, related_revenue, unrelated_revenue, exclusion_amt. |
schedule_d.assets[] | object[] | Schedule D Part IX — other assets detail. Each: description, book_value_boy, book_value_eoy. |
schedule_d.investments[] | object[] | Schedule D Parts VII (other securities) + VIII (program-related investments). Each: description, valuation_method, book_value_eoy. |
schedule_d.other_liabilities[] | object[] | Schedule D Part X — other liabilities. Each: description, book_value_eoy. Note: only EOY (no BOY pair). |
governance_detail
Full voting-board roster with titles, committee memberships, compensation-review process, meeting-minutes flags, and policies (conflict of interest, whistleblower, document retention, joint venture, independence).
registration
State-level registration filings (where ingested), Schedule R related-organization full roster with ownership percentages, foreign registration details.
Error Codes
| Status | Error | Meaning |
|---|---|---|
| 400 | MISSING_EIN | The ein query param is required. |
| 400 | INVALID_EIN | EIN is not 9 digits / not parseable. |
| 400 | INVALID_TAX_YEAR | tax_year must be a 4-digit integer. |
| 403 | IP_NOT_ALLOWED | The calling IP is not on the allowlist for this API key. |
| 403 | Forbidden | Missing or invalid x-api-key header. |
| 404 | NOT_FOUND | No filing for this EIN (or not for the requested year). Response includes years_available[]. |
| 500 | INTERNAL_ERROR | Unexpected server error. request_id included for support tickets. |
Rate Limits
| Plan | Requests / minute | Burst | Tier access |
|---|---|---|---|
| Free | 10 | 20 | Base only |
| Basic | 60 | 120 | Base only |
| Pro | 300 | 600 | Base + Pro |
| Enterprise | Custom | Custom | Base + Pro + bespoke attachments |
When you exceed a limit, API Gateway returns 429 Too Many Requests. Back off and retry after 30 seconds. Contact support@givalgo.ai to adjust plans.