Skip to main content

Documentation Index

Fetch the complete documentation index at: https://momogood.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

Coming Soon — webhook notifications. Push notifications for resource changes. Until then, use the polling pattern below. Contact support@givergy.com to express interest.
Coming Soon — bulk and async export jobs. For one-time large backfills, ask us about async export — useful when polling individual events at scale isn’t the right shape.
The simplest reliable approach is since-based polling. The examples below assume the Custom Data Export family; substitute the path prefix for /salesforce/v1 or /blackbaud/v1 as appropriate.
  1. On first run, call GET /<your-namespace>/v1/events?since=-1 to backfill all events visible to your service user.
  2. For each event id returned (paginate with offset / limit if you have more than 1000 events):
    • GET /<your-namespace>/v1/events/{eventId}/items?since=<lastSyncTs>
    • GET /<your-namespace>/v1/events/{eventId}/purchases?since=<lastSyncTs>
    • GET /<your-namespace>/v1/events/{eventId}/guests?since=<lastSyncTs>
  3. Persist max(updated) across all records returned as the next lastSyncTs. Keep fine-grained cursors per resource if you need different sync cadences.
  4. On subsequent runs, repeat with the saved cursor.
The Salesforce and Blackbaud families don’t include a list-events endpoint today. Integrations using those families typically receive event IDs out-of-band (e.g. from the destination CRM) and call /items, /purchases, and /guests directly. A list-events endpoint for these families is Coming Soon — contact support@givergy.com if you need it.

Bundle pagination caveat

For /items and /purchases, the offset and limit parameters apply per category inside the bundle, not across the whole response. If you have more than 1000 records in any single category for an event, you must paginate by re-issuing the request with rising offset until every category returns an empty array. The bundle wrapper structure (the six keys) is constant; only the array contents shrink. For example, requesting /items?offset=0&limit=1000 then /items?offset=1000&limit=1000 returns rows 0–999 then rows 1000–1999 of every category independently — not “the next 1000 items across all categories.”
Event stateSuggested interval
Active event (people are bidding / checking out)Every few minutes
Post-event reconciliationHourly
Idle / historical syncLess frequently
The shared rate-limit zone tolerates this comfortably. Avoid sub-second tight loops — see Rate limiting for the request-per-second target.

Cursor storage

Store lastSyncTs per resource per event, keyed however your sync job tracks state:
sync_state[event_id][resource] = max(updated)
If your job crashes partway through an event’s resources, that resource’s cursor stays at its previous value and the next run picks up where it left off. The since filter is inclusive of the cursor (updated >= since), so re-fetching a few overlapping records is harmless — your upsert logic should be idempotent anyway.

When the since cursor isn’t enough

since only tracks changes, not deletions. The list endpoints implicitly filter to records with status: "active", so a record being archived/obfuscated will simply stop appearing — your downstream copy won’t see the change unless you periodically reconcile by listing all current records. For most reporting use cases, this is fine. If you need true deletion semantics, plan a periodic full reconciliation (e.g. weekly): list everything currently active, diff against your local copy, and mark anything missing as deleted on your side.