API Changelog
New endpoints and fields as they ship. Read the reference documentation.
November 11, 2026
Know which business a token is for
POST /oauth/token now returns franchise_id with the tokens, on the first exchange and on every refresh. Store it with the tokens to match a connection to the business.
Backdrops for a booking
List the backdrops a customer can choose for a booking, and save their choice.
GET /api/v1/photobooth_backgrounds?event_booking_id=lists the backdrops offered with that booking's package and free at its date and time, priced for the package.GET /api/v1/photobooth_backgroundspages when you sendpageorper, with the totals inmeta. Without them it returns the whole list.POST /api/v1/event_bookings/{event_booking_id}/event_photobooth_backgroundssets the backdrop from aphotobooth_background_id, at that backdrop's price.
Saving works on a package with no backdrop yet. Read show_backdrops on the event booking to see whether the package takes one. A page filtered by event_booking_id can hold fewer than per backdrops.
Send a finished design as approved
For widgets where the customer personalizes the design themselves. Add approved: true to POST /api/v1/template_selections and the image in template_image_url becomes the design's approved final artwork.
- The business gets the "design approved" message in place of the "design selected" one.
- Posting again for the same
design_idreplaces the approved artwork.
October 26, 2026
Designs and artwork proofs
Find a booking's designs, save the customer's template choice, and follow the proofs through to approval.
GET /api/v1/designs?event_id=lists a booking's designs, one per design collection, with each design'sstatus.GET /api/v1/design_template_categorieslists the collections, so you can tell a booking's designs apart.GET /api/v1/designs/{design_id}/artworkslists a design's proofs, newest first.PUT /api/v1/designs/{design_id}/artworks/{id}/approveand/rejectapprove a proof or send it back with adeclined_reason.
Posting to /api/v1/template_selections again for the same design_id replaces that design's selection and leaves its proofs alone.
October 22, 2026
Recurring bookings
Repeat a confirmed booking weekly or monthly and manage the series. Admins only.
GET /api/v1/recurring_eventslists series, grouped inmeta.sections.POST /api/v1/recurring_eventsmakes a booking recurring;GET /api/v1/recurring_events/newreturns its default settings.PUT /api/v1/recurring_events/{id}/generateand/remove_excessrun in the background and return202.GET /api/v1/events?recurring_event_id=lists a series' bookings. Events now carryrecurring_event_idandrecurring_event_role.
October 14, 2026
Price each proposal option
Quote each option on a proposal with alternatives: its packages, add-ons, adjustments and totals.
GET /api/v1/events/{event_id}/proposal_alternatives/{id}returns the option'ssub_total,tax_amount,final_totalanddeposit_amount_due.- Event bookings include
proposal_alternative_id. - Event add-ons include
total_price, the quantity times the unit price. include=event_adjustmentssideloads adjustments, such as travel fees and discounts, on an event or an alternative.
While a proposal has alternatives, the event's starting_balance, deposit_amount_due and balance_amount_due add every option together, so quote from each alternative instead. The include parameter is now listed in the reference for every endpoint that supports it.
October 12, 2026
Sync only what changed
Fetch just the bookings and proposals that changed since your last sync, instead of pulling everything again.
GET /api/v1/events?updated_since=2026-10-12T15:00:00Zreturns events changed at or after that time, including new booking question and questionnaire answers.
Every event now includes updated_at. Start each sync a minute before your last one began, since changes take a few seconds to become searchable.
Record a payment
Record a payment you collected outside Check Cherry, such as cash, check or Venmo.
POST /api/v1/events/{event_id}/event_paymentsrecords a payment on a booking.
October 9, 2026
Manage extras
Create, edit and remove the extras in your catalog. Every extra lives in a group inside an extra category, and customers see the group name as a heading.
POST /api/v1/extrascreates an extra in the group named byextra_group_idand returns it.PUT /api/v1/extras/{id}updates an extra's name, description, pricing or visibility. SetstatustoArchivedto archive it.DELETE /api/v1/extras/{id}removes an extra from the catalog. Bookings that already include it are unaffected.PUT /api/v1/extras/{id}/movemoves an extra to the end of another group.GET /api/v1/extra_categories/{extra_category_id}/extra_groupsreturns a category's groups in order.POST /api/v1/extra_categories/{extra_category_id}/extra_groupscreates a group in a category.GET /api/v1/extra_groups/{id}returns one group.PUT /api/v1/extra_groups/{id}renames a group.DELETE /api/v1/extra_groups/{id}removes a group and the extras in it.
Reads need offerings_read; everything else needs offerings_write. Change a group with the move endpoint, not with an update.
September 29, 2026
Signed webhooks
Every webhook now carries webhook-id, webhook-timestamp and webhook-signature headers in the Standard Webhooks format, so you can confirm a delivery came from Check Cherry and was not altered. The body is unchanged and verification is optional. webhook-id stays the same across retries and resends, so you can use it to skip duplicates. Read the webhooks guide.
September 28, 2026
Events list returns at most 100 per page
GET /api/v1/events caps per at 100. A larger value is clamped, not rejected, so read meta.per_page and page until page reaches meta.total_pages.
September 25, 2026
Proposal alternatives
Give a client options on a proposal. Each alternative holds its own packages and price, and the client books one of them.
POST /api/v1/events/{event_id}/proposal_alternativesadds an alternative built around one package and returns it.GET /api/v1/events/{event_id}/proposal_alternatives/{id}returns one alternative with the IDs of its packages.PATCH /api/v1/events/{event_id}/proposal_alternatives/{id}sets thecustom_titlethe client sees and thecustom_deposit_amount.DELETE /api/v1/events/{event_id}/proposal_alternatives/{id}removes an alternative and its packages.POST /api/v1/events/{event_id}/proposal_alternatives/{id}/duplicatecopies an alternative with its packages, add-ons, backdrop and discounts, and returns the copy.POST /api/v1/events/{event_id}/proposal_alternatives/{id}/choose_alternativepicks an alternative on the client's behalf and removes the rest.
Fetching needs assigned_event_read or unassigned_event_read; everything else needs assigned_event_write or unassigned_event_write. Add more packages to an alternative with POST /api/v1/events/{id}/event_bookings and its proposal_alternative_id. List every alternative with GET /api/v1/events/{id}?include=proposal_alternatives.
The first alternative you add creates two: the packages already on the proposal move into one, and the new package goes into the other. Choosing an alternative cannot be undone.
August 27, 2026
Staff check-ins
Staff clock in and out, optionally against a booking, and you can pull the resulting timesheet out for payroll or an external time tracker.
POST /api/v1/staff_check_insrecords a punch:kindofcheck_in,check_out, orstatus_updateto add a note or photo mid-shift.GET /api/v1/staff_check_inslists shifts, most recent first.GET /api/v1/staff_check_ins/{id}returns one shift. Add?include=event,notesto embed the booking and the shift's notes and photos.
Punching and reading your own shifts need own_staff_check_in_read_and_create. search_mode chooses whose shifts the list returns: my by default, or all for the whole business and user with a staff_id for one person, both of which need all_staff_check_in_read. check_in_at_start and check_in_at_end bound the list by check-in date and include both days. The whole resource is available only when the business has staff check-in turned on.
Correct or delete a recorded shift
Fix a punch someone got wrong, or drop one that should not be there.
PATCH /api/v1/staff_check_ins/{id}correctscheck_in_at,check_out_at, or the booking the shift is linked to.DELETE /api/v1/staff_check_ins/{id}removes the shift along with its notes and photos.
Both need own_staff_check_in_write for your own shift or all_staff_check_in_write for anyone's. Both grants are admin-only by default, and every correction is recorded in the shift's history with the user who made it.
August 14, 2026
Manage the packages on a proposal or booking
Sell more after the fact, or fix what is already there. Adding a package brings its add-ons across, and pricing, tax and the event title are recalculated on every change.
POST /api/v1/events/{id}/event_bookingsadds a package and returns the event booking it created.PATCH /api/v1/event_bookings/{id}edits a package, or swaps in a different one withuse_new_or_existing_packageset tonew.PATCH /api/v1/event_bookings/{id}/update_staffingsets how many staff the package needs.DELETE /api/v1/events/{event_id}/event_bookings/{id}removes a package.
All four need assigned_event_write or unassigned_event_write. To add a package, send its event_type_id and a starts_at_date, plus a proposal_alternative_id when the proposal has alternatives. What else is required depends on how the package is sold: a length, a unit count, or a unit range.
Two gotchas: the update replaces the package rather than merging into it, so anything you leave out is cleared. And an event always keeps one package, so removing the last one is a 403.
Convert a lead to a booking in one call
Turn a lead to a proposal or booking more easily. The lead's packages, venue, notes, and other details carry over, and the lead is marked converted. The lead's message history moves onto the new event.
POST /api/v1/leads/{id}/convert_to_bookingcreates a confirmed booking, or one awaiting signature withsignature_collected: false.POST /api/v1/leads/{id}/convert_to_proposalcreates a proposal, holding the date withproposal_date_reserved.
Both need event_create, and both take an empty body. Every field they accept is optional and overrides what came from the lead, using the same names as POST /api/v1/bookings.
One gotcha: packages replaces the lead's packages outright rather than merging with them. Leave it out to book what the lead actually asked for. Converting a lead that has already been converted produces a second event and leaves the first alone.
August 13, 2026
Bookings and proposals each have their own endpoint
Creating a booking and creating a proposal are separate calls, so each one documents only the fields that apply to it.
POST /api/v1/bookingscreates a confirmed booking, or one awaiting signature withsignature_collected: false.POST /api/v1/proposalscreates a proposal, holding the date withproposal_date_reservedand expiring onproposal_valid_through.
Both take the event's packages as packages, and both need event_create. contact_type is one of New Customer, Existing Customer or None; any other value is now a 422 rather than an event created with no client on it. Existing Customer also needs customer_user_id.
POST /api/v1/events is no longer documented. It keeps working, so existing integrations, including Zapier, are unaffected.
Suggestion lists are readable
The song questions on a questionnaire draw from a suggestion list. You can now read those lists.
GET /api/v1/suggestion_listsreturns every list with itstitleanditem_count.GET /api/v1/suggestion_lists/{id}returns one list's songs, each with artist, album, yoursongNotes, and Spotify, YouTube, Apple Music and SoundCloud links.
Both need planning_read.
Also documented: suggestionListId and allowCustomSongEntry on questionnaire fields. On a field, suggestionListId is the list it draws from; in values, songSuggestionListId is where the chosen song came from.
August 11, 2026
Questionnaires
A questionnaire collects what a business needs once a booking is secured: timelines, song requests, setup notes, signatures. The whole surface is now documented.
/api/v1/questionnairescovers the lifecycle: list and read them, attach one from a template, write answers, collect a signature, mark complete or incomplete, reset, delete./api/v1/questionnaire_templateslists and reads the templates you attach from, and needsplanning_read.POST /api/v1/questionnaires/create_externalattaches a questionnaire hosted on another site. Readkindbefore rendering one: it carries anexternal_urland no questions, and you mark it complete yourself.
data holds the questions and values holds the answers, keyed by question uuid. Both are schemas, with a table naming every field type and the element its answer is stored under. Three things to know before writing answers:
- Answers merge by uuid. The array you send under a uuid replaces that question's answers whole,
[]clears one, andreplace: truereplaces the entire blob. valuesis required, and an answer carrying a type or element name the question does not declare is a 422.- A field group is a tab, and headers, explainer text, images and separators are fields too, so not every field takes an answer.