pms_duplicate
The PMS already holds a booking made with this `Idempotency-Key`. The first request went through; `existing` names the booking.
When it fires
Repull sends your Idempotency-Keyto the PMS as the booking's reference. A create reached the PMS again with a key it has already booked under — usually a retry after a timeout — and the PMS refused to book twice. The first request went through.
existing names the booking the PMS already holds (externalId, confirmationCode).
Response shape
Every Repull error follows the same envelope. The code is stable and safe to switch on.
{
"error": {
"code": "pms_duplicate",
"message": "Guesty already holds this booking: Guesty: a reservation with this originId already exists",
"fix": "This request was already made with the same idempotency key; look the booking up instead of creating it again.",
"docs_url": "https://repull.dev/docs/errors/pms_duplicate",
"request_id": "req_01J5X7Y8Z9ABCDEF12345678",
"provider": "guesty",
"existing": { "externalId": "64f1c2a9e1b2", "confirmationCode": "GY-a1B2c3D4" }
}
}How to fix
- Treat it as success: the booking exists. Do not create it again with a new key.
- Find it with `GET /v1/reservations` (filter by `listingId` and the check-in date) and match `existing.confirmationCode`.
- If it is not listed yet, it arrives with the next sync and `reservation.created` fires then.
Common gotchas
A new key would book the stay a second time. See Idempotency.
Examples
curl
curl "https://api.repull.dev/v1/reservations?listingId=4118&check_in_after=2026-10-01&check_in_before=2026-10-01" \ -H "Authorization: Bearer sk_live_YOUR_KEY"
TypeScript
if (res.status === 409) {
const { error } = await res.json()
if (error.code === 'pms_duplicate') {
// Already booked — look it up, never re-create
const list = await fetch(
`https://api.repull.dev/v1/reservations?listingId=${booking.listingId}&check_in_after=${booking.checkIn}&check_in_before=${booking.checkIn}`,
{ headers: { Authorization: `Bearer ${process.env.REPULL_API_KEY}` } },
).then(r => r.json())
return list.data.find((r: any) => r.confirmationCode === error.existing?.confirmationCode)
}
}If you're an AI agent
The booking already exists in the PMS from an earlier request with this Idempotency-Key. Do not create it again. Look it up with GET /v1/reservations using `existing.confirmationCode`.
Related
- Error reference — the full table of error codes
- Using Repull from AI agents — patterns for handling errors in agent loops
- Creating reservations
- Idempotency
Hit an error that isn't covered? Email hello@repull.dev with the request id from the response headers.