Charitable Documentation

Learn how to make the most of Charitable with clear, step-by-step instructions.

Ambassadors Moderation – How To Approve, Reject, or Request Changes

Requires: Charitable Pro 1.8.16+
Charitable Ambassadors 3.0.0+

When ambassadors submit fundraisers on your site, you need a way to look them over before they go live – check the title makes sense, the goal is reasonable, the image isn’t off-brand.

The Moderation tab is the single place you do that. Every fundraiser submission flows through one queue with four clear views (Pending, Action Required, Rejected, Approved) and three actions you can take on each one (Approve, Reject, Request Changes).

It’s deliberately quick. You can approve a row in two clicks, reject with a written reason in three, or work through twenty at a time using bulk actions.

And if you change your mind right after approving, you have a 30-second window to undo it before the ambassador’s email is sent.

The Moderation queue showing pending fundraisers with inline Approve, Reject, and Request Changes actions

When You’d Use It

  • Daily queue check – open Moderation first thing, glance at the Pending count, and clear the backlog before it grows.
  • After a recruitment push – a flood of new submissions arrives because an ambassador shared their invite link. Bulk-approve the ones that look clean.
  • Brand-safety review – a submission’s title or image doesn’t fit your cause. Request changes with a note explaining what to fix.
  • Spam control – obvious junk submissions get rejected outright.

Where to Find Ambassadors Moderation

In your WordPress admin panel, go to Charitable » Ambassadors » Moderation

The number in the tab label (e.g. Moderation 7) is the count of fundraisers currently awaiting a decision. It updates as you work the queue, so when it hits zero you know you’re caught up.

Manual vs Auto Approval

Moderation only matters if you’re running manual approval. That’s the default for new installs, but it’s a single setting you can flip:

WordPress Admin > Charitable > Ambassadors > General > Automatically Approve Campaigns

SettingWhat happensWho uses it
OFF (default)Every submission lands in Pending. You decide whether it goes live.Most nonprofits – especially when running fundraisers under a brand or for a cause that matters to be presented carefully.
ONSubmissions publish immediately. The Moderation queue still works for after-the-fact review and the audit log still records who did what, but you’re not gating the front door.Programs that prioritize speed and trust their ambassadors, or use a separate community-moderation tool.

You can switch modes at any time without losing history.

The Four Views

A sub-nav across the top of the Moderation tab splits the queue into four lists:

The Pending / Action Required / Rejected / Approved sub-nav at the top of the Moderation tab
ViewWhat’s in itTypical action
PendingFresh submissions waiting for your first decision.Approve, reject, or request changes.
Action RequiredFundraisers you asked for revisions on. They’re sitting in draft until the ambassador updates and resubmits.Re-review once the ambassador resubmits.
RejectedSubmissions you turned down. They stay here as an audit trail.Usually nothing – they’re historical. You can un-reject by approving from this view.
ApprovedEverything currently live.View only. Use Undo Approve within 30s of approving; after that, edit the fundraiser directly.

Each view has its own count badge so you can see at a glance where work is sitting.

Approving a Single Fundraiser

The default approve flow is two clicks: hover the row, click Approve, done. The fundraiser publishes, the audit log records who approved it and when, and an email goes out to the ambassador letting them know.

Hovering a Pending row to reveal the inline Approve / Reject / Request Changes actions

If you want to approve without sending the email (rare but useful for migration imports or test fundraisers), uncheck the “Notify ambassador” box that appears in the approval confirmation. Or set the global default with a filter (see Developer reference below).

Rejecting a Fundraiser

Click Reject on the row. A modal opens asking for a reason:

The Reject modal asking for a reason, with the campaign title shown for confirmation

The reason is required – even a short note like “Title doesn’t match our brand guidelines” gives the ambassador something to act on. After you submit, three things happen:

  1. The fundraiser transitions to a custom charitable-rejected status (so it’s clearly distinguishable from drafts and trashed posts).
  2. The reason is stored on the fundraiser so any moderator can see it later.
  3. The ambassador receives the Creator Campaign Rejected email with your reason quoted in the body.

The fundraiser disappears from Pending and shows up in Rejected.

Requesting Changes

Use Request Changes when a fundraiser is almost there – it needs a tweak, but isn’t outright wrong. Click the action and a similar modal opens asking for guidance:

The Request Changes modal asking for guidance text, with the campaign title shown for confirmation

The fundraiser drops back to draft status. The ambassador gets the Creator Campaign Needs Revision email with your notes, edits the fundraiser, and resubmits. When they resubmit, it lands back in Pending with the change log preserved.

This is the kindest path for a fundraiser that’s close to good. Use it instead of rejection any time you’d rather the ambassador fix it than start over.

Bulk Actions

When the queue is busy, you can do several at once. Tick the checkboxes on the rows you want to act on, pick an action from the Bulk Actions dropdown above the table, and apply:

Three Pending rows ticked, with the Bulk Actions dropdown open showing Approve / Reject / Request Changes
  • Bulk Approve publishes them all at once, sending the approval email to each ambassador.
  • Bulk Reject opens a single Reject modal where the reason you enter applies to every selected row.
  • Bulk Request Changes does the same for change requests.

A bulk action shows a single confirmation notice at the top of the page when it’s done (“3 fundraisers approved”). The audit log still records each decision individually.

The 30-Second Undo

Right after you approve a fundraiser, a small “Undo” pill appears next to the row for 30 seconds:

The Undo pill appearing inline after an approval, showing a countdown timer

Click it and the approval is rolled back: the fundraiser transitions back to Pending, the audit log records an “undo_approve” entry, and the approval email is not sent (we deliberately don’t send the email until the undo window has passed for inline approvals – so undoing inside the window means the ambassador never knows you nearly approved them).

After 30 seconds, the pill disappears. After that, the only way back is to manually unpublish the fundraiser via the standard WordPress post editor.

The Undo is per-action, not per-row. If you approve five fundraisers in a row, you get five separate Undo pills, each independent.

The Audit Log

Every action – approve, reject, request changes, undo, resubmit – is recorded on the fundraiser itself in an append-only audit log. To see it, click into a single row in any view and scroll down:

The expanded row showing the audit log entries: approved, then resubmitted, then approved again, each with timestamp and moderator name

Each entry shows:

  • Action – approved / rejected / changes_requested / undo_approve / resubmitted
  • Moderator – which admin took the action
  • Timestamp – when it happened
  • Reason or notes – the text you typed (rejections and change requests)
  • Notified flag – whether the email was sent (for approvals)

The log is append-only – you can’t edit or delete entries from the UI. It’s the record you can fall back to if an ambassador ever asks “why was my fundraiser rejected?” or “who approved this?”

The Pending Count Is Everywhere

The Pending view’s count badge powers two other places in the admin so you don’t have to keep an eye on it manually:

  • The Moderation tab label itself (Moderation 7).
  • The Pending Approvals KPI tile on the Overview dashboard – this one only appears when at least one fundraiser is waiting.

Both pull from the same single source so they’re always in sync.

Editing Approved Fundraisers

In Ambassadors 3.0, edits to already-approved fundraisers go live immediately – they don’t loop back through Moderation. The reasoning is that an ambassador correcting a typo in their already-approved fundraiser shouldn’t need to wait again for your team. If post-approval edit moderation is important to your workflow, it’s flagged for a future version.

Tips

  • Set an SLA. A pending fundraiser is a fundraiser not raising money. Aim to clear Pending within 24 hours.
  • Use Request Changes generously. It’s the most ambassador-friendly action – shows you read the submission and want to help, not just gatekeep.
  • Lean on bulk actions. If 80% of submissions look clean, tick them all and bulk-approve in one go. Save the slow individual review for the outliers.
  • Read the reason field as a template. When the same reject reason comes up three times, that’s a sign your submission form needs better guidance up front.

Developer Reference

The rest of this page is for developers customizing the Moderation workflow.

Custom post status

Rejected fundraisers transition to a custom charitable-rejected status registered in includes/charitable-ambassadors-post-status.php. It’s:

  • Excluded from the front-end campaign archive (is_archive_visible() = false).
  • Excluded from wp_count_posts() for visitor-facing counts.
  • Included in admin queries when you filter the Moderation list table by Rejected.

To restore a rejected fundraiser, transition it back to draft or publish through the standard wp_update_post() call.

Audit-log storage

The audit log lives at post-meta key _charitable_ambassadors_moderation_log on each fundraiser. The value is an indexed array; each entry is an associative array:

[
    'action'          => 'approved' | 'rejected' | 'changes_requested' | 'undo_approve' | 'resubmitted',
    'moderator_id'    => int,   // WP user ID
    'timestamp'       => int,   // Unix epoch
    'reason_or_notes' => string,
    'notified'        => bool,  // optional, only on approve entries
]

The Charitable_Ambassadors_Moderation_Log class is the single read/write API:

Charitable_Ambassadors_Moderation_Log::append( $campaign_id, $action, $moderator_id, $reason_or_notes, $extra = [] );
Charitable_Ambassadors_Moderation_Log::get( $campaign_id ); // array of entries, oldest first
Charitable_Ambassadors_Moderation_Log::render_html( $campaign_id ); // newest-first HTML for the expanded row

Custom-table migration is deferred to a future version. Until then, the post-meta storage is the source of truth.

Reason/notes meta

The most recent reject reason and change-request notes are mirrored to dedicated post-meta keys so emails and template overrides can read them directly:

Meta keyStamped by
_charitable_ambassadors_rejection_reasondo_reject()
_charitable_ambassadors_needs_revision_notesdo_request_changes()

These keys are cleared on the next status transition out of charitable-rejected / draft – so once a fundraiser is approved, they’re gone.

Filters

FilterDefaultPurpose
charitable_ambassadors_moderation_default_notify_on_approvetrueDefault value of the “notify ambassador” checkbox in the inline approve flow. Return false to default-to-silent approvals.
charitable_ambassadors_skip_creator_campaign_approvedfalseUsed internally to suppress the approval email during a single approve call. Generally not for site code – flip the default-notify filter above instead.

Actions

ActionArgsFires when
transition_post_status$new_status, $old_status, $postStandard WP. Moderation hooks at priority 20 to catch ambassador resubmissions and log them.

AJAX endpoints

All on wp_ajax_ only, nonce per row, capability manage_charitable_settings:

ActionPurpose
charitable_ambassadors_moderation_approveApprove a single fundraiser. Returns the re-rendered row HTML plus a one-time undo nonce.
charitable_ambassadors_moderation_rejectReject with reason. Returns the re-rendered row HTML.
charitable_ambassadors_moderation_request_changesRequest changes with notes. Returns the re-rendered row HTML.
charitable_ambassadors_moderation_undo_approveRoll back a recent approval. Requires the one-time undo nonce returned by the approve call.

Form-POST handlers

URLUsed by
admin-post.php?action=charitable_ambassadors_moderation_bulkThe Bulk Actions form at the top of the table.
admin-post.php?action=charitable_ambassadors_moderation_singleThe Approve / Reject / Request Changes banner on the Ambassadors preview page. Same business logic as the AJAX endpoints; redirects back to Moderation with a result query-arg.

Reusable business logic

The same approve/reject/request-changes path is used everywhere (AJAX, bulk, banner). The methods on Charitable_Ambassadors_Moderation are public and callable from your own code once you’ve handled capability + nonce checks:

Charitable_Ambassadors_Moderation::get_instance()->do_approve( $campaign_id, $notify = true );
Charitable_Ambassadors_Moderation::get_instance()->do_reject( $campaign_id, $reason = '' );
Charitable_Ambassadors_Moderation::get_instance()->do_request_changes( $campaign_id, $notes = '' );

Pending count source

The Pending count badge across the admin (tab label, Overview KPI tile, anywhere else) is sourced from a single helper to keep them in sync:

Charitable_Ambassadors_Overview_Data::get_instance()->get_pending_approvals_count();

The value is range-independent (it always reflects “right now,” not the active Overview date range) and is cached by the Overview transient layer. Saving an approval or rejection busts the cache automatically through the Overview data class’s existing hooks.

Capabilities

Single gate: manage_charitable_settings. Granted to Administrators by default. Add the cap to another role to grant Moderation access without granting full Charitable settings access.

Logging

Every moderation action writes to Charitable Tools > Log via charitable_ambassadors_log(). The structured log entries have ambassadors_event keys:

EventWhen
moderation_approvedApprove action committed.
moderation_rejectedReject action committed.
moderation_changes_requestedRequest Changes committed.

Customization examples

Default to silent approvals (no email):

add_filter( 'charitable_ambassadors_moderation_default_notify_on_approve', '__return_false' );

Notify a Slack channel on every rejection:

add_action( 'transition_post_status', function ( $new, $old, $post ) {
    if ( 'charitable-rejected' !== $new ) {
        return;
    }
    if ( get_post_type( $post ) !== 'campaign' ) {
        return;
    }
    $reason = get_post_meta( $post->ID, '_charitable_ambassadors_rejection_reason', true );
    // ...post to Slack webhook with $post->post_title and $reason.
}, 30, 3 );

Read the audit log for a fundraiser:

$log = Charitable_Ambassadors_Moderation_Log::get( $campaign_id );
foreach ( $log as $entry ) {
    printf( "%s by user #%d at %sn", $entry['action'], $entry['moderator_id'], gmdate( 'c', $entry['timestamp'] ) );
}

Programmatically approve a fundraiser from an external workflow (e.g. a CRM webhook):

if ( current_user_can( 'manage_charitable_settings' ) ) {
    Charitable_Ambassadors_Moderation::get_instance()->do_approve( $campaign_id, true );
}

Related

Helpful Links

🤝 Get help when you need it

Connect with Customer Support →

📑 Find the guide you need

Browse the Documentation Hub →

⬇️ Download proven strategies, campaign ideas, and expert tools

Get the Fundraising Kit →

🔗 Let your AI Assistant do the fundraising work for you.

Connect Charitable to your AI assistant →

💸 Get Free Fundraising Resources
Head to the Charitable Fundraising Hub →

🤔 Got questions about Charitable?
Charitable FAQs →

Need help understanding non-profit terms and jargon?
See our Non-Profit Glossary →

Still have questions? We’re here to help!

Last Modified:

What's New In Charitable

View The Latest Updates
🔔 Subscribe to get our latest updates
📧 Subscribe to Emails

Email Subscription

Join our Newsletter

We won’t spam you. We only send an email when we think it will genuinely help you. Unsubscribe at any time!

Improvement Payments

💸 Introducing Tiered Rates for Fee Relief: Match the Ask to the Gift!

Fee Relief asks your donors one short question at checkout: would you like to cover the processing fee on this gift? Until now that question used a single rate for every donation on a gateway, so a $10 gift and a $500 gift were asked for the same percentage. Fee Relief 1.3.0 lets you set as many donation bands as you like, each carrying its own rate. Why this is important:

  • 🪙 Gentler on small gifts: A fixed transaction cost is a far bigger share of a $10 donation than a $500 one, so bands let you ask for less at the bottom.
  • 🎚️ As many bands as you need: Each band carries its own percentage and its own fixed amount, and the top band runs on with no upper limit.
  • 🛑 An optional ceiling: A Maximum fee field stops any donor being asked for more than a number you choose, however large the gift.
  • 🔌 Set per payment gateway: Stripe can run on four bands while Windcave and Payfast stay on a single rate, because bands belong to a gateway and not to your whole site.
  • 🛡️ Nothing changes until you say so: Your current rates stay exactly as they are until you switch Use Tiered Rates on under Charitable » Settings » Advanced » Fee Relief.

Check out our announcement here.

Donations Improvement

📊 Your Pro Dashboard Can Now Compare, Export, and Score!

Most fundraising dashboards only tell you how much you have raised. Charitable Pro 1.8.19 rebuilds the dashboard and the Reports Overview around the harder questions: whether anything is broken, whether this period beat the last one, and which single change would make the most difference today. Why this is important:

  • 📈 Every figure has a trend: Pick a period and the tiles and the chart move together, with each total shown against the previous period.
  • 🗓️ Charts that stay readable: Short ranges group donations day by day, while longer ranges group by week or month, so a full year reads as a curve instead of a flat line.
  • 🔀 Compare any 2 periods: Not just consecutive ones, so you can ask how this December did against last December. That matters because fundraising is seasonal.
  • 📤 Export the whole summary: Send the full overview out as CSV or PDF, ready for a board pack or a funder report.
  • 🎯 Score your setup for free: Have your fundraising setup scored, so the one change worth making next is the one you can see.

Check out our announcement here.

Feature New

🎟️ Introducing Charitable Events: Sell Tickets Inside Your Campaigns!

Most nonprofits sell event tickets in one tool and collect donations in another, which leaves two sets of reports and a manual match at the end of the year. Charitable Events brings both together, selling tickets through the same donation forms and payment gateways you already run in Charitable. Why this is important:

  • 🎟️ Every ticket is a donation: Ticket sales run through the gateway you already use and count toward the campaign goal, with everything managed under Charitable » Events.
  • 📱 QR check-in from any phone: Each attendee gets their own QR code on the receipt, and volunteers scan at the door through a check-in link that needs no WordPress account.
  • 🧾 Receipts ready for tax time: Give each ticket type a fair market value, and Charitable puts the correct tax-deductible amount on every donor receipt.
  • 📋 Attendee details at checkout: Ask every guest for a meal choice, shirt size, or access needs, with a separate attendee record created for each ticket.
  • 🗓️ Blocks and calendars included: Three editor blocks plus Sugar Calendar and The Events Calendar support put your events where supporters already look.

Check out our announcement here.

ai New

🚀 Unleash AI Power in Charitable!

Your AI assistant can now build, edit, and manage your Charitable fundraising campaigns directly — just by asking. With Charitable Pro adding write support for the WordPress Abilities API, tools like ChatGPT, Claude, and Cursor can handle full administrative actions safely through MCP. Why this is important:

  • 🤖 Campaign creation in plain language: Prompt your assistant with a goal like “Set up a fundraiser for the shelter with a $5,000 goal”, and it builds a real draft campaign complete with suggested donation tiers.
  • 🎨 Instant donation form tweaks: Add custom fields, change button colors, or reorder elements without diving into form settings.
  • 📝 Offline gift logging: Tell your assistant about cash or check gifts, and it will match donor emails and record transactions into your history.
  • 🛡️ Safety and control by default: Write access stays strictly off until turned on in Charitable » Tools » AI MCP, keeping read-only reporting safe by default.
  • 📜 Full audit logging: Every change made by an AI assistant is tracked under Charitable » Tools » Logs, so you always know who (or what) updated your site.

Check out our announcement here.

Improvement Payments

💰 Accept Recurring Donations with Windcave and Charitable

A donor sets their gift up once on Windcave’s secure payment page, and Charitable bills every renewal after that on schedule. Why this is important:

🏦 Organizations banked in New Zealand or Australia: monthly giving on the gateway your bank already set you up with, with no second processor to onboard.
⛪ Churches taking regular tithes and offerings: congregants set their own schedule once, which is the simplest way to launch recurring church giving without a separate platform.
🌏 Groups with donors in several currencies: Windcave handles more than 20, so a supporter can give in the currency they actually hold.
📅 Operating funds rather than one-time campaigns: switch on Recurring Only mode and the one-off option disappears, so every gift to that campaign is a subscription.
🧾 Teams with no developer on staff: 3 sets of credentials pasted into a settings page, and no code anywhere.

Check out our announcement here.