Resy
Card at some venues · no Resy password · OTP unless the end_user has an active session
Search Resy by passing providers: ["resy"]; a dining search without providers searches OpenTable only. No Resy password is ever needed: Resy texts a one-time code to customer.phone_number, and the booking returns requires_action with next_action.type "otp". If that phone already has a Resy account, customer.email must match the account's email, or the booking fails with error_code: "account_email_mismatch". If it has none, a Resy account is created during the booking. party_size is required (1–20).
Some Resy venues need a card. Check card_required on the POST /v1/availability/search response: false means no card is needed; true means send metadata.payment (the same shape as on OpenTable) or have the card authorized through AgentCard. A booking that reaches Resy's card form without a card fails with error_code: "card_required". window_minutes on availability keeps only slots within that many minutes of the requested datetime.
Each Resy slot from availability, and from a search with a datetime, carries terms: the cancellation fee, deposit and deadlines Resy states for it. Resy gives these as numbers with no currency or unit, so neither is filled in. A confirmed Resy booking carries confirmation.terms with the venue's cancellation sentence word for word, read just before the reservation is made. See Restaurant terms.
End-user sessions
Send end_user, your stable id for the diner, on POST /v1/bookings. Once a booking signs the diner in with the code, Ophelia keeps that Resy sign-in for them, and their later Resy bookings with the same end_user are made signed in as them, with no code. If Resy stops accepting the session, it is marked expired and the next booking goes through the code again. To connect a diner ahead of a booking, list or disconnect sessions, or check whether their Resy account has a card on file, see Sessions.
Cancelling or modifying
A confirmed Resy booking cannot be cancelled or modified through Ophelia. POST /v1/bookings/{id}/cancel leaves it confirmed with error_code: "cancellation_unsupported", and the diner cancels with Resy directly. A booking still waiting on its code can be cancelled.
If you're testing against a real Resy account, the customer fields you submit (email, phone number) must match the info tied to that account, or authentication will fail.