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_backgrounds pages when you send page or per, with the totals in meta. Without them it returns the whole list.
  • POST /api/v1/event_bookings/{event_booking_id}/event_photobooth_backgrounds sets the backdrop from a photobooth_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_id replaces 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's status.
  • GET /api/v1/design_template_categories lists the collections, so you can tell a booking's designs apart.
  • GET /api/v1/designs/{design_id}/artworks lists a design's proofs, newest first.
  • PUT /api/v1/designs/{design_id}/artworks/{id}/approve and /reject approve a proof or send it back with a declined_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_events lists series, grouped in meta.sections.
  • POST /api/v1/recurring_events makes a booking recurring; GET /api/v1/recurring_events/new returns its default settings.
  • PUT /api/v1/recurring_events/{id}/generate and /remove_excess run in the background and return 202.
  • GET /api/v1/events?recurring_event_id= lists a series' bookings. Events now carry recurring_event_id and recurring_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's sub_total, tax_amount, final_total and deposit_amount_due.
  • Event bookings include proposal_alternative_id.
  • Event add-ons include total_price, the quantity times the unit price.
  • include=event_adjustments sideloads 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:00Z returns 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_payments records 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/extras creates an extra in the group named by extra_group_id and returns it.
  • PUT /api/v1/extras/{id} updates an extra's name, description, pricing or visibility. Set status to Archived to 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}/move moves an extra to the end of another group.
  • GET /api/v1/extra_categories/{extra_category_id}/extra_groups returns a category's groups in order.
  • POST /api/v1/extra_categories/{extra_category_id}/extra_groups creates 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_alternatives adds 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 the custom_title the client sees and the custom_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}/duplicate copies an alternative with its packages, add-ons, backdrop and discounts, and returns the copy.
  • POST /api/v1/events/{event_id}/proposal_alternatives/{id}/choose_alternative picks 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_ins records a punch: kind of check_in, check_out, or status_update to add a note or photo mid-shift.
  • GET /api/v1/staff_check_ins lists shifts, most recent first.
  • GET /api/v1/staff_check_ins/{id} returns one shift. Add ?include=event,notes to 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} corrects check_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_bookings adds a package and returns the event booking it created.
  • PATCH /api/v1/event_bookings/{id} edits a package, or swaps in a different one with use_new_or_existing_package set to new.
  • PATCH /api/v1/event_bookings/{id}/update_staffing sets 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_booking creates a confirmed booking, or one awaiting signature with signature_collected: false.
  • POST /api/v1/leads/{id}/convert_to_proposal creates a proposal, holding the date with proposal_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/bookings creates a confirmed booking, or one awaiting signature with signature_collected: false.
  • POST /api/v1/proposals creates a proposal, holding the date with proposal_date_reserved and expiring on proposal_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_lists returns every list with its title and item_count.
  • GET /api/v1/suggestion_lists/{id} returns one list's songs, each with artist, album, your songNotes, 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/questionnaires covers 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_templates lists and reads the templates you attach from, and needs planning_read.
  • POST /api/v1/questionnaires/create_external attaches a questionnaire hosted on another site. Read kind before rendering one: it carries an external_url and 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, and replace: true replaces the entire blob.
  • values is 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.