items/total envelope and a Skip/Take cursor. It also exposes two separate filter surfaces: a simple Filter query parameter on /list endpoints, and an advanced query-builder pattern on /query endpoints. This page covers both, plus the iteration patterns for processing large result sets reliably.
The conventions are Raise-specific — they differ from CRM+‘s pagination conventions in ways that partners coming from CRM+ need to know. Two of the most important differences are called out as you encounter them on this page.
The response envelope
Every paginated response from Raise uses the same shape:items— the array of records for the current page. Its length is at most the requestedTake.total— the total count of records matching the query across all pages, not just the current page.
The two filter surfaces
Raise exposes two distinct mechanisms for filtering results, and they live on different endpoints:| Endpoint pattern | Filter mechanism | Use |
|---|---|---|
/list (GET) — e.g., GET /api/Donor/list | Simple Filter query parameter (free-text) plus pagination params | Quick list views, free-text searches, common-case reads |
/query (POST) — e.g., POST /api/Donor/query | Structured query builder in the JSON request body — supports field-level conditions, multi-value matching, AND/OR grouping | Complex segmentation, exports, reporting |
Pagination on /list endpoints
All /list endpoints accept the same set of query parameters. Below is the canonical example using GET /api/Donor/list:
| Parameter | Type | Description |
|---|---|---|
Skip | integer | The number of records to skip before returning results. Use for paging through results. |
Take | integer | The maximum number of records to return in this response. |
SortBy | string | The field to sort by. Endpoint-specific — see Sort fields per endpoint. |
Descending | boolean | If true, sort in descending order. If false or omitted, sort ascending. |
Filter | string | A free-text filter that narrows the result set. The exact matching behavior is endpoint-specific. |
IncludeDetails | boolean | If true, include related entities (addresses, contact methods, etc.) in each item. Performance cost — see below. |
A basic list request
cURL
JavaScript
Sort fields per endpoint
The validSortBy values are endpoint-specific. The Raise spec documents them in the parameter description. For GET /api/Donor/list, the sortable fields are:
/list endpoints (/api/Gift/list, /api/Campaign/list, etc.) have their own sortable-field sets — check the parameter description on the specific endpoint.
The Filter parameter
The Filter query parameter is a free-text search filter on /list endpoints. The Raise OpenAPI spec does not document the exact matching behavior — whether it searches across all fields, specific fields, supports operators, or uses any wildcard syntax. Behavior may vary per endpoint.
The exact matching semantics of the
Filter parameter are not documented in the spec. For predictable, structured filtering, prefer the /query endpoint pattern below. Use Filter for quick free-text searches in interactive contexts where the user can iterate on the search term.The IncludeDetails toggle
Several /list endpoints support an IncludeDetails boolean parameter. When true, the response includes related entities embedded in each item — for GET /api/Donor/list, this means each donor’s addresses and contact methods are included inline.
The Raise spec calls this out explicitly on POST /api/Donor/query:
When includeDetails=true, the response includes all related entities (DonorAddresses, DonorContactMethods) similar to the GET by ID endpoint. This may impact performance for large result sets.
Two patterns:
When IncludeDetails is true | When IncludeDetails is false |
|---|---|
| Each item carries full related-entity data — addresses, contact methods, etc. | Each item carries summary data only — id, name, email, etc. |
| Use for export workflows where the full record is needed | Use for list views, segment iteration, change detection |
| Slower per request; less bulk throughput | Faster per request; higher bulk throughput |
IncludeDetails=false and only request full details when the workflow needs them.
A complete pagination loop
The canonical pattern for iterating through every record matching a list query:JavaScript
- Loop condition is
skip < total, notpage.items.length === take. The last page typically returns fewer items thanTake. totalis captured from the first response. Capturing it once gives stable bounds even if records are inserted concurrently.- Sort by
idfor stable iteration. Other sort orders may produce inconsistent results if records change during pagination.
Pagination on /query endpoints
The advanced query-builder pattern lives on /query endpoints — POST /api/Donor/query, POST /api/Gift/query, POST /api/Campaign/query, POST /api/RecurringGift/query, POST /api/Segment/query. The pagination and sorting parameters are present, but in a different form: they’re camelCase fields in the JSON body, not query parameters.
The query body fields
| Field | Type | Description |
|---|---|---|
skip | integer | Records to skip — same semantics as Skip on /list |
take | integer | Maximum records to return |
sortBy | string | Sort field — same valid values as the corresponding /list endpoint |
descending | boolean | Sort direction |
includeDetails | boolean | Include related entities — same semantics as IncludeDetails on /list |
queryType | integer | The type of query being executed. See Query types below. |
groups | array | Array of QueryGroupModel — the filter structure |
selectedColumns | array of strings | List of result columns to return for each item — lets you request a subset |
filter | string | Free-text filter — same role as Filter on /list |
The filter structure
Thegroups[] array carries the structured filter. Each group contains a set of conditions[] and a conjunct operator that determines how the conditions combine:
parameteris the field being filtered. The valid parameter names per query type are discovered viaGET /api/Query/options/{queryType}— see Discovering query options.operatoris an integer enum (0–29, 30 possible values). The numeric values map to operators like Equals, Not Equals, Greater Than, Between, etc. — but the spec does not expose the mapping.conjunctis an integer enum (0or1) that combines conditions or groups. The two values correspond to AND and OR, but the spec does not document which is which.
values (array) for multi-value matches or secondaryValue for two-bound operators (Between).
Query types
ThequeryType field on a query request identifies what’s being queried — donor, gift, recurring gift, campaign, etc. Like operator, it’s an integer enum (0–9) without documented labels in the spec.
When calling a specific query endpoint (POST /api/Donor/query), the queryType is implied — the endpoint operates on donors. The field is still required in the body, with the integer value matching the donor query type.
The GET /api/Query/list/{queryType} and GET /api/Query/options/{queryType} endpoints take the queryType integer as a path parameter, so partners do need to know the integer values to use them.
Discovering query options
TheGET /api/Query/options/{queryType} endpoint returns the available parameters, operators, and result fields for a given query type:
cURL
- Valid
parameternames for filter conditions - The integer-to-label mapping for operators
- The list of selectable result columns (for
selectedColumns)
Selecting specific columns
TheselectedColumns array on a query request lets you request a subset of result fields rather than the full record. For large result sets where the full record is unnecessary, this reduces response payload size:
GET /api/Query/options/{queryType} (same endpoint as for parameters and operators).
Iteration patterns
Basic pagination
The same pattern as for/list endpoints, applied to the body fields:
JavaScript
ID-cursor iteration for very large result sets
For result sets in the tens of thousands of records or larger, theskip-based loop has two costs: server-side performance degrades at high skip values, and concurrent inserts can shift offsets. An ID-cursor pattern avoids both:
JavaScript
GET /api/Query/options/{queryType} at integration startup.
Performance considerations
Use the largest Take the endpoint supports
Each request consumes one slot in your rate-limit budget regardless of how many records it returns. A Take=1000 request returns 1,000 records for the cost of one request; a Take=25 request returns 25. For bulk operations, use the maximum the endpoint accepts.
For interactive list views in a UI, smaller pages (Take=25 or Take=50) load faster and don’t fetch records the user never sees.
Filter aggressively in the request, not client-side
A query that returns 500 records after filtering is much cheaper than one that returns 50,000 you discard client-side. Push filters into the request — either asFilter on /list or as groups[] on /query — wherever possible.
Use IncludeDetails=false when you can
Embedded related entities (includeDetails: true) significantly increases response payload size. Use it only when the workflow needs the full record. For change detection, segment iteration, and list views, the default summary representation is enough.
Use selectedColumns on /query endpoints
For workflows that only need a handful of fields per record, selectedColumns reduces payload size without sacrificing pagination throughput.
Where to go next
Rate Limits
The throttling patterns that pair with pagination strategy.
The Raise Data Model
Understand what
parameter values mean per query type.Query Gifts by Filters
The Gift-specific version of the query patterns on this page.
Query Donors by Filters
The Donor-specific version of the query patterns on this page.