Skip to main content

Raiser's Edge Connector (Technical Reference)

Written by Philippe Trussart

Overview

The Raiser’s Edge connector syncs data from Blackbaud Raiser’s Edge NXT (via the SKY API) into your data warehouse.

It pulls:

  • Constituents and their contact info

  • Gifts, funds, campaigns, appeals and packages

  • Opportunities and fundraiser assignments

  • Event records and event participants

  • Key constituent flags via the SKY Query APIs (no-valid-address, solicit codes, etc.)

The connector is read-only and does not write anything back to Raiser’s Edge.


Authentication

The connector uses the SKY API OAuth2 flow:

  • OAuth base URL: https://oauth2.sky.blackbaud.com/

  • API base URL: https://api.sky.blackbaud.com/

You’ll need:

  • A SKY API application configured in Blackbaud’s developer portal

  • Client ID / client secret

  • An access token and refresh token with permissions to the endpoints listed below

Tokens are passed in HTTP headers on each request; the connector handles refreshing when tokens expire.


Discovery

When you run discover:

  • The connector loops through every configured stream name.

  • It inspects the column definitions and, if there is an id field, marks it as the unique key.

  • It emits the full JSON schema for that table to the catalog.

  • It also writes initial state for each stream:

    • memberships starts at 1754-01-01 00:00:00

    • All other tables start at 0001-01-01 00:00:00

These last_started timestamps are later used as the starting point for incremental syncs.


Incremental vs truncate-and-reload

There are two main sync patterns:

  1. Standard API endpoints
    For most tables (e.g., constituents, gifts, addresses, etc.), the connector calls the corresponding SKY API “list” endpoints (like constituent/v1/constituents) and uses date fields such as date_modified or date_added to advance the state watermark.

  2. Query-based tables (SKY Query API)
    For these four logical tables:

    • constituent_solicit_codes

    • constituent_addressee_and_salutation

    • constituent_no_valid_address

    • constituent_requests_no_email

    the connector uses the SKY Query API instead of standard list endpoints:

    • It discovers the numeric query type ID from query/querytypes.

    • It looks up node IDs and field IDs for each configured column (node and fieldName in the config).

    • It then runs a query instance and streams the results.

    For query-based tables, every sync is a truncate-and-reload:

    $this->singer->writeTableAction($table, 'truncate');
    ``` :contentReference[oaicite:11]{index=11}

    However, the query itself usually filters on **“Constituent Date Last Changed”** (`date_modified` column) so you can still think of it as time-bounded by that date in practice.

Deceased / inactive flags

Several tables include configuration flags:

  • has_deceased on constituents

  • has_inactive on:

    • constituents

    • addresses

    • email_addresses

    • online_presences

    • campaigns

    • appeals

    • packages

    • funds

    • opportunities

    • events

The connector uses these flags to include or exclude deceased or inactive records via the corresponding query parameters in SKY API calls.


Custom sync methods

Two tables are not simple list calls; they use custom logic:

  • fundraiser_assignments

    • Endpoint: fundraising/fundraisers/types

    • Method: syncFundraiserAssignments (walks assignment data across funds, campaigns, and appeals).

  • event_participants

    • Endpoint: event/eventlist

    • Method: syncEventParticipants

    • For each event, the connector calls the participants endpoint and flattens the participant data into the event_participants table.

Because these are composed from multiple underlying calls, they behave more like snapshot tables (data refreshed on each run) instead of purely incremental feeds.


Timeouts and retries

  • Default HTTP timeout: 600 seconds.

  • The connector keeps an internal timeout counter and will log/handle timeouts gracefully (exact retry behavior is implemented in the shared HTTP helper).

In practice, for very large datasets we recommend shorter sync windows (e.g., smaller date ranges or more frequent runs) to avoid long-running queries.


Deletes

The connector does not implement incremental deletes:

  • If a record is deleted in Raiser’s Edge, it will not be explicitly deleted from your warehouse by this connector.

  • To reflect deletes, you will need:

    • Either a downstream soft-delete strategy, or

    • Periodic full reloads (truncate & re-sync) of specific tables.


Operational Considerations & Known Limitations

  1. No hard deletes

    • Records deleted in Raiser’s Edge are not automatically removed from your warehouse data.

    • Plan periodic full reloads or use soft-delete logic downstream if you need to detect removals.

  2. Query-based tables are truncate-and-reload

    • constituent_solicit_codes, constituent_addressee_and_salutation, constituent_no_valid_address, and constituent_requests_no_email are always fully refreshed.

    • On very large databases, this can be relatively heavy; schedule these less frequently if needed.

  3. Large datasets and timeouts

    • The connector uses a 600-second HTTP timeout. Long-running queries on very large tenants can hit this limit.

    • If you frequently see timeouts, consider:

      • Running syncs more frequently (smaller deltas)

      • Disabling rarely used streams

      • Splitting jobs by stream.

  4. Membership baseline date

    • Memberships use a different start watermark (1754-01-01) which effectively pulls all historical memberships on first run.

  5. Typographical quirks in field names

    • Some field names reflect the exact SKY objects and may include spelling inconsistencies (for example, memebers in the memberships stream, or online_presense in constituents).

    • Do not “correct” these names when building SQL; use them exactly as they appear in the schema.

  6. API permissions

    • Access to some streams (e.g., gifts, opportunities, query endpoints) depends on the scopes granted to your SKY API app and user.

    • If a stream returns errors, verify that your app and user have appropriate permissions in Blackbaud.

Did this answer your question?