Skip to content

Add entries and bookings with the API

Webhooks send what happens on your website to other apps. The API goes the other way: with a key you create in the Cloud tab, Zapier, Make, n8n or your own systems add entries to your tables, add bookings of times and places in classes, and read entries. Included in every plan and in the trial, without credits.

Ask ChatGPT Ask Claude

Create an API key

  1. Open Cloud in the editor and scroll to Connections, then API keys.

  2. Click Create an API key, give it the name of the service that will use it, like Zapier, and tick what it may do.

  3. Click Create key and copy the key that starts with fsk_. frascati shows it this once: it keeps only a fingerprint of it and cannot show it again.

Read entries
Read the entries of your tables, visitors' entries too, never orders. Its name in the API: entries:read.
Add entries
Add entries to your tables. Its name in the API: entries:write.
Add bookings
Add bookings of times and places in classes. Its name in the API: bookings:write.

A key that adds or reads entries may also list your tables with their columns, and every key may read your services and your classes' dates, which its work needs. Make one key per service: Revoke stops a key at once and leaves the others working. A website has up to 10 keys. Whoever has a key can do what it allows, so keep it out of your website's code and out of shared documents.

Keys work while you have a plan or a trial. Without one, frascati makes no new key, and every request with a key answers plan_required; your keys stay and work again once you choose a plan.

Requests

Every address starts with https://frascati.app/api/v1. Send the key in the Authorization header as Bearer and the key, and bodies as JSON with Content-Type: application/json. Answers are JSON too. The API is for servers and tools like Zapier: it answers no browser on another website.

Check a key
curl https://frascati.app/api/v1/key \
  -H "Authorization: Bearer fsk_your_key"

The answer names the website, the key and its permissions. Zapier and Make use such a request to test a connection.

GET /api/v1/key
The key's website and permissions.
GET /api/v1/tables
Your tables, with their columns and how many entries each has. Needs Read entries or Add entries.
GET /api/v1/tables/{table}/entries
The entries of a table, newest first. Needs Read entries.
POST /api/v1/tables/{table}/entries
Adds an entry. Needs Add entries.
GET /api/v1/booking
Your online booking: services, team, time zone.
GET /api/v1/booking/times
The free start times of a day.
POST /api/v1/bookings
Adds a booking of a time. Needs Add bookings.
GET /api/v1/classes
Your classes and events and their coming dates with the places left.
POST /api/v1/class-bookings
Adds places on a date of a class or an event. Needs Add bookings.

Limits and errors

A key makes up to 60 requests a minute. Every answer says how many are left in X-RateLimit-Remaining; past the limit the answer is 429 with Retry-After, the seconds until the next minute. A website adds up to 200 bookings, of times and places in classes together, and 1,000 entries a day through the API, counted per day in UTC; past that the answer is 429 daily_limit with Retry-After, the seconds until midnight UTC. An error is JSON with a code to act on and a sentence to read: { "error": { "code": "missing_values", "message": "Fill in: name.", "fields": ["name"] } }.

400 invalid_json, invalid_request, invalid_cursor

What it means
The body is no JSON object, a part of the address is missing, or the cursor is from another table.

401 missing_key, invalid_key, revoked_key

What it means
No key, a wrong key, or one you revoked.

403 missing_permission

What it means
The key may not do this. Create one with the permission.

403 plan_required

What it means
The website's owner has no plan and no trial. The keys work again once there is one.

403 limit_reached

What it means
Your plan's entries are used up.

404 not_found

What it means
No such table (Orders is not in the API), or no such address in the API.

409 needs_force

What it means
The time or the date needs a look. The answer says why; send it again with "force": true to book it anyway.

409 booking_not_set_up, classes_not_set_up, date_cancelled

What it means
The website takes no bookings of this kind, or you cancelled the date.

422 missing_values, invalid_values, empty_entry

What it means
Something to fix in the entry; fields names the columns.

422 invalid_booking, unknown_service, unknown_class, not_a_date

What it means
Something to fix in the booking: the service, the class, the date or the name.

429 rate_limited

What it means
More than the requests of a minute, or more wrong or revoked keys from one address than a minute takes.

429 daily_limit

What it means
The website added what a day allows through the API. Retry-After says the seconds until midnight UTC.

500 server_error

What it means
Something went wrong on our side. Try again in a moment.

Add and read entries

Your tables and their columns
curl https://frascati.app/api/v1/tables \
  -H "Authorization: Bearer fsk_your_key"
Add an entry to the table requests
curl -X POST https://frascati.app/api/v1/tables/requests/entries \
  -H "Authorization: Bearer fsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"name": "Lena Graf", "email": "lena@example.com", "message": "A quote for a new kitchen"}'

Send the values by the columns' keys, as GET /tables lists them, or by the columns' names: Zapier and Make send what you type. They are checked like in the Cloud tab: a price may be 18.50, 18,50 or CHF 18.50, an email must be one, a choice one of its options. A required column left out or a value that does not fit answers 422 with the columns in fields; names that are no column come back in ignored. The answer 201 has the entry as it was saved.

  • In a table your visitors fill, like requests or a waitlist, an entry from the API is one like theirs: it shows under the table, and your webhooks get entry.created with source set to api. You get no email for it.
  • In a table your website shows, like a menu or a price list, it goes to the end of the list. Send { "data": { … }, "hidden": true } to keep it off the website for now.
  • It counts toward your plan's entries per website: 300 with Starter, 5,000 with Pro, 50,000 with Business.
  • The table Orders is not in the API, neither to read nor to add to: it holds your buyers' names, addresses and payments. Each paid order reaches Zapier, Make or n8n through the webhook order.paid.
Read entries, newest first
curl "https://frascati.app/api/v1/tables/requests/entries?limit=20" \
  -H "Authorization: Bearer fsk_your_key"

limit is 50 unless you say, at most 100. When there are more, the answer's next holds a cursor: send it as cursor for the next page. Each entry has its id, createdAt and its values in data, in a table your website shows also whether it is hidden.

Add bookings

Your services and team
curl https://frascati.app/api/v1/booking \
  -H "Authorization: Bearer fsk_your_key"
The free times of a day
curl "https://frascati.app/api/v1/booking/times?service=cut&date=2026-10-20" \
  -H "Authorization: Bearer fsk_your_key"
Add a booking
curl -X POST https://frascati.app/api/v1/bookings \
  -H "Authorization: Bearer fsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"service": "cut", "date": "2026-10-20", "time": "10:00", "name": "Lena Graf", "email": "lena@example.com", "phone": "+41 79 000 00 02", "note": "Booked by phone"}'

A booking from the API is one you add yourself under Add booking in the Cloud tab: confirmed at once, with the person of your team you name in staff, else whoever is free. A time that overlaps other bookings with no place left, lies outside your opening hours, on a closed day or in the past answers 409 with needs_force and what is wrong; send the same again with "force": true to book it anyway. service, date, time and name are required; people is for tables, email, phone and note are optional.

frascati sends the guest no email for a booking from the API, neither a confirmation nor reminders: the system that made it tells the guest. It shows in the Cloud tab as added through the API, in your calendar link and your CSV file, and your webhooks get booking.created with source set to api.

Places in classes and events

Your classes and their coming dates
curl https://frascati.app/api/v1/classes \
  -H "Authorization: Bearer fsk_your_key"
Book places on a date
curl -X POST https://frascati.app/api/v1/class-bookings \
  -H "Authorization: Bearer fsk_your_key" \
  -H "Content-Type: application/json" \
  -d '{"session": "vinyasa~2026-10-19~18:30", "seats": 2, "name": "Lena Graf", "email": "lena@example.com"}'

session comes from GET /classes; class, date and time work too. The date must be one of the class's dates and not cancelled. When it has fewer places left than you ask for, or is over, the answer is 409 with needs_force and left or the warning past; with "force": true the guest gets the places anyway, as when you add a guest in the Cloud tab. No email goes to the guest here either.

Zapier

  1. Add an action Webhooks by Zapier with the event POST.

  2. URL: the address, like https://frascati.app/api/v1/tables/requests/entries. Payload Type: json.

  3. Data: one line per column, the column's key or name on the left, the value from your trigger on the right.

  4. Headers: Authorization with Bearer fsk_your_key. Then Test step: Zapier shows frascati's answer.

Make

  1. Add the module HTTP and Make a request.

  2. URL: the address. Method: POST. Headers: Authorization with Bearer fsk_your_key.

  3. Body type: Raw, content type JSON (application/json), and as request content the JSON with your values, like {"name": "{{1.name}}", "email": "{{1.email}}"}. Tick Parse response.

n8n

  1. Add an HTTP Request node. Method: POST, URL: the address.

  2. Authentication: Generic Credential Type, then Header Auth, with the name Authorization and the value Bearer fsk_your_key.

  3. Turn on Send Body, choose JSON and add your values, by the columns' keys.

What the API does not do yet

  • No app of its own in Zapier's or Make's list and no sign-in with OAuth: you connect with their HTTP steps and a key.
  • Entries and bookings are added, not changed or deleted; that stays in the Cloud tab.
  • Bookings are not read through the API. Your webhooks send each new, confirmed and cancelled one, and the calendar link under Bookings has them all.
  • No emails to guests for bookings from the API.
  • Keys belong to one website; a key for all websites of an account does not exist.
  • No orders, payments, products, form messages or website content through the API. Paid orders come through the webhook order.paid.
  • No two-way calendar sync: your bookings go to Google Calendar, Apple Calendar or Outlook through the calendar link, read only, and a busy time there does not block a time on your website.
  • No connection to Google Business Profile, a CRM or a newsletter tool of its own; they go through Zapier, Make or n8n.

Something missing or unclear? Write to us.