API keys

Every API request carries a key, and the key decides two things: whose booking pages and bookings the request can see, and what it can do with them. Each key belongs to the clndr.pro account that created it. A key can't reach another account's pages, so if your site shows booking pages for three people, each of them creates a key (or you use the embed, which needs none).

Two types

SecretPublishable
Prefixclndr_sk_clndr_pk_
Lives inYour server: env vars, a secrets managerBrowser bundles, mobile apps, HTML
Env var we use in these docsCLNDR_SECRET_KEYNEXT_PUBLIC_CLNDR_PUBLISHABLE_KEY
Rate limit300 requests per 60 s120 requests per 60 s
Read booking pages and questionsYesYes
Read open slotsYesYes
Create bookingsYesYes
List and read bookings (guest names, emails, answers)YesNo
Confirm and cancel bookingsYesNo

In scope terms: publishable keys hold booking_pages:read, booking_pages:slots and bookings:create. Secret keys hold those plus bookings:read and bookings:write. A request outside a key's scopes gets 403 API key is missing required scope(s): …. The dashboard gives every key its type's full set; narrower custom scopes aren't available yet.

Create a key

  1. Open API Keys

    Sign in at www.clndr.pro and open API keys in the sidebar.

  2. Choose the type and a name

    Choose Create API Key, pick Secret key or Publishable key, and name it after where it will be used: "Marketing site", "CRM sync job". The name is only shown to you.

  3. Copy it now

    The full key is shown once. clndr.pro stores a hash and the first 16 characters (for example clndr_sk_4f1c2a9), so a lost key can't be recovered, only replaced.

You can create five keys an hour.

Where keys go

The rule is the prefix. A clndr_sk_ key never reaches a browser; a clndr_pk_ key can go anywhere.

In Next.js, only variables that start with NEXT_PUBLIC_ are copied into client bundles, at build time. That makes the naming do the work:

.env.local
# Server only. Read it in server components, server actions, route handlers.
CLNDR_SECRET_KEY=clndr_sk_...
 
# Inlined into the browser bundle. Safe, and visible to anyone.
NEXT_PUBLIC_CLNDR_PUBLISHABLE_KEY=clndr_pk_...

Don't put a secret key in a NEXT_PUBLIC_ variable, and don't read process.env.CLNDR_SECRET_KEY in a file marked 'use client'. Next.js leaves non-public variables out of client code, so that read gives you undefined in the browser: the SDK throws Clndr: `apiKey` is required when you build the client, and a hand-written fetch gets 401. Adding import 'server-only' to the file that builds your secret-key client turns the mistake into a build error instead.

Because public variables are baked in at build time, changing NEXT_PUBLIC_CLNDR_PUBLISHABLE_KEY needs a rebuild, not just a restart.

On Vercel

vercel env add CLNDR_SECRET_KEY production
vercel env add NEXT_PUBLIC_CLNDR_PUBLISHABLE_KEY production

Run them again with preview and development if those environments call clndr.pro too. You can use the same keys everywhere, or create separate ones so revoking a leaked preview key doesn't touch production.

What each key exposes

A publishable key is public the moment you deploy it: anyone can read it from your page source. With it they can list every booking page on your account (including inactive and private ones), read their questions and open slots, and book those open slots, the same as a guest on your site could. Bookings made with a publishable key must match a slot the API is offering right now, so the key can't drop meetings outside your hours or past the page's max_days_ahead. They can't see who booked, change a booking, or touch your pages or availability. If a private page shouldn't be discoverable at all, keep it off accounts whose publishable keys you ship, or book it through your server with the secret key instead.

A secret key reads every booking on the account: guest names, email addresses, times and answers. It can also confirm and cancel bookings. It can't edit booking pages, availability, access codes or account settings; those exist only in the dashboard.

Rotate a key

Rotation doesn't need downtime, because two keys can be active at once:

  1. Create a new key of the same type.
  2. Put it in your env vars and deploy.
  3. Check the old key's Last used date in the dashboard. Once it stops moving, choose Revoke on it.

Revoke switches a key off and keeps it in the list, so you can still see when it was last used. Requests with it get 401 API key has been revoked. Delete removes it entirely; requests then get 401 Invalid API key. Revoke first, delete later.

Keys don't expire. The API honours an expiry date on a key, but the dashboard has no way to set one yet.

If a secret key leaks

Revoke it in the dashboard straight away; it stops working on the next request. Then create a replacement, deploy it, and look through Meetings for bookings that were cancelled or confirmed without you. The key never had access to your account itself, so there's no password to change.

If it was committed to git, revoking is what protects you. Rewriting history doesn't remove copies that were already pulled or forked.

Sending the key

Use either header. They're equivalent:

Authorization: Bearer clndr_sk_...
x-clndr-key: clndr_sk_...

Always send requests to https://www.clndr.pro/api/v1. The bare clndr.pro host redirects to www, and HTTP clients strip Authorization when a redirect changes host, so the request arrives without a key and fails with 401 Missing API key.