Guests
List guests with search
/v1/guestsRequest
curl https://api.repull.dev/v1/guests?limit=20 \ -H "Authorization: Bearer $REPULL_API_KEY"
Response
{
"data": [
{
"id": "123",
"displayName": "Example",
"displayNameLong": "Example",
"avatarUrl": "https://example.com/...",
"language": "Example text",
"country": null,
"phone": "+15550000000",
"email": "guest@example.com",
"totalReservations": 0,
"totalRevenue": "Example text",
"lastStayedAt": null,
"firstStayedAt": null,
"createdAt": "2026-06-01T12:00:00.000Z"
}
],
"pagination": {
"nextCursor": "eyJpZCI6MTIzfQ==",
"hasMore": true,
"total": 0
}
}Captured from a real response. Regenerated on every release, and CI fails if this shape stops matching the API.
Query Parameters
cursorstringOpaque cursor returned in the previous response's `pagination.nextCursor`. Omit to fetch the first page.
offsetintegerFirst-class alias for cursor-based pagination. Mutually exclusive with `cursor` — passing both returns 422. Accepts integers in `[0, 10000]`; deeper walks must use `cursor` (constant per-page cost). The response always includes `pagination.nextCursor` so consumers can switch from offset → cursor mid-walk for deep pagination without re-keying.
limitintegerMax items per page. Hard cap is 100.
qstringCase-insensitive substring search on name, email, or phone.
has_reservationbooleanRestrict to guests that do (`true`) or do not (`false`) have any reservation on file.
listingIdintegerRestrict to guests with at least one reservation on the given internal Repull listing id.
Get a guest profile by ID
/v1/guests/:idRequest
curl https://api.repull.dev/v1/guests/789 \ -H "Authorization: Bearer $REPULL_API_KEY"
Response
{
"id": "123",
"displayName": "Example",
"displayNameLong": "Example",
"avatarUrl": "https://example.com/...",
"language": "Example text",
"country": null,
"phone": "+15550000000",
"email": "guest@example.com",
"totalReservations": 0,
"totalRevenue": "Example text",
"currency": "USD",
"isBlacklisted": false,
"blacklistedReason": null,
"riskLevel": "low",
"verificationLevel": 0,
"createdAt": "2026-06-01T12:00:00.000Z",
"contacts": [
{
"type": "email",
"value": "Example text",
"verified": false,
"isPrimary": true,
"lastUsed": null
}
],
"flags": [],
"notes": [],
"reservationsSummary": {
"total": 0,
"future": 0,
"past": 0,
"cancelled": 0
}
}Captured from a real response. Regenerated on every release, and CI fails if this shape stops matching the API.
Create a new guest
/v1/guestsNote
Request
curl -X POST https://api.repull.dev/v1/guests \
-H "Authorization: Bearer $REPULL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Marco",
"lastName": "Rossi",
"language": "it"
}'Response
{ "data": { "id": "790", "firstName": "Marco", ... } }Body Parameters
firstNamestringRequiredlastNamestringemailstringphonestringE.164 preferred. Stored normalised.
languagestringBCP-47 tag.
currencystringisBusinessTravelerbooleanproviderstringA connected PMS to create the guest in as well, e.g. `guesty`. Created there first; its id comes back as `pms.externalId`.
Update a guest — in its PMS too, when linked to one
/v1/guests/:idNote
Request
curl -X PATCH https://api.repull.dev/v1/guests/790 \
-H "Authorization: Bearer $REPULL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"lastName": "Rossi",
"email": "marco.rossi@example.com"
}'Response
{
"id": 790,
"firstName": "Marco",
"lastName": "Rossi",
"language": "it",
"contacts": [{ "type": "email", "value": "marco.rossi@example.com", "isPrimary": true }],
"updatedAt": "2026-10-03T14:02:11Z",
"pms": [{ "provider": "guesty", "applied": ["guest"] }]
}Body Parameters
firstNamestringlastNamestringemailstringAdded as the guest's newest email; earlier ones are kept.
phonestringE.164 preferred. Added as the guest's newest phone; earlier ones are kept.
languagestringBCP-47 tag.