play icon for videos
← Academy
SOPACT ACADEMY · GRANT INTELLIGENCE · ANALYZE

Review a Nonprofit's 990 Before Granting

Pull the compliance signals from a 990-PF or audit fast — expenses, program-vs-admin split, restricted-fund use, governance notes, and auditor concerns, with figures quoted and gaps marked.

<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <style> @keyframes pulseDot{0%,100%{opacity:1}50%{opacity:.35}} *{box-sizing:border-box} body{margin:0;font-family:'Hanken Grotesk',-apple-system,BlinkMacSystemFont,sans-serif;background:#EEF2F9;padding:26px;display:flex;justify-content:center} .card{width:600px;max-width:100%;background:#FFFFFF;border:1px solid #E3E9F4;border-radius:20px;box-shadow:0 26px 64px -32px rgba(15,30,70,.34),0 2px 4px rgba(15,30,70,.05);overflow:hidden} .hdr{display:flex;align-items:center;gap:11px;padding:16px 20px;border-bottom:1px solid #EEF1F7;background:#F5F8FE} .hdr .ic{display:inline-flex;width:30px;height:30px;align-items:center;justify-content:center;border:2px solid #155DFC;border-radius:50%;color:#155DFC;font-size:15px;font-weight:800;flex-shrink:0} .hdr .t{min-width:0} .hdr .t .n{font-weight:800;font-size:14.5px;color:#0F172A;letter-spacing:-.2px} .hdr .t .s{font-size:12px;color:#64748B} .hdr .pill{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:11.5px;font-weight:700;color:#155DFC;background:#E6EEFF;padding:5px 10px;border-radius:20px;white-space:nowrap} .hdr .pill .d{width:6px;height:6px;border-radius:50%;background:#155DFC;animation:pulseDot 2s infinite} .tabs{display:flex;gap:0;padding:12px 16px 0;background:#F5F8FE} .tab{flex:1;display:flex;flex-direction:column;align-items:center;gap:5px;cursor:pointer;font-family:inherit;font-size:11.5px;font-weight:700;color:#64748B;background:transparent;border:none;border-bottom:2px solid transparent;padding:8px 4px 10px} .tab.on{font-weight:800;color:#155DFC;border-bottom-color:#155DFC} .tab .num{display:inline-flex;width:20px;height:20px;align-items:center;justify-content:center;border-radius:50%;font-size:11px;font-weight:800;color:#64748B;background:#EEF1F7} .tab.on .num{color:#fff;background:#155DFC} .divider{height:1px;background:#EEF1F7} .body{padding:20px} .eyebrow{font-size:10.5px;font-weight:800;letter-spacing:1.2px;text-transform:uppercase;color:#155DFC;margin-bottom:5px} .eyebrow.g{color:#15884F} .headline{font-family:'Inter',Georgia,serif;font-size:18.5px;font-weight:600;line-height:1.25;color:#0F172A;margin-bottom:12px} .lede{font-size:12.5px;line-height:1.55;color:#475569;margin:0 0 14px} .rows{display:flex;flex-direction:column;gap:8px;margin-bottom:14px} .row{display:flex;align-items:center;gap:11px;background:#F5F8FE;border:1px solid #EEF1F7;border-radius:11px;padding:11px 13px} .row .emoji{font-size:17px} .row .rt{flex:1;min-width:0} .row .rt .n{font-size:13px;font-weight:700;color:#0F172A} .row .rt .s{font-size:12px;color:#64748B} .pillsm{font-size:11px;font-weight:800;color:#155DFC;background:#E6EEFF;padding:4px 9px;border-radius:6px;flex-shrink:0} .pillsm.gray{font-weight:700;color:#64748B;background:#EEF1F7} .chainwrap{position:relative;padding-left:26px} .chainline{position:absolute;left:8px;top:8px;bottom:8px;width:2px;background:#E3E9F4} .cnode{position:relative;margin-bottom:14px} .cdot{position:absolute;left:-26px;top:4px;width:16px;height:16px;border-radius:50%;background:#fff;border:3px solid #94A3B8} .clabel{font-size:9.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;color:#64748B;margin-bottom:4px} .cbox{background:#F5F8FE;border:1px solid #EEF1F7;border-radius:11px;padding:10px 12px;font-size:12px;line-height:1.5;color:#334155} .cbox.graded{display:flex;align-items:flex-start;gap:9px;border-left-width:3px;border-left-style:solid} .cnote{margin:0 0 14px 4px;font-size:11px;line-height:1.5} .cnote .plus{display:inline-flex;width:16px;height:16px;align-items:center;justify-content:center;background:#155DFC;color:#fff;border-radius:4px;font-size:10px;font-weight:800;flex-shrink:0;margin-right:6px} .csummary{display:flex;align-items:center;gap:12px;background:#0A1B3D;border-radius:13px;padding:11px 15px;margin-top:4px} .csummary .t{flex:1;font-size:11.5px;color:#CBD8F5} .csummary .t b{color:#F1F5FF} .mxwrap{border:1px solid #EEF1F7;border-radius:12px;overflow:hidden;margin-bottom:10px} .mxhead{display:grid;grid-template-columns:118px 1fr 1fr;background:#F5F8FE;border-bottom:1px solid #EEF1F7} .mxhead div{font-size:9px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;color:#64748B;padding:7px 9px} .mxrow{display:grid;grid-template-columns:118px 1fr 1fr;border-bottom:1px solid #EEF1F7} .mxrow:last-child{border-bottom:none} .mxrow>div{padding:9px;font-size:11.5px;line-height:1.4;color:#334155;display:flex;align-items:center;flex-wrap:wrap;gap:5px} .mxrow .mxlabel{font-weight:700;color:#0F172A;background:#FAFBFE} .mxchip{font-size:9px;font-weight:800;letter-spacing:.3px;text-transform:uppercase;padding:3px 6px;border-radius:5px;white-space:nowrap} .promptwrap{padding:0 20px 18px} .promptlbl{font-size:10px;font-weight:800;letter-spacing:1px;text-transform:uppercase;color:#94A3B8;margin-bottom:7px} .prompt{display:flex;align-items:flex-start;gap:9px;font-family:ui-monospace,'SF Mono',Menlo,monospace;font-size:11px;line-height:1.5;color:#1E293B;background:#F5F8FE;border:1px solid #EEF1F7;border-left:3px solid #155DFC;border-radius:9px;padding:11px 12px} .prompt .car{color:#155DFC;font-weight:800;flex-shrink:0} .flagrow{display:flex;align-items:flex-start;gap:10px;background:#F5F8FE;border:1px solid #EEF1F7;border-radius:11px;padding:10px 12px;border-left-width:3px;border-left-style:solid;margin-bottom:8px} .flagtag{font-size:9.5px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;padding:4px 8px;border-radius:5px;white-space:nowrap;flex-shrink:0} .flagtxt{font-size:12px;line-height:1.45;color:#334155} .lp{display:flex;align-items:center;gap:12px;background:#0A1B3D;border-radius:13px;padding:14px 16px;margin-top:6px} .lp .ic{display:inline-flex;width:34px;height:34px;align-items:center;justify-content:center;background:#14295C;border:1px solid #26407A;border-radius:9px;color:#7FA8FF;font-size:16px;flex-shrink:0} .lp .rt{flex:1;min-width:0} .lp .rt .n{font-size:13px;font-weight:800;color:#F1F5FF} .lp .rt .s{font-size:11.5px;color:#9DB2D9} .lp .open{font-size:11px;font-weight:800;color:#0A1B3D;background:#7FA8FF;padding:6px 11px;border-radius:7px;white-space:nowrap} </style> </head> <body> <div class="card"> <div class="hdr"> <span class="ic">&#128196;</span> <div class="t"> <div class="n">990-PF · Compliance Read</div> <div class="s">DEMO-05 · Grant Applications · Sopact Sense</div> </div> <span class="pill"><span class="d"></span>Auditing</span> </div> <div class="tabs" id="tabs"></div> <div class="divider"></div> <div class="body" id="body"></div> <div class="promptwrap"> <div class="promptlbl">The prompt behind this step</div> <div class="prompt"><span class="car">&gt;</span><span id="promptTxt"></span></div> </div> </div> <script> (function(){ var TABS = ["Setup", "Audit", "Fix", "Report"]; var CONTENT = [{"eyebrow": "Step 1 · Load the filing", "headline": "The input is the 990-PF, nothing else", "lede": "Point the Assistant at the real record — nothing inferred, nothing invented.", "prompt": "You are the Sopact Sense Assistant. Here is this organization’s 990-PF filing: [PASTE OR ATTACH FILING]. Use only what it states; mark anything you infer as [INFERRED]. Wait for my task."}, {"eyebrow": "Step 2 · Extract & cite", "headline": "Four facts, every figure traced to a page", "lede": "Every fact is extracted and graded — <strong style=\"color:#15884F\">green</strong>, <strong style=\"color:#C9820A\">amber</strong>, <strong style=\"color:#C63E2B\">red</strong>.", "prompt": "Extract compliance facts from this 990-PF and quote the figures."}, {"eyebrow": "Step 3 · Close the compliance gap", "headline": "Implied is not the same as confirmed", "lede": "Take the lowest-graded item and resolve it with the one thing that's realistically obtainable.", "prompt": "Take the lowest-graded fact above and resolve it using only what’s realistically requestable. Show the before → after status and the one document that clears it."}, {"eyebrow": "Step 4 · Missing & incomplete report", "headline": "What a diligence reviewer would flag first", "lede": "Every amber or red item becomes one named ask — the report leads with the decision it informs.", "prompt": "Create a 'missing & incomplete' report from this analysis in Sopact branding. List every element graded amber or red, what is missing, and the one input that would fix each. Lead with the decision this report informs."}]; var BODIES = { setup: "<div class=\"row\"><span class=\"emoji\">&#128196;</span><div class=\"rt\"><div class=\"n\">990-PF filing</div><div class=\"s\">DEMO-05 · full public filing</div></div><span class=\"pillsm\">Loaded</span></div><div class=\"row\"><span class=\"emoji\">&#128203;</span><div class=\"rt\"><div class=\"n\">Compliance checklist</div><div class=\"s\">Expenses · split · policy · concerns</div></div><span class=\"pillsm gray\">Extracted</span></div><div class=\"row\"><span class=\"emoji\">&#128274;</span><div class=\"rt\"><div class=\"n\">Quote-the-figure rule</div><div class=\"s\">Every fact traces to a page number</div></div><span class=\"pillsm gray\">Required</span></div>", build: "<div class=\"mxwrap\"><div class=\"mxhead\"><div></div><div>Value</div><div>Source</div></div><div class=\"mxrow\"><div class=\"mxlabel\">Program expenses</div><div>$480k<span class=\"mxchip\" style=\"background:#15884F;color:#fff\">GREEN</span></div><div>990 p.10</div></div><div class=\"mxrow\"><div class=\"mxlabel\">Program/admin split</div><div>82% / 18%</div><div>derived</div></div><div class=\"mxrow\"><div class=\"mxlabel\">Conflict-of-interest policy</div><div>referenced<span class=\"mxchip\" style=\"background:#C9820A;color:#fff\">AMBER</span></div><div>not attached</div></div><div class=\"mxrow\"><div class=\"mxlabel\">Auditor concerns</div><div>—<span class=\"mxchip\" style=\"background:#C63E2B;color:#fff\">RED</span></div><div>none stated — unconfirmed</div></div></div>", fix: "<div class=\"mxwrap\"><div class=\"mxhead\"><div></div><div>Value</div><div>Source</div></div><div class=\"mxrow\"><div class=\"mxlabel\">Program expenses</div><div>$480k<span class=\"mxchip\" style=\"background:#15884F;color:#fff\">GREEN</span></div><div>990 p.10</div></div><div class=\"mxrow\"><div class=\"mxlabel\">Program/admin split</div><div>82% / 18%</div><div>derived</div></div><div class=\"mxrow\"><div class=\"mxlabel\">Conflict-of-interest policy</div><div>attached<span class=\"mxchip\" style=\"background:#15884F;color:#fff\">GREEN</span></div><div>not attached</div></div><div class=\"mxrow\"><div class=\"mxlabel\">Auditor concerns</div><div>—<span class=\"mxchip\" style=\"background:#C63E2B;color:#fff\">RED</span></div><div>none stated — unconfirmed</div></div></div><div class=\"cnote\" style=\"color:#15884F;margin-left:0\"><span class=\"plus\">+</span><strong>Fix applied:</strong> Request the actual conflict-of-interest policy document, not just the reference.</div>", reportFlags: "<div class=\"flagrow\" style=\"border-left-color:#C9820A\"><span class=\"flagtag\" style=\"color:#C9820A;background:#FBF0DA\">AMBER</span><div class=\"flagtxt\">Conflict-of-interest policy — referenced in the filing but the document itself isn’t attached.</div></div><div class=\"flagrow\" style=\"border-left-color:#C63E2B\"><span class=\"flagtag\" style=\"color:#C63E2B;background:#FCE9E7\">RED</span><div class=\"flagtxt\">Auditor concerns — nothing stated in the filing, which is not the same as confirmed clean.</div></div>", lpTitle: "Missing & incomplete report · shareable link", lpSub: "Decision-first · Sopact branding · 990-PF · Compliance Read", summaryBefore: "Grade: 1 green &middot; 1 amber &middot; 1 red. Implied ≠ confirmed.", summaryAfter: "Grade: 2 green &middot; 0 amber &middot; 1 red. Confirmed, not implied." }; var phase = 1; var tabsEl = document.getElementById('tabs'); var bodyEl = document.getElementById('body'); var promptEl = document.getElementById('promptTxt'); function renderTabs(){ tabsEl.innerHTML = ''; TABS.forEach(function(label, i){ var b = document.createElement('button'); b.type = 'button'; b.className = 'tab' + (i === phase ? ' on' : ''); b.innerHTML = '<span class="num">' + (i+1) + '</span><span>' + label + '</span>'; b.addEventListener('click', function(){ phase = i; render(); }); tabsEl.appendChild(b); }); } function renderBody(){ var c = CONTENT[phase]; var eyebrowClass = (phase===2) ? 'eyebrow g' : 'eyebrow'; var out = '<div class="' + eyebrowClass + '">' + c.eyebrow + '</div><div class="headline">' + c.headline + '</div><p class="lede">' + c.lede + '</p>'; if (phase === 0) { out += '<div class="rows">' + BODIES.setup + '</div>'; } else if (phase === 1) { out += BODIES.build; out += '<div class="csummary"><div class="t"><b>' + BODIES.summaryBefore + '</b></div></div>'; } else if (phase === 2) { out += BODIES.fix; out += '<div class="csummary"><div class="t"><b>' + BODIES.summaryAfter + '</b></div></div>'; } else { out += BODIES.reportFlags; out += '<div class="lp"><span class="ic">&#128196;</span><div class="rt"><div class="n">' + BODIES.lpTitle + '</div><div class="s">' + BODIES.lpSub + '</div></div><span class="open">Open &rarr;</span></div>'; } bodyEl.innerHTML = out; promptEl.textContent = c.prompt; } function render(){ renderTabs(); renderBody(); } render(); })(); </script> </body> </html>

In short: To review a nonprofit's 990-PF before granting, pull the compliance facts fast: total expenses, the program-vs-admin split, restricted-fund use, governance notes, and any auditor concerns — quoting the figures and marking anything implied rather than stated. Sopact Sense grades each fact green, amber, or red so a program officer sees what's confirmed, what's referenced but unproven, and what needs the document before the money moves.

1 · Set up over your data

Start with the audit or 990-PF loaded as clean data with persistent contact IDs, so every figure traces back to a line in the filing. Point the assistant at the dataset and have it read your Decision Brief first — the decision, audience, outcomes, indicators, and evidence standard.

You are the Sopact Sense Assistant working over the DEMO-05 · Grant Applications dataset (clean data + persistent contact IDs). Load my Decision Brief (decision, audience, outcomes, indicators, evidence standard) first, then wait for my task.

2 · Write the compliance prompt

The prompt names the facts and forces quoted figures. Paste this verbatim:

From [ORG]'s audit / 990-PF, extract total expenses, program-vs-admin split, restricted-fund use, governance notes, auditor concerns — quoting figures. Mark implied. Grade green/amber/red.

The prompt works because of five elements: the dataset it reads over, the compliance facts it must extract, the instruction to quote figures directly, the rule to mark implied when a fact isn't explicitly stated, and the call to grade green/amber/red so unconfirmed signals are visible.

3 · What Sense produces

Run it against the Foundation grant round demo:

Run on the Grant Applications dataset (DEMO-05) already loaded in Sopact Sense.

GRADE: green | expenses | program cited; amber | policy | referenced not attached; red | auditor | concerns unconfirmed

The green fact is program expenses, cited directly from the filing. The amber fact is a policy referenced in the document but not attached, so it can't be verified. The red fact is an auditor concern that's implied but unconfirmed — you need the management letter to clear or confirm it.

4 · Turn a weak link green

Take the weakest fact and resolve it with the single document that confirms it. Sense shows the before → after grade.

Take the lowest-graded element above and fix it using only what the program could realistically measure. Show the before → after grade and the single indicator/edit that moves it to green.

5 · Make the report and share it

Turn the compliance scan into a report, then a link that opens with no login.

Create a 'missing & incomplete' report from this analysis in Sopact branding [or paste your website URL / brand guideline to apply your own]. List every element graded amber or red, what is missing, and the one input that fixes each. Lead with the decision this report informs.
Create a shareable link for this report and open it in a new tab.

Tricks, tips, and troubleshooting

Quote the figure, don't paraphrase. A compliance review lives on exact numbers. Require the quoted figure and its location so a reviewer can verify the program-vs-admin split rather than trust a summary.

Mark implied as amber. When a fact is suggested but not stated — a policy referenced, a concern hinted — grade it amber and name the document that would confirm it, rather than reading it as settled.

Auditor concerns are red until confirmed. Treat any hint of an auditor concern as red and request the management letter; never clear it on inference.

Separate restricted from unrestricted. Restricted-fund misuse is a distinct risk. Pull restricted-fund use as its own fact so it isn't buried in the total expenses line.

Request the management letter for [ORG] and re-grade the auditor-concerns fact once it confirms or clears the implied concern.

Frequently asked questions

How do you review a nonprofit's 990 before granting?

Pull the compliance facts that bear on the funding decision — total expenses, the program-vs-admin split, restricted-fund use, governance notes, and auditor concerns — and quote the figures directly from the filing. Mark anything implied but not stated as amber, and treat unconfirmed auditor concerns as red until the supporting document confirms or clears them.

What is a 990-PF and why does it matter for funders?

A 990-PF is the annual return private foundations file with the IRS, and an audit is the equivalent assurance document for many nonprofits. For a funder they reveal how money is spent, whether restricted funds are used as intended, and whether auditors raised concerns — the signals that tell you a grantee can be trusted with the grant.

What makes a compliance review weak?

A review is weak when it paraphrases instead of quoting figures, treats referenced-but-unattached policies as proven, or clears auditor concerns on inference. The fix is to quote every figure, mark implied facts amber, and hold auditor concerns red until the management letter confirms them.

Ready to try it for yourself?

Open Sopact Sense, paste your program description, and put it to work.

Try in Sopact