Acknowledgment letters look like one job until you try to pull the list. A family renewing at the Contributor level, a bank sponsoring your summer camp, and a family foundation funding a conservation program all need a thank-you. They need different letters, different signers, and often different addresses. The query behind each one has to sort them correctly, or a foundation program officer ends up with a “Welcome back, member!” letter.
Below is how to think about building these queries in Altru so each letter stream comes out clean, plus the gaps you will likely have to cover with process rather than a checkbox.
Start from revenue, not constituents
An acknowledgment thanks someone for a specific payment, so build the query on a revenue-based source rather than a constituent-based one. A constituent query tells you who someone is. A revenue query tells you what they gave, when, how much, and what it was applied to. You can still reach constituent fields (name, address, constituency, organization details) through the revenue record.
Keep each row as one payment. If you start from constituents and pull in revenue, a donor with three gifts this month turns into one confusing row or three duplicated letters, depending on how the fields are set up.
One base query, three filtered versions
Rather than building three queries from scratch, build one solid base query with the filters every letter shares, then save copies that add the filter unique to each audience. When you fix something in the base logic later, you know exactly which three queries to update.
Filters every version shares
- Date range. Revenue date within your acknowledgment cycle (last week, last month). Pick one cycle and stick with it so nothing falls between runs.
- Not yet acknowledged. This is the filter that matters most. Use whatever your organization records when a letter goes out, whether that is Altru’s acknowledgment status, a letter history, or an attribute you maintain. Without it, every run re-sends last cycle’s thank-yous.
- Exclusions. Deceased constituents, “do not acknowledge” or “do not mail” solicit codes, and anonymous gifts that should get a letter without public recognition.
- Amount threshold, if your policy only sends formal letters above a certain gift size.
Membership letters
Filter on revenue applied to memberships. Add the membership program and level to the output so you can vary the letter by tier, and include the new expiration date if your letter confirms the term. Decide up front whether membership upgrades and add-on donations made in the same transaction get one combined letter or two. A payment split between a membership and a gift will match both your membership filter and your donation filter if you are not careful.
Corporate letters
Filter on the constituent being an organization, and then narrow to corporations. Altru does not automatically know the difference between a corporation and a foundation. Both are organization records, so you need a field you control to tell them apart. Common choices are a constituency, an industry value, or a custom attribute. Whichever you use, check that it is filled in consistently before trusting the query. Pull the organization’s primary contact so the letter goes to a person, not just “Acme Corp.”
Foundation letters
Same as corporate, filtered to your foundation designation. Foundation gifts are often tied to grants or pledges, so include the designation or campaign and any pledge information your letter references. Many foundations also want the grant or reference number they assigned, so if you store it on the revenue record, add it to the output.
The details that cause wrong letters
- Soft credits and matching gifts. A company match is paid by the organization but usually thanked on behalf of the employee too. Decide whether the matching company goes in the corporate stream and whether the employee gets a separate note, then test that the query produces exactly that.
- Households. Make sure the addressee and salutation you pull are the ones for the household or couple, not just one person, if that is how you write member letters.
- Payments on pledges. Some organizations acknowledge the pledge once and not every installment. If that is your rule, filter installment payments out of the regular stream.
- Organization records missing a contact. Run a quick check for corporate and foundation records with no primary contact or address before the letters go out.
Check the output before you mail
Before trusting a new query, run it alongside a revenue report for the same date range and compare totals. Every payment should land in exactly one letter stream or in a deliberate exclusion. A gift that appears in two streams, or in none, points to a filter you need to fix. Do this once in a test or sandbox environment if you have one, and again on the first live run.
Then close the loop. Whatever marks a gift as acknowledged in Altru has to happen after the letters are produced, every cycle. If that step is manual, put it on the same checklist as printing, or the “not yet acknowledged” filter stops meaning anything. If you are unsure how Altru’s built-in acknowledgment processing interacts with your queries, test a small batch first or confirm with Blackbaud support before relying on it.
Getting the lists where letters get written
Many teams do the actual letter merge outside Altru, which means exporting each query every cycle. Data Bridge from Social Good syncs Altru query results to Google Sheets, Mailchimp, ActiveCampaign, and other tools, so the membership, corporate, and foundation lists stay current in the place you merge from, without someone re-running exports each week. The query design above still does the real work; this just removes the copy step.
Quick answers
Can one query handle all three letter types?
It can, if you add output fields that let you split the results afterward. Separate saved queries are easier to hand off and harder to misuse, so most teams end up with three.
How do I tell corporations from foundations in Altru?
Use a field you maintain yourself, such as a constituency or attribute on the organization record. Clean it up first, because the query is only as accurate as that field.



