Get a gift request
GET /gift_requests/{id}
Description
Retrieves a single gift request by its id. The response is a single JSON
object you get back from Create a gift request:
the gift request's own fields, with its owned associations (the recipient,
the shipping_address, the offering, and the line_items) returned inline
rather than as references you have to fetch separately. The campaign and the
sender come back as small summaries, enough to label the gift request and to
fetch the full record when you need more.
When to use
Reach for this endpoint to read a gift request back after you've created it,
to follow its status as the gift is redeemed and delivered, or to pick up the
redemption_url once it has been generated.
To create a gift request in the first place, use Create a gift request. To discover which campaigns are available, browse Campaigns.
Parameters
Path
id (string · uuid · required) is the gift request to retrieve. An id that doesn't
match a gift request in your account returns 404.
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.
Worked examples
A read is a plain GET by id, with no request body. The JavaScript,
Python, and Ruby versions fetch the gift request and read a couple of fields
off it; swap in the id you're interested in.
- cURL
- JavaScript
- Python
- Ruby
curl -X GET https://api.andopen.co/gift_requests/4fb4cb3f-9666-43b5-8884-7f5194483d1a \
-H "Authorization: Bearer <api_key>" \
-H "AndOpen-API-Version: 2026-05"
const response = await fetch(
"https://api.andopen.co/gift_requests/4fb4cb3f-9666-43b5-8884-7f5194483d1a",
{
method: "GET",
headers: {
Authorization: "Bearer <api_key>",
"AndOpen-API-Version": "2026-05",
},
},
);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const giftRequest = await response.json();
console.log(giftRequest.status, giftRequest.redemption_url);
import requests
response = requests.get(
"https://api.andopen.co/gift_requests/4fb4cb3f-9666-43b5-8884-7f5194483d1a",
headers={
"Authorization": "Bearer <api_key>",
"AndOpen-API-Version": "2026-05",
},
)
response.raise_for_status()
gift_request = response.json()
print(gift_request["status"], gift_request["redemption_url"])
require "net/http"
require "json"
uri = URI("https://api.andopen.co/gift_requests/4fb4cb3f-9666-43b5-8884-7f5194483d1a")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer <api_key>"
request["AndOpen-API-Version"] = "2026-05"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
http.request(request)
end
response.value # raises on a non-2xx response
gift_request = JSON.parse(response.body)
puts "#{gift_request['status']} #{gift_request['redemption_url']}"
Response shape
A successful call returns 200 OK with the gift request as a flat top-level
JSON object: the same shape Create a gift request returns.
| Field | Description |
|---|---|
reference (string · required) | A human-readable handle for the gift request, unique within your account and stable for its lifetime. Show it to your own users and quote it to support; the API itself takes the id. |
status (string · required) | The public-facing status, one of submitted, redeemed, dispatched, delivered, cancelled. A freshly-created request is submitted; the others are reached as the gift is redeemed, dispatched, and delivered, or cancelled. This is the field you poll to follow. delivered is not terminal, as the per-field notes below explain. |
campaign (object · required · nullable) | The campaign this request belongs to, embedded as an { id, name, web_url } summary. null for an ad-hoc send that belongs to no campaign. Fetch the rest of the campaign with Get a campaign. |
redemption_url (string · uri · required · nullable) | The link the recipient follows to redeem. |
web_url (string · uri · required) | The gift request's page in the &Open web app, on your organization's own domain. This is the sender-facing view and needs a signed-in session, so show it to your own users rather than the recipient. |
recipient (object · required) | The recipient, returned inline. |
sender (object · required) | The user recorded as responsible for the send, embedded as an { id, name, email } summary. Read their team and budget with Get a user. |
shipping_address (object · required · nullable) | The shipping address, returned inline in direct-send mode and null in choice mode. |
offering (object · required) | What was put in front of the recipient: the items on offer, whether they receive all of them or choose one, and whether they see them at redemption. |
line_items (array · required · nullable) | The line items, returned inline once locked. |
email_message (object · required · nullable) | The personal message that went into the invitation email, or null when the send carries none. |
{
"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": null,
"offering": {
"selection_mode": "one",
"visible_at_redemption": true,
"line_items": [
{
"id": "f6a7b8c9-d0e1-2345-6789-0abcdef01234",
"sku": "NOTEBOOK-A5",
"variant_id": "a7b8c9d0-e1f2-3456-789a-bcdef0123456",
"name": "Leather Notebook",
"quantity": 1,
"images": [
{
"name": "leather-notebook.jpg",
"url": "https://files.andopen.co/rndd63mwgj94j2vf3v2ngnye0hkn",
"urls": {
"thumbnail": "https://files.andopen.co/vw2mvwevyqxh98l7esf67nvunr4h",
"large": "https://files.andopen.co/mz4rc8kx1nvq7j93wtf5bd2hs0yl",
"large_wide": "https://files.andopen.co/q7pz3n8htv2ke0d5rjw94flxs6cb"
}
}
]
}
]
},
"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"
}
Per-field notes
shipping_addressandline_itemscome backnulluntil they're set.shipping_addressisnulluntil an address is provided, andline_itemsuntil the items are locked or chosen.line_itemsisnull, never[], before items are locked. For direct-send the items lock at creation, soline_itemsis populated from the start. For choice mode they lock at redemption, so the field staysnulluntil the recipient chooses. Treatnullas "not yet locked", not "no items".redemption_urlcan benullon a just-created request. The link is generated shortly after creation, so a read immediately after create may still returnnull; keep polling until it appears.deliveredcovers partial fulfillment, and it is not terminal. It means the gift reached the recipient, including a request whose remaining items failed or were cancelled, and the status can change again while a remaining item is retried. Don't treat it as the end of the lifecycle or stop polling on it.campaignandsenderare summaries, so they carry a label, anid, and little else. Use thenameto display the gift request, and theidto fetch the full campaign or user when you need more than the label. The campaign summary also carries its ownweb_url.offering.line_itemsandline_itemshold different sets, and never the same item twice. Before redemptionoffering.line_itemscarries what the recipient was shown andline_itemsisnull; after redemptionline_itemscarries what they chose andoffering.line_itemscarries what they left. Voucher, cause, and gift-set offerings are not represented yet and come backnull.recipient.thank_you_countcounts the thank-yous the recipient has sent for this gift, and starts at0.recipient.namejoins their first and last name, and staysnulluntil they supply at least one of the two.
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.
| Status | Meaning |
|---|---|
| 400 | The 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). |
| 401 | Authentication failed: missing or invalid bearer token. |
| 403 | Authorized but not permitted to access this resource. |
| 404 | The requested resource does not exist. |
| 429 | Too many requests. Rate limit exceeded. |
| 500 | Internal server error. |
| 503 | Service 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.
A read takes no body, so there's nothing to validate. The failure you'll handle most is a missing resource:
404 not_found: no gift request with thatid.401 authentication_error: the token is missing, unrecognized, or expired (unauthorized). A token is only valid in the region it was issued for, so one presented to the wrong region fails the same way.403 authorization_error: the token authenticated but isn't allowed to read this resource (forbidden,insufficient_scope).400 api_error:unsupported_api_versionwhen theAndOpen-API-Versionheader is missing or unsupported (returned before authentication).429 rate_limit_error: you've exceeded the rate limit; back off using theRetry-Afterheader.500/503 api_error: a fault on our side; rare, and safe to retry after a short delay (honorRetry-Afteron a503).