Skip to main content

Charity Engine Connector (Technical Documentation)

Written by Philippe Trussart

This guide explains how the CharityEngine connector fetches data, what it syncs, how it handles pagination/retries/deletes, and what each table contains at a high level. It’s modeled in the same spirit as the DMI and Luminate docs you liked: practical, explicit, and copy-paste friendly.


Overview

  • Protocol: CharityEngine SOAP API (/v/3/Soap, Get{Object} operations).

  • Sync style: Incremental by date fields per table; the connector windows large ranges into 24-hour slices and backstops the start time by 2 minutes to avoid missing edge records. Enforces a lower bound of 2010-01-01T00:00:00.

  • Pagination: Offset/limit loop per slice; limit = 2000 until a page returns fewer than 2000 results.

  • Rate Limiting: The API throttle is respected with adaptive backoff.

  • Schema handling: Each table has a fixed column map. JSON-shaped substructures are serialized as JSON strings; empty arrays are normalized to NULL.

  • Retries & errors: Requests are retried on connection issues (with sleep). Timeouts surface a clear message (e.g., check IP allowlist). Non-200 HTTP codes are mapped to specific exceptions, but CharityEngine often returns HTTP 200 with an error payload, which is parsed and handled.


Authentication & Endpoint

All calls are POSTed to:

https://api.charityengine.net/v/3/Soap SOAPAction: https://api.charityengine.net/v/3/CharityEngineIntegrationApi/Get{Object}

The connector dynamically injects the from/to filters into the XML body using each table’s configured date field(s).


Incremental Strategy

For each selected table:

  1. Read the bookmark (last_started) from state.

  2. Move the start back 2 minutes (safety overlap).

  3. If the gap ≥ 24h, query in daily windows from start to start + 24h, advancing until caught up; otherwise query start..now.

  4. After completing a table, write last_started back to state.

Note: Earliest allowed start is 2010-01-01 (enforced if the bookmark predates that).


Deletes

Some tables publish a stable identifier and are delete-aware (the connector advertises delete_keys in metadata). For example, contacts, email_addresses, and do_not_solicit_email_addresses expose id as a delete key; downstream systems can use this to reconcile hard deletes.


Column Mapping Notes

  • Simple fields: Extracted directly from attribute or element paths (e.g., ["@attributes","Id"]id).

  • Boolean/timestamp typing: Columns are typed (boolean/timestamp/string) before records are written; arrays that resolve empty are set to NULL.

  • JSON fields: Certain nested structures (e.g., “Payment…”, “Attribution…”, address composites) are emitted as JSON strings when modeled as type: json in the schema.


Request Construction

The connector builds a SOAP envelope like:

<x:Envelope xmlns:x="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="https://api.charityengine.net/v/3">   <x:Header/>   <x:Body>     <ns:Get{Object}>       <ns:queryParameters>         <ns:{FilteringField}From>{start}</ns:{FilteringField}From>         <ns:{FilteringField}To>{end}</ns:{FilteringField}To>         <ns:StartRowIndex>{offset}</ns:StartRowIndex>         <ns:MaximumRows>{limit}</ns:MaximumRows>       </ns:queryParameters>     </ns:Get{Object}>   </x:Body> </x:Envelope>

With SOAPAction header …/Get{Object}. The connector normalizes responses (sometimes repairing malformed XML) and then extracts the correct sub-node for list items (e.g., Conversions, MessageReturns, Registrations, etc.).


Discovery & Metadata

  • Discovery: For each selected stream, the connector writes the schema (columns) and key properties (indexes) to the singer catalog.

  • Unique/Delete keys: The connector writes unique_keys and (when applicable) delete_keys via writeMeta so downstream targets can deduplicate and apply deletes.


Operational Considerations and Known Limitations

  • Incremental sync design:
    Each stream uses an incremental date field (such as DateCreated or DateModified). The connector reads the bookmark from the last run, moves the start time back 2 minutes to cover edge records, and requests data in 24-hour windows until caught up.

  • Earliest allowable start date:
    Queries will not go earlier than 2010-01-01 00:00:00, regardless of bookmark state.

  • 24-hour window slicing:
    Large backfills are broken into 1-day windows to prevent overly large requests and improve stability. This can cause slower initial syncs for high-volume datasets.

  • Pagination:
    Each window is paginated with a 2000-record limit per page. The tap continues paging until fewer than 2000 records are returned.

  • Retry and error handling:
    The tap retries transient connection errors and times out gracefully. Persistent timeout errors include clear messaging (e.g., “Check if the IP address is allowlisted”). Although CharityEngine sometimes returns HTTP 200 responses containing error messages, the connector inspects the payload and converts these into explicit errors.

  • Delete support:
    Hard deletes are only supported for select tables—specifically:

    • contacts

    • email_addresses

    • do_not_solicit_email_addresses
      Other tables do not advertise delete keys and will not produce delete records.

  • Nested structures:
    Complex nested fields (like primary addresses, organization details, phone numbers, and JSON arrays) are serialized as JSON strings. This ensures consistent schema output but requires downstream flattening or transformation for analytics.

  • Variable response nodes:
    Some API responses return result arrays under unexpected node names (Conversions, Registrations, MessageReturns, etc.). The connector handles known cases but may require code updates if new objects or naming conventions are introduced in the API.

  • Schema drift:
    CharityEngine’s SOAP API may occasionally add new fields or rename elements. Since the connector uses a fixed schema map, new fields will not appear until the connector mapping is updated.

  • Performance and rate limits:
    Pagination, retry logic, and 24-hour windowing help throttle requests, but extensive historical syncs can still be slow. CharityEngine rate limits are handled gracefully but may extend total sync time.

  • Environment sensitivity:
    Some CharityEngine environments (sandbox vs. production) handle acknowledgments differently. Test or sandbox runs might not mark records as processed upstream.

  • Timezone and date normalization:
    All timestamps are processed as provided by the API. If data mixes UTC and local times or omits offsets, you may observe minor timestamp inconsistencies in downstream data.


FAQ

Q: How does the connector avoid missing records between runs?
A: It replays the last 2 minutes and queries in 24-hour windows for big gaps.

Q: How are nested/complex objects represented?
A: Either flattened into explicit columns (per the column map) or emitted as JSON strings for flexible storage.

Q: Are hard deletes supported?
A: Yes—when a table exposes delete_keys, the connector publishes them so downstream targets can apply deletes. Examples include contacts.id and email_addresses.id.

Did this answer your question?