Credentials
Every call to the Grondia API carries an API key. A key belongs to one campground, carries a set of scopes that decide which endpoints it may call, and is created by that campground’s administrator. OAuth 2.0 is planned; until then, credentials are API keys only.
Who creates a key
Section titled “Who creates a key”For your own development, ask Felix, felix@grondia.com, or Siro, siro@grondia.com, for a sandbox: you get a read-only key for a test campground (the Quickstart says what it contains).
For a real campground, its administrator creates the key in the Grondia admin under Settings → App Store → Developer API. They give it a name, tick the scopes, optionally set an expiry in days, and copy the key. Then they paste it into your product.
- The key is shown once. Grondia stores only a hash of it, so nobody can show it again. If it is lost, the administrator revokes it and creates a new one.
- One key per campground. A product used by several campgrounds asks each one for its own key, and stores them apart.
- The campground needs the API module. The Developer API card is locked for a campground without it. The campground asks its Grondia contact; this page quotes no price.
A product that wants a review or a listing in the Grondia App Store starts at the Partner program.
Before the first production key for your product, you sign short API terms of use, which also cover how you handle the guests’ personal data. Felix or Siro send them to you. The sandbox key needs no signature.
Sending the key
Section titled “Sending the key”A key is ck_ followed by 29 letters, digits, - and _: 32 characters in
all. The first 8 (ck_ and five more) are its prefix, which the admin shows
next to the key’s name so the operator can tell keys apart. The rest is secret.
Send the key as a bearer token in the Authorization header of every request,
over HTTPS. Here it lists the campground’s sites:
curl https://api.campone.ch/api/v1/public/sites/ \ -H "Authorization: Bearer ck_a1b2cXXXXXXXXXXXXXXXXXXXXXXXX"import requests
key = "ck_a1b2cXXXXXXXXXXXXXXXXXXXXXXXX"requests.get( "https://api.campone.ch/api/v1/public/sites/", headers={"Authorization": f"Bearer {key}"}, timeout=10,)const key = "ck_a1b2cXXXXXXXXXXXXXXXXXXXXXXXX";await fetch("https://api.campone.ch/api/v1/public/sites/", { headers: { Authorization: `Bearer ${key}` },});The scheme is case-sensitive: write Bearer, not bearer. Each key also has
its own rate limit: 1000 requests per rolling hour by
default.
Scopes
Section titled “Scopes”A key can call an endpoint only if it carries the scope the endpoint asks for.
Paths below are relative to https://api.campone.ch/api/v1/public/.
| Scope | Opens | In the admin |
|---|---|---|
bookings:read |
GET bookings/, GET bookings/{id}/ |
Yes |
bookings:write |
POST bookings/, POST bookings/{id}/cancel/ |
Yes |
sites:read |
GET sites/; also enough for GET ari/ and GET ari/restrictions/ |
Yes |
customers:read |
GET customers/ |
Yes |
invoices:read |
GET invoices/ |
Yes |
ari:read |
GET ari/, GET ari/restrictions/ |
On request |
ari:write |
PUT ari/restrictions/, and GET ari/restrictions/ |
On request |
webhooks:write |
Every webhook endpoint: list, register, delete, delivery log, replay | On request |
pos:read |
GET pos/products/, GET pos/transactions/{external_ref}/ |
Yes, on the External POS system card |
pos:write |
POST pos/transactions/ |
Yes, on the External POS system card |
config:read |
Nothing documented here. Grondia’s own onboarding tools read a campground’s booking-page setup with it. | No |
config:write |
Nothing documented here. Grondia’s own onboarding tools write a campground’s booking-page setup with it. | No |
catalog:write |
Nothing documented here. Grondia’s Sites Studio, where campground websites are edited, reads and writes the booking page’s unit names, texts and photos with it. | Yes, for the Sites Studio |
The Developer API screen offers six scopes: the five reads and writes for
bookings, sites, customers and invoices, plus catalog:write. The campground’s
administrator creates pos:read and pos:write somewhere else: on the
External POS system card in the App Store, for a till (see
Shop and restaurant tills). A key with
any of the others, such as ari:read or webhooks:write for a channel manager
(see Channel managers), is created on
request: write to Felix, felix@grondia.com, or to
Siro, siro@grondia.com, and say which campground and
which scopes. Ask for the scopes your product uses and no more; the operator
sees every scope on the key.
The Zapier card in the admin creates its own key with a zapier scope for
Grondia’s Zapier integration. It opens nothing documented here; the
Zapier recipe says how Zapier connects.
When a call is refused
Section titled “When a call is refused”| Status | Meaning | What to do |
|---|---|---|
401 Unauthorized |
The key is missing, unknown ({"detail": "invalid_key"}), revoked or expired ({"detail": "key_inactive"}), or the header is not Authorization: Bearer <key>. The response has a WWW-Authenticate: Bearer realm="api" header. |
Check the header. If the key was revoked or has expired, ask the campground for a new one. Retrying does not help. |
403 Forbidden |
The key is valid but lacks the scope this endpoint needs. | Ask for a key with that scope (see the table above). |
Every other error, and the shapes its body comes in, is in Errors.
Expiry and revocation
Section titled “Expiry and revocation”A key never expires unless the administrator sets an expiry when creating it.
The administrator can revoke a key at any time on the same screen, and it stops
working at once. After expiry or revocation every call answers 401 with
key_inactive.
The administrator also sees when each key was last used, and its recent requests: method, path, status and time. Request and response bodies are not logged.
Personal data
Section titled “Personal data”Guest personal data is redacted by default:
- Bookings:
guest_first_nameandguest_last_namecome back empty andguest_emailas"[redacted]". Dates, site, status, price and references are never redacted. - Customers:
first_nameandlast_namecome back empty,emailas"[redacted]"andphone_numberempty.
Two scopes lift the redaction, bookings:pii and customers:pii. Neither can
be created in the admin today. If your product needs personal data, write to
Felix, felix@grondia.com, or to Siro,
siro@grondia.com; access is decided case by case
with Felix. Asking for personal data
says what to put in the message.
Webhook payloads never carry personal data. For a booking’s details, fetch the booking; the rules above apply to what comes back. What each call returns, field by field, is in Personal data. A guest-messaging product or a CRM works within these limits as the Guest messaging and CRM recipe shows.
OAuth 2.0
Section titled “OAuth 2.0”Planned. Today there is no way for an operator to approve an app on their own, so these docs describe API keys only. When OAuth is available for partners, it will be documented here.