REST API and per-tenant scoping

Booknetic SaaS REST API guide — how /wp-json/booknetic/v1/ becomes tenant-aware, what tenants can call, and what owner operations stay inside the admin UI.

Version:
Categories

What this REST API is for

Booknetic includes a WordPress REST API for working with Booknetic data from external systems.

In a normal Booknetic installation, the REST API is available under this namespace:

/wp-json/booknetic/v1/

In Booknetic SaaS, the same Booknetic REST API is tenant-aware. That means a tenant's API request works inside that tenant's own Booknetic workspace.

Use it when a tenant or their developer wants to connect Booknetic with systems such as:

  • an internal dashboard;
  • a CRM or customer database;
  • a reporting tool;
  • a payment reconciliation tool;
  • a custom mobile or web app that needs tenant booking data.

The most important rule is:

Authenticate as the tenant whose data you want to access. The API response is scoped to that tenant's data.

For the general tenant admin experience, see Tenant admin panel reference. For the tenant data boundary, see Data isolation and permission boundaries.

Base URL

The REST namespace is:

/wp-json/booknetic/v1

So a full request usually looks like this:

https://your-domain.com/wp-json/booknetic/v1/appointments

In a SaaS setup, use the tenant URL that belongs to the tenant making the request.

Directory-mode tenant URLs

If your platform uses directory-style tenant URLs, the tenant slug appears after your main domain:

https://your-domain.com/tenant-slug/

Depending on how your SaaS routing is configured, the tenant-scoped REST URL may be built from that same tenant URL context, for example:

https://your-domain.com/tenant-slug/wp-json/booknetic/v1/appointments

Subdomain-mode tenant URLs

If your platform uses subdomain-style tenant URLs, the tenant slug appears before your main domain:

https://tenant-slug.your-domain.com/

The REST URL then uses that tenant subdomain:

https://tenant-slug.your-domain.com/wp-json/booknetic/v1/appointments

Subdomain mode requires DNS and hosting support. If you are not sure which URL style your platform uses, review Tenant URLs and routing before giving developers API URLs.

Authentication

Booknetic REST requests use WordPress REST authentication. For server-to-server integrations, the practical option is WordPress Application Password / Basic Auth.

The request sends an HTTP Basic Auth header using the tenant user's WordPress username and that user's application password:

Authorization: Basic base64(username:application-password)
Content-Type: application/json

With curl, you can write this as:

curl -u '[email protected]:xxxx xxxx xxxx xxxx xxxx xxxx' \
  'https://tenant-slug.your-domain.com/wp-json/booknetic/v1/appointments?skip=0&limit=20'

Or, if your developer wants to build the header manually:

curl -H 'Authorization: Basic <base64-tenant-username-and-application-password>' \
  'https://tenant-slug.your-domain.com/wp-json/booknetic/v1/appointments?skip=0&limit=20'

Security: Do not use the SaaS owner's WordPress administrator credentials for tenant integrations. Create credentials for the tenant user that owns the integration.

How per-tenant scoping works

In plain English, a tenant-scoped REST request works like this:

  1. The developer sends a request to the standard Booknetic REST namespace:
/wp-json/booknetic/v1/...
  1. The request authenticates as a WordPress user connected to a tenant.
  2. Booknetic resolves that tenant context.
  3. Booknetic reads or writes data inside that tenant's scope.
  4. The response contains that tenant's data only.

For example, if Aurora Wellness Studio authenticates with its own tenant user and calls:

GET /wp-json/booknetic/v1/customers

The response should contain Aurora Wellness Studio customers, not another tenant's customers.

Plan permissions and user capabilities still apply. If a tenant's plan does not include a module, an API call for that module may fail or return no usable data even if the credentials are valid.

What tenants can access through the REST API

The public REST namespace is for tenant Booknetic data and selected Booknetic module actions.

Common tenant-facing resources include:

Resource Example endpoint Notes
Appointments GET /appointments List appointment data for the current tenant scope.
Appointment detail GET /appointments/{id} Returns the appointment only if it belongs to the authenticated scope and permissions allow access.
Appointment status PUT /appointments/{id}/change-status Changes appointment status when the user has permission.
Customers GET /customers, POST /customers, PUT /customers/{id} Customer list/create/update for the current tenant scope.
Locations GET /locations, POST /locations, PUT /locations/{id} Location access depends on tenant plan and permissions.
Services GET /services, GET /services/categories, GET /services/extras Useful for select lists and service lookup.
Staff GET /staffs The route is staffs, not staff.
Payments GET /payments/{appointmentId}, PUT /payments/{appointmentId} Payment info is tied to an appointment ID.
Dashboard GET /dashboard/stats, GET /dashboard/upcoming-appointments, GET /dashboard/graph Dashboard-style data for the authenticated scope.
Notifications GET /notifications, POST /notifications/mark-as-read In-app notification endpoints where available.

Important note about appointment create/update

Some public API references describe appointment create and update routes. In the reviewed Booknetic source for this SaaS documentation batch, POST /appointments and PUT /appointments/{id} routes exist, but the reviewed controller returns an empty response for those actions.

Because of that, do not build a production integration that depends on appointment create/update through those routes unless Booknetic support or Engineering confirms the supported request body and runtime behavior for your version.

For appointment integrations, the safer documented actions are listing appointments, reading appointment details, deleting where permitted, and changing status where permitted.

What is not available through the public REST API

Booknetic SaaS also has owner-side screens for managing the platform. Those screens are not the same as the public tenant REST API.

The reviewed source did not find a public /wp-json/booknetic/v1/ REST endpoint for SaaS owner-side operations such as:

  • listing all tenants;
  • creating or editing tenants;
  • deleting tenants;
  • managing SaaS plans;
  • changing SaaS settings;
  • managing platform-level custom fields;
  • mutating the SaaS workflow editor;
  • managing tenant API keys centrally from the owner account;
  • using one owner key to query all tenants' operational data.

Those owner-side screens use internal admin routes inside the WordPress admin area. They are not documented as public REST API endpoints and should not be used as customer-facing integration endpoints.

Use the SaaS owner UI for owner-side operations such as Tenants, Plans, Payments, and SaaS Settings.

Example: get appointments for one tenant

This request lists appointments for the tenant user represented by the credentials:

curl -u '[email protected]:xxxx xxxx xxxx xxxx xxxx xxxx' \
  'https://tenant-slug.your-domain.com/wp-json/booknetic/v1/appointments?skip=0&limit=20'

Example response shape:

{
  "data": [],
  "meta": {
    "total": 0,
    "skip": 0,
    "limit": 20
  }
}

A tenant with appointments will receive appointment objects inside data.

Example: list customers

curl -u '[email protected]:xxxx xxxx xxxx xxxx xxxx xxxx' \
  'https://tenant-slug.your-domain.com/wp-json/booknetic/v1/customers?skip=0&limit=50'

Example response shape:

{
  "data": [],
  "meta": {
    "total": 0,
    "skip": 0,
    "limit": 50
  }
}

Example: create a customer

Use this only with credentials for the tenant that should own the customer record:

curl -u '[email protected]:xxxx xxxx xxxx xxxx xxxx xxxx' \
  -X POST 'https://tenant-slug.your-domain.com/wp-json/booknetic/v1/customers' \
  -H 'Content-Type: application/json' \
  -d '{
    "first_name": "QA",
    "last_name": "Customer",
    "email": "[email protected]",
    "phone": "+15555550199",
    "note": "Imported via API"
  }'

A successful customer create/update action returns a customer ID shape such as:

{
  "customer_id": 123
}

If validation fails, Booknetic may return a validation error with field-level details.

Example: change an appointment status

When the authenticated tenant user has permission to change appointment status:

curl -u '[email protected]:xxxx xxxx xxxx xxxx xxxx xxxx' \
  -X PUT 'https://tenant-slug.your-domain.com/wp-json/booknetic/v1/appointments/123/change-status' \
  -H 'Content-Type: application/json' \
  -d '{
    "status": "approved",
    "run_workflows": 1
  }'

Use the appointment ID that belongs to that tenant. Do not use this endpoint to test another tenant's appointment ID.

Example: update payment status for an appointment

If an external reconciliation tool needs to mark an appointment payment as paid:

curl -u '[email protected]:xxxx xxxx xxxx xxxx xxxx xxxx' \
  -X PUT 'https://tenant-slug.your-domain.com/wp-json/booknetic/v1/payments/123' \
  -H 'Content-Type: application/json' \
  -d '{
    "status": "paid",
    "paid_amount": 50
  }'

Payment status values are expected to be one of:

pending
paid
canceled
not_paid

The {appointmentId} in the URL is the appointment ID connected to the payment.

Response and error shapes

List endpoints commonly return:

{
  "data": [
    {}
  ],
  "meta": {
    "total": 42,
    "skip": 0,
    "limit": 20
  }
}

Single-item endpoints commonly return:

{
  "data": {}
}

Create/update endpoints may return an ID:

{
  "id": 123
}

or, for customers:

{
  "customer_id": 123
}

Validation errors can include a 422 response with field details:

{
  "code": "422",
  "message": "Validation failed",
  "data": {
    "status": 422,
    "errors": {
      "email": "Please enter a valid email"
    }
  }
}

Rate limits

The reviewed Booknetic SaaS source for this documentation batch did not identify a Booknetic-specific public REST rate-limit policy.

That does not mean integrations should send unlimited traffic. REST calls still use your WordPress site, hosting resources, database, security plugins, caching layers, and any firewall or CDN rules you have configured.

Recommended integration behavior:

  • use pagination with skip and limit instead of requesting everything repeatedly;
  • avoid tight polling loops;
  • cache results in your external system when possible;
  • retry failed requests with backoff instead of immediately repeating them;
  • schedule large sync jobs outside your busiest booking hours;
  • monitor hosting CPU, PHP workers, and database load.

If you run a high-volume integration, test it on staging or during a low-traffic window before using it in production.

REST API vs webhooks

REST API and webhooks solve different problems.

Need Use
Your external system wants to read or update Booknetic data on demand REST API
Booknetic or a payment provider needs to notify your site when an event happens Webhook
A tenant developer wants to pull appointment data into a dashboard REST API
Stripe needs to tell Booknetic SaaS that a subscription renewal was paid Stripe webhook

For Stripe SaaS billing events, see Setting up Stripe webhook for SaaS billing.

If you are building tenant booking integrations, do not confuse Stripe billing webhooks with Booknetic tenant REST API calls. Stripe webhooks are for SaaS subscription billing updates. The Booknetic REST API is for tenant booking data.

Common questions

Can my tenant give their developer API access?

Yes, the tenant can give a developer tenant-scoped API access by using credentials for that tenant user, typically through a WordPress Application Password / Basic Auth flow.

Only share credentials with trusted developers. Treat application passwords like secrets, and revoke them when the integration is no longer needed.

Can I use one owner API key to read every tenant's appointments and customers?

No public owner-side cross-tenant REST key was found in the reviewed source.

If you need data from multiple tenants through the public REST API, the safer model is to call each tenant's endpoint with that tenant's own credentials and keep the data separated in your external system.

Do not try to bypass the tenant boundary by using internal admin routes or direct database access unless you have a controlled, security-reviewed internal process. Direct database access can expose private tenant/customer data and should not be treated as a normal customer integration method.

Can the SaaS owner manage tenants and plans through REST?

Not through a public REST endpoint found in the reviewed source.

Use the SaaS owner admin panel for tenant, plan, SaaS settings, SaaS payments, and platform workflow management.

Is there a separate booknetic-saas/v1 REST namespace?

No separate public booknetic-saas/v1 namespace was found in the reviewed source for this documentation batch.

Use the standard Booknetic REST namespace:

/wp-json/booknetic/v1/

Is there an official SDK?

No official Booknetic SaaS REST SDK was identified in the source material used for this page.

Developers can call the REST API directly with standard HTTP clients such as curl, JavaScript fetch, PHP HTTP clients, Python requests, or Postman.

How does API versioning work?

The current namespace includes the version in the path:

/wp-json/booknetic/v1/

If Booknetic introduces a future REST version, it would normally appear as a new namespace such as v2. Keep integrations written against the documented namespace for your installed Booknetic version.

Why does an endpoint return permission errors for one tenant but not another?

Check these items first:

  1. Is the username/application password correct?
  2. Is the application password still active?
  3. Does that WordPress user belong to the tenant you expect?
  4. Does the tenant's plan include the module you are calling?
  5. Does the user have the needed capability for that action?
  6. Are you calling the correct tenant URL?

Plan capabilities apply to API calls. If the tenant cannot access a module in the tenant panel, the related API action may also fail.

Best practices for SaaS owners

Before giving API guidance to tenants:

  • confirm the tenant URL style your platform uses;
  • create separate credentials for each tenant integration;
  • never share the SaaS owner's WordPress administrator credentials;
  • enable only the modules and plan capabilities the tenant should use;
  • document which external system owns each application password;
  • revoke unused application passwords;
  • test a non-destructive GET request before sending create/update/delete requests;
  • keep tenant data separated in external systems too.

Quick troubleshooting checklist

Problem What to check
401 unauthorized Username, application password, revoked password, malformed Basic Auth header.
403 or permission denied Tenant plan capability, user capability, module access.
Empty data array Tenant may not have records yet, filters may be too narrow, or request is scoped to a different tenant.
Wrong tenant data expected Check the tenant URL and the authenticated user. Do not reuse one WordPress user across tenants unless intentionally configured.
404 endpoint not found Confirm the path is under /wp-json/booknetic/v1/ and check route spelling, for example staffs instead of staff.
Create/update does not behave as expected Confirm that endpoint is supported in your installed Booknetic version before relying on it.
Slow responses Reduce polling, paginate, and check WordPress hosting/server resources.

Related documentation