Sites and roles
A site's own details and settings, who can do what inside it, an audit trail, and renaming our words to match yours.
Portland has an address, a phone number, opening hours and a set of preferences. Inside it, some people can see invoices and some can't. And Sarah doesn't call her customers "clients" — her staff say "households".
That's this module: the operational detail of a site, the roles inside it, the record of who changed what, and the vocabulary your staff see.
One site, one id
You created Portland in the dashboard, and that gave it a database, a region, an owning group — and an id. What lives here is the same site's operational detail (address, phone, settings) inside that database, under that same id.
So the value you send as X-Location-Id is also what location_id means in any request
body. You can leave those fields out and we'll fill them in; send a different id and
you'll get a 422, because there is no other site in this database to name.
Sites are created by provisioning, never by API. A second premises is a second site, with its own database and its own keys.
Read it instead
Sites and roles is a site's own details and settings, who can do what inside it, and a record of who changed what. REST, a secret key, a location header.
A site carries an address, a phone number, opening hours and its settings. Roles inside it hold permissions. An audit log records every change. And language overrides rename our nouns to yours, so staff read households rather than clients.
Read the audit log and a compliance screen is something you query rather than something you build. Create a role once and everyone assigned to it inherits the same permissions. Subscribe to organizations.role.created to mirror them into your own admin.
organizations.view reads details, settings, roles and audit logs. It is the scope an internal dashboard wants, and the one an integration almost never needs to write.
Sites and roles: a site's details, the roles inside it, an audit trail, and your own words for our nouns. The guide is below.
Before you start
- The module switched on for the site. If it isn't, everything below returns
403regardless of your key — check the site's modules on the Locations page first. - A credential with the right scopes —
organizations.viewto read. - The site's id, for
X-Location-Idon every request.
The endpoints
| For | Endpoint |
|---|---|
| Site details | GET /api/modules/organizations/locations |
| Get one site | GET /api/modules/organizations/locations/{location} |
| Change site details | PATCH /api/modules/organizations/locations/{location} |
| Site settings | GET /api/modules/organizations/locations/{location}/settings |
| Save settings | PUT /api/modules/organizations/locations/{location}/settings |
| Roles in the site | GET /api/modules/organizations/roles |
| Create a role | POST /api/modules/organizations/roles |
| Who changed what | GET /api/modules/organizations/audit-logs |
| Audit filter options | GET /api/modules/organizations/audit-logs/filters |
| Audit summary | GET /api/modules/organizations/audit-logs/statistics |
| Available languages | GET /api/modules/organizations/language |
| Terms you can rename | GET /api/modules/organizations/language-terms |
| Your renamings | GET /api/modules/organizations/language-overrides |
| Rename a term | POST /api/modules/organizations/language-overrides |
Site details and settings
Details are the site's own record — the things you'd print on an invoice. Read and change them like any resource.
Settings are a key-value bag, saved as a whole:
curl -X PUT "https://api.hyphabase.com/api/modules/organizations/locations/$SITE_ID/settings" \
-u sk_live_xxx: -H "X-Location-Id: $HYPHABASE_LOCATION_ID" \
-H "Content-Type: application/json" \
-d '{"settings": {"invoice_footer": "Thank you — Brightside Cleaning", "week_starts_on": "monday"}}'Settings save as a whole set
PUT with a settings array replaces what's there. Read the current settings, change the
key you care about, and send the merged result — otherwise you'll quietly drop everything
you didn't include.
Roles inside a site
These are permissions for people working in Portland — a cleaner who sees their own schedule, a coordinator who sees invoices too. Distinct from the dashboard roles that decide who can open a site or issue a key, which are set up by clicking: Staff and roles.
Roles hold module permission strings — the same clients.view / schedules.create names a
key's scopes use. See Who can do what.
Assigning a role to a person is in the Staff module; defining the roles is here.
Who changed what
The audit log is the most underrated thing in this module. It answers "who deleted that customer" without a conversation.
curl -G https://api.hyphabase.com/api/modules/organizations/audit-logs \
-u sk_live_xxx: -H "X-Location-Id: $HYPHABASE_LOCATION_ID" \
--data-urlencode "per_page=50"tells you what you can filter by, generated from what's actually in the log — so build a filter UI from that rather than hardcoding options.
GET /api/modules/organizations/audit-logs/statisticsgives you counts, for a "recent activity" panel.
It's read-only, which is the point. Nothing in the API lets you edit or delete an audit entry.
Calling things what your staff call them
Sarah's team says "households", not "clients". Rather than making everyone translate, override the term.
GET /api/modules/organizations/language-termslists every term you can rename;
POST /api/modules/organizations/language-overridessets one.
Two things to be clear about. This changes display labels, not the API — field names,
endpoints and event types are unaffected, so your code still says clients. And it's per
site, so Portland can say "households" while Salem says "clients", which is either a feature
or a trap depending on how much you like consistency.
If you're building your own front end you may not need this at all — you control your own labels. It exists for the dashboard, and for anything reading labels from the API.
What you get told about
| Event | When |
|---|---|
organizations.location.created | A site's operational record is created |
organizations.location.updated | Its details change |
organizations.role.created | A role is added |
What to grant
| Scope | Lets you |
|---|---|
organizations.view | Read site details, settings, roles and audit logs |
organizations.create | Create roles and language overrides |
organizations.update | Change site details and settings |
organizations.delete | Delete roles and overrides |
organizations.view is safe for a publishable key — enough for a booking page to show a
site's address and phone number.
organizations.update changes settings that other modules read, so it has wider reach than
it looks.
What goes wrong
Recipes
Show your customers the right site details. Read the site's record and render its
address and phone on a booking page. A publishable key with organizations.view is enough.
An activity feed. Poll audit-logs newest-first and render it. Drive the filter options
from the filters endpoint so it stays right as the log grows.
Match the vocabulary your staff already use. Fetch language-terms, let an admin rename
the handful that matter, and store overrides per site.