# Build on BackendFree

> One REST API and a set of TypeScript packages for the content, bookings, payments and analytics behind a website, and what to read first.

BackendFree keeps what sits behind a website: the pages its owner edits, the
appointments, the payments and the visitor figures. The website itself stays
yours, built with whatever you like and hosted wherever you like. It reads and
writes through one REST API, and the TypeScript packages below wrap that API.

## Where calls go

Every call goes to `https://backendfree.com/api/v1`, with a key in the `Authorization` header.

```sh title=terminal
curl https://backendfree.com/api/v1/project \
  -H "Authorization: Bearer pk_live_..."
```

No path names a website. The key says which project is asking, so one front end
can serve more than one website by swapping the key.

## Two kinds of key

A **publishable** key (`pk_live_...`) is safe in a web page: it reads published
content, lists free times and takes a booking. A **secret** key
(`sk_live_...`) also lists every booking, reads the payments and starts a
checkout, so it belongs on a server only. Neither changes the content or the
diary's setup, and neither refunds: those stay in the dashboard. [Keys and
allowed websites](/docs/keys/) has the whole table.

## The packages

| Package | For |
|---|---|
| [`@backendfree/core`](/docs/core/) | The client every other package is built on: keys, errors, caching, idempotent writes and verifying a webhook. |
| [`@backendfree/cms`](/docs/cms/) | Published pages as the typed sections the owner edits, and knowing when to rebuild. |
| [`@backendfree/bookings`](/docs/bookings/) | Services, staff, free times and taking a booking, with a token the customer manages it by. |
| [`@backendfree/payments`](/docs/payments/) | Taking a payment into the business's own account, from your own server with a secret key. |
| [`@backendfree/webanalytics`](/docs/webanalytics/) | Reporting page views from your own server, for the visitors and crawlers a script never sees. |
| [`@backendfree/inbox`](/docs/inbox/) | Sending a contact form's message to the website's inbox, past the spam checks, and reading them back. |

Plain ES modules with no dependencies, so the same import works in a browser,
on a server, in a build script and in a worker at the edge.

```sh title=terminal
npm install @backendfree/core @backendfree/bookings
```

## What to read next

- [Quickstart](/docs/quickstart/): from a key to a paid booking in six steps.
- [Booking page](/docs/booking-page/): bookings on a page hosted here, with nothing to build.

- [Times and timezones](/docs/times/): why every time carries an offset.
- [Verify a delivery](/docs/webhooks/): the webhooks your server receives.
- [Allowances and rate limits](/docs/limits/), and the [error codes](/docs/errors/) to branch on.
