Skip to main content
Version: 2026-05

List gift requests

GET /gift_requests

Description

Lists the gift requests in your account, newest first, as a cursor-paginated collection. Each item carries the full gift-request shape: the same object Get a gift request returns, with the recipient, sender, offering, and line items embedded inline.

What you get back depends on the token you send. An admin or service token sees every gift request in the account. A non-admin user token sees only the gift requests that user sent.

When to use

Use this endpoint to work across many gift requests at once: reconciling a batch you sent, building a dashboard, or finding one by its reference when that is all a colleague gave you. Filters combine, so you can narrow to one campaign, one sender, or one week without paging the whole account.

When you already have a gift request's id, fetch it directly with Get a gift request. To create one, use Create a gift request.

Parameters

Headers

AndOpen-API-Version (string · required) is the API version this request targets. Always send 2026-05. Requests authenticate with a bearer token; see Authentication for how to present it and Environments for the regional base URL to send it to.

Query parameters

Every one of these is optional, and sent together they page, sort, and filter the same collection.

Paging

limit (integer · optional) is how many gift requests to return per page. Defaults to 25, which is also the maximum: each item carries its full nested shape, so the page is capped to keep response size and time predictable. A larger value is clamped to 25 server-side rather than rejected; a non-numeric, zero, or negative value is rejected with a 400.

after (string · uuid · optional) is the keyset pagination cursor. Pagination is cursor-based, not page-numbered: to fetch the next page, pass the id of the last gift request in the page you just received. Omit it for the first page. A cursor that references no existing record is rejected with a 400. Stop paging when the response's has_more is false.

Ordering

sort (string · optional) is the field to order by, - prefix for descending. Defaults to -created_at (newest first); created_at, updated_at, and -updated_at are also accepted. Any other field is rejected with a 400.

Filtering

Filters combine with AND, so each one you add narrows the page further. Two kinds behave differently when nothing matches, and the difference is worth knowing before you debug an empty page:

  • An exact-match filter (status, reference, campaign, sender) given an unrecognized value matches nothing and returns an empty page.
  • A substring filter (campaign.name, sender.name, sender.email, recipient.email, recipient.name, recipient.first_name, recipient.last_name) is case-insensitive and matches anywhere in the value.

status (string · optional) filters by public status. Accepts a single value or a comma-separated list, matching any of them.

reference (string · optional) matches a gift request's human-readable reference exactly. A reference is unique within your account, so this returns at most one item.

campaign (string · optional) filters by campaign id. Ad-hoc sends belong to no campaign, so they never match this filter. campaign.name (string · optional) matches against the campaign's name instead.

sender (string · optional) filters by the sending user's id. The literal me resolves to the authenticated user, which needs user authentication: a service token has no connecting user and gets a 400. sender.name (string · optional) and sender.email (string · optional) match against the sender's name and email.

recipient.email (string · optional), recipient.name (string · optional), recipient.first_name (string · optional), and recipient.last_name (string · optional) match against the gift recipient. Because recipient.email is a substring match, a bare domain such as @example.com selects every recipient on it.

created_at (object · optional) filters by creation time with bracketed range operators: created_at[gte], created_at[lte], created_at[gt], and created_at[lt]. Values are ISO 8601 timestamps, and several operators combine into an interval, so created_at[gte]=2026-01-01T00:00:00.000Z&created_at[lt]=2026-04-01T00:00:00.000Z is the first quarter. An unknown operator or a non-ISO-8601 value is rejected with a 400.

Worked examples

The cURL version is the raw HTTP call; the JavaScript, Python, and Ruby versions are idiomatic equivalents. Each asks for the redeemed gift requests on one campaign.

curl -X GET "https://api.andopen.co/gift_requests?campaign=a1b2c3d4-e5f6-7890-abcd-ef1234567890&status=redeemed" \
-H "Authorization: Bearer <api_key>" \
-H "AndOpen-API-Version: 2026-05"

Paging through a filtered set

To walk every match, keep fetching while has_more is true, passing the last gift request's id as the after cursor each time. Hold the filters steady across the loop; changing one mid-walk shifts the collection under the cursor. The cURL version shows a single follow-up request; the others loop until the last page.

curl -X GET "https://api.andopen.co/gift_requests?created_at%5Bgte%5D=2026-01-01T00:00:00.000Z&after=4fb4cb3f-9666-43b5-8884-7f5194483d1a" \
-H "Authorization: Bearer <api_key>" \
-H "AndOpen-API-Version: 2026-05"

Response shape

A successful call returns 200 OK with a page object: a data array of gift requests plus a boolean cursor flag. Paging is driven by has_more and the after cursor.

FieldDescription
data (array · required)The gift requests in this page. Each entry is a full gift request, identical to what Get a gift request returns; see that page for the per-field detail.
has_more (boolean · required)Whether more gift requests exist beyond this page. When true, fetch the next page by passing the last item's id as the after cursor; when false, you've reached the end.
data.status (string · required)Each item's status, one of submitted, redeemed, dispatched, delivered, cancelled. Every item also carries its reference, its campaign summary, and its sender summary, so you can label a row without a second call.
{
"data": [
{
"id": "4fb4cb3f-9666-43b5-8884-7f5194483d1a",
"reference": "ACME-M5RD6J8",
"status": "redeemed",
"campaign": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Q4 Customer Appreciation",
"web_url": "https://acme.andopen.co/sender/gift-history/campaigns/a1b2c3d4-e5f6-7890-abcd-ef1234567890"
},
"redemption_url": "https://gift.andopen.co/r/abc123",
"web_url": "https://acme.andopen.co/sender/gift-history/4fb4cb3f-9666-43b5-8884-7f5194483d1a",
"recipient": {
"id": "b2c3d4e5-f6a7-8901-bcde-f01234567890",
"thank_you_count": 1,
"first_name": "Alice",
"last_name": "Smith",
"name": "Alice Smith",
"email": "alice@example.com"
},
"sender": {
"id": "9f8e7d6c-5b4a-3210-fedc-ba9876543210",
"name": "Dana Okafor",
"email": "dana@acme.example"
},
"shipping_address": {
"id": "e5f6a7b8-c9d0-1234-5678-90abcdef0123",
"first_name": "Alice",
"last_name": "Smith",
"address1": "12 Merrion Square",
"address2": "Apt 4B",
"city": "Dublin",
"region": "Leinster",
"postal_code": "D02 XY45",
"country_code": "IE",
"phone": "+353871234567"
},
"offering": {
"selection_mode": "all",
"visible_at_redemption": false,
"line_items": null
},
"line_items": [
{
"id": "d4e5f6a7-b8c9-0123-4567-890abcdef012",
"sku": "HOODIE-L-BLK",
"variant_id": "c3d4e5f6-a7b8-9012-cdef-012345678901",
"name": "Hoodie: Large / Black",
"quantity": 1,
"images": [
{
"name": "hoodie-black.jpg",
"url": "https://files.andopen.co/8k2mfp4qz7x9v1c3b5n0jhtl",
"urls": {
"thumbnail": "https://files.andopen.co/p3wq7m2zx8k4n6v0bjhtldsf",
"large": "https://files.andopen.co/r9td5c1yfw3jq7n2vk8mzbxh",
"large_wide": "https://files.andopen.co/h4nj8sv2qd6kz0wt3mfy9lpc"
}
}
]
}
],
"email_message": {
"subject": "A small thank-you",
"body": "Thanks for being a great customer!"
},
"created_at": "2026-04-16T10:30:00.000Z",
"updated_at": "2026-04-16T10:30:00.000Z"
}
],
"has_more": false
}

Per-field notes

  • Every item is the full gift request. The list does not return a trimmed summary; each entry includes the same recipient, sender, offering, and line items as the single-gift-request endpoint. This is why the page size is capped at 25.
  • has_more drives paging, not a total count. The response carries no total and no next URL. Treat has_more: false as the only signal to stop, and build the next request from the last item's id.
  • Exact-match filtering is forgiving. An unknown value for status, reference, campaign, or sender yields an empty page, not a 400, so an empty data array can mean either "no matches" or "filter typo".
  • data[].campaign is null on an ad-hoc send. Those items are reachable only by leaving campaign off the request, so a campaign-filtered sweep never accounts for them.

Error cases

Every failure uses the shared error model: a top-level errors array of objects carrying type, code, message, and (for field-level problems) param. See Errors for the full type/code taxonomy and how to handle each category; the codes below are the ones this endpoint produces.

StatusMeaning
400The request is malformed or violates a precondition. Typical triggers are a missing or unsupported `AndOpen-API-Version` header, a request body that is not valid JSON, or pagination parameters that fail server-side validation (`limit` non-numeric or non-positive, `after` referencing a record that does not exist).
401Authentication failed: missing or invalid bearer token.
403Authorized but not permitted to access this resource.
429Too many requests. Rate limit exceeded.
500Internal server error.
503Service unavailable. The account may be under maintenance. Check the `Retry-After` header.

Every error carries a type, one of: validation_error, authentication_error, authorization_error, not_found_error, rate_limit_error, api_error.

The ones you'll meet in practice:

  • 400 validation_error: a query parameter was rejected, each naming the offending one in param. An after cursor referencing no existing record is invalid_reference. A limit that is not a positive integer, an unsupported sort field, a malformed created_at operator or timestamp, and sender=me under service authentication are all invalid_format.
  • 400 api_error: unsupported_api_version when the AndOpen-API-Version header is missing or unsupported (returned before authentication).
  • 401 authentication_error: the bearer token is missing, invalid, or expired (unauthorized).
  • 403 authorization_error: the token is valid but not permitted to list gift requests (forbidden).
  • 429 rate_limit_error: too many requests; back off and retry (rate_limited). The RateLimit-* response headers tell you the budget and reset time.