/pingVerify API key and connectivityResponses
| Status | Description | Body |
|---|---|---|
| 200 | OK | { ok: boolean, tenantId: string (uuid), timestamp: string (date-time) } |
| 401 | Error | Error |
| 403 | Error | Error |
| 429 | Too Many Requests | RateLimitError |
| 500 | Error | Error |
OneBookPlus Public API · v1.0.0
Every endpoint on this page is rendered from the same OpenAPI 3.1 document the API itself serves, so the reference can't drift from the implementation. The stable v1 surface covers contacts, invoices, quotes and bookings; breaking changes only ship under the v2 preview.
All v1 requests are made against a single base URL. Authentication uses a bearer API key issued from your dashboard (Settings → API keys); keys are scoped to one business account with read or read-write permissions. API access requires developer-access approval on your account.
API keys issued from /dashboard/settings/api-keys. Format: `obp_live_<random>` (prefix `obp_`). Send as `Authorization: Bearer obp_...`.
A v2 preview of the same surface is served under /api/v2 (spec at /api/v2/openapi.json) — identical today, and the only place breaking changes will land.
curl https://onebookplus.com.au/api/v1/ping \
-H "Authorization: Bearer obp_..."
# Base URL: https://onebookplus.com.au/api/v1
# Keys are issued at /dashboard/settings/api-keysList endpoints return { data, next_cursor }. Pass ?cursor= to fetch the next page; next_cursor is null when exhausted. limit accepts 1–200 (default 50), and updated_since filters by ISO 8601 timestamp for incremental syncs.
Failures return a JSON body of { error } with an optional field naming the failing validator on 400s. Statuses used: 400, 401, 403, 404, 409, 415, 429 and 500 (see the Error schema).
Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers. The default limit is 60 requests per minute per API key, with tighter per-endpoint caps on write operations; 429 responses include Retry-After.
16 operations across 5 resource groups.
Ping & diagnostic endpoints.
/pingVerify API key and connectivity| Status | Description | Body |
|---|---|---|
| 200 | OK | { ok: boolean, tenantId: string (uuid), timestamp: string (date-time) } |
| 401 | Error | Error |
| 403 | Error | Error |
| 429 | Too Many Requests | RateLimitError |
| 500 | Error | Error |
/contactsList contacts| Name | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integer | No | Max rows to return (1-200). Min: 1. Max: 200. Default: 50. |
| cursor | query | string (uuid) | No | Opaque UUID cursor from a previous response's next_cursor. |
| updated_since | query | string (date-time) | No | Only return rows with updated_at >= this ISO 8601 timestamp. |
/contactsCreate a contact| Field | Type | Required | Description |
|---|---|---|---|
| string (email) | Yes | — | |
| first_name | string | null | No | — |
| last_name | string | null | No | — |
| phone | string | null | No | — |
| company_name | string | null | No | — |
| city | string | null | No | — |
| state | string | null | No | — |
| postcode | string | null | No | — |
/contacts/{id}Get a contact| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | string (uuid) | Yes | — |
/contacts/{id}Update a contact| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | string (uuid) | Yes | — |
At least one field must be supplied.
| Field | Type | Required | Description |
|---|---|---|---|
| string | null (email) | No | — | |
| first_name | string | null | No | — |
| last_name | string | null | No | — |
| phone | string | null | No | — |
| company_name | string | null | No | — |
| city | string | null | No | — |
| state | string | null | No | — |
| postcode | string | null | No | — |
/contacts/{id}Soft-delete a contact| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | string (uuid) | Yes | — |
/invoicesList invoices| Name | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integer | No | Max rows to return (1-200). Min: 1. Max: 200. Default: 50. |
| cursor | query | string (uuid) | No | Opaque UUID cursor from a previous response's next_cursor. |
| updated_since | query | string (date-time) | No | Only return rows with updated_at >= this ISO 8601 timestamp. |
/invoices/{id}Get an invoice| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | string (uuid) | Yes | — |
/bookingsList bookings| Name | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integer | No | Max rows to return (1-200). Min: 1. Max: 200. Default: 50. |
| cursor | query | string (uuid) | No | Opaque UUID cursor from a previous response's next_cursor. |
| updated_since | query | string (date-time) | No | Only return rows with updated_at >= this ISO 8601 timestamp. |
/bookingsCreate a booking| Field | Type | Required | Description |
|---|---|---|---|
| contact_id | string (uuid) | Yes | — |
| service_name | string | Yes | — |
| start_time | string (date-time) | Yes | — |
| end_time | string | null (date-time) | No | Defaults to start_time + 60 minutes if omitted. |
| notes | string | null | No | — |
/bookings/{id}Get a booking| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | string (uuid) | Yes | — |
/bookings/{id}Update a booking| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | string (uuid) | Yes | — |
At least one field must be supplied.
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | No | One of: cancelled, confirmed, completed, no_show. |
| notes | string | null | No | — |
| start_time | string (date-time) | No | — |
| end_time | string (date-time) | No | — |
/quotesList quotes| Name | In | Type | Required | Description |
|---|---|---|---|---|
| limit | query | integer | No | Max rows to return (1-200). Min: 1. Max: 200. Default: 50. |
| cursor | query | string (uuid) | No | Opaque UUID cursor from a previous response's next_cursor. |
| updated_since | query | string (date-time) | No | Only return rows with updated_at >= this ISO 8601 timestamp. |
/quotesCreate a quote| Field | Type | Required | Description |
|---|---|---|---|
| contact_id | string (uuid) | Yes | — |
| total | number | Yes | Min: 0. |
| currency | string | null | No | 3-letter ISO 4217 code. Defaults to AUD. Pattern: ^[A-Z]{3}$ |
| valid_until | string | null (date-time) | No | Defaults to 30 days from today. |
| line_items | array of object | No | Accepted for forward compatibility but currently ignored server-side — the canonical line-item table is not reconciled from API writes yet. |
/quotes/{id}Get a quote| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | string (uuid) | Yes | — |
/quotes/{id}Update a quote| Name | In | Type | Required | Description |
|---|---|---|---|---|
| id | path | string (uuid) | Yes | — |
At least one field must be supplied.
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | No | One of: draft, sent, viewed, accepted, declined, expired, converted. |
| total | number | No | Min: 0. |
| valid_until | string (date-time) | No | — |
The 12 object models referenced by request and response bodies above.
| Field | Type | Required | Description |
|---|---|---|---|
| error | string | Yes | — |
| field | string | No | Field name when a validator fails (400 responses). |
| Field | Type | Required | Description |
|---|---|---|---|
| error | string | Yes | — |
| retry_after_ms | integer | No | Min: 0. |
| Field | Type | Required | Description |
|---|---|---|---|
| id | string (uuid) | Yes | — |
| string | null (email) | No | — | |
| first_name | string | null | No | — |
| last_name | string | null | No | — |
| phone | string | null | No | — |
| company_name | string | null | No | — |
| city | string | null | No | — |
| state | string | null | No | — |
| postcode | string | null | No | — |
| created_at | string (date-time) | Yes | — |
| updated_at | string (date-time) | Yes | — |
| Field | Type | Required | Description |
|---|---|---|---|
| string (email) | Yes | — | |
| first_name | string | null | No | — |
| last_name | string | null | No | — |
| phone | string | null | No | — |
| company_name | string | null | No | — |
| city | string | null | No | — |
| state | string | null | No | — |
| postcode | string | null | No | — |
At least one field must be supplied.
| Field | Type | Required | Description |
|---|---|---|---|
| string | null (email) | No | — | |
| first_name | string | null | No | — |
| last_name | string | null | No | — |
| phone | string | null | No | — |
| company_name | string | null | No | — |
| city | string | null | No | — |
| state | string | null | No | — |
| postcode | string | null | No | — |
| Field | Type | Required | Description |
|---|---|---|---|
| id | string (uuid) | Yes | — |
| invoice_number | string | Yes | — |
| contact_id | string | null (uuid) | No | — |
| status | string | Yes | — |
| issue_date | string | null (date) | No | — |
| due_date | string | null (date) | No | — |
| total | number | Yes | — |
| currency | string | Yes | Exactly 3 characters. |
| paid_at | string | null (date-time) | No | — |
| created_at | string (date-time) | Yes | — |
| updated_at | string (date-time) | Yes | — |
| Field | Type | Required | Description |
|---|---|---|---|
| id | string (uuid) | Yes | — |
| contact_id | string | null (uuid) | No | — |
| service_name | string | null | No | — |
| start_time | string (date-time) | Yes | — |
| end_time | string (date-time) | Yes | — |
| status | string | Yes | One of: cancelled, confirmed, completed, no_show. |
| notes | string | null | No | — |
| created_at | string (date-time) | Yes | — |
| updated_at | string (date-time) | Yes | — |
| Field | Type | Required | Description |
|---|---|---|---|
| contact_id | string (uuid) | Yes | — |
| service_name | string | Yes | — |
| start_time | string (date-time) | Yes | — |
| end_time | string | null (date-time) | No | Defaults to start_time + 60 minutes if omitted. |
| notes | string | null | No | — |
At least one field must be supplied.
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | No | One of: cancelled, confirmed, completed, no_show. |
| notes | string | null | No | — |
| start_time | string (date-time) | No | — |
| end_time | string (date-time) | No | — |
| Field | Type | Required | Description |
|---|---|---|---|
| id | string (uuid) | Yes | — |
| quote_number | string | Yes | — |
| contact_id | string | null (uuid) | No | — |
| status | string | Yes | One of: draft, sent, viewed, accepted, declined, expired, converted. |
| issue_date | string | null (date) | No | — |
| valid_until | string | null (date) | No | — |
| total | number | Yes | — |
| currency | string | Yes | Exactly 3 characters. |
| created_at | string (date-time) | Yes | — |
| updated_at | string (date-time) | Yes | — |
| Field | Type | Required | Description |
|---|---|---|---|
| contact_id | string (uuid) | Yes | — |
| total | number | Yes | Min: 0. |
| currency | string | null | No | 3-letter ISO 4217 code. Defaults to AUD. Pattern: ^[A-Z]{3}$ |
| valid_until | string | null (date-time) | No | Defaults to 30 days from today. |
| line_items | array of object | No | Accepted for forward compatibility but currently ignored server-side — the canonical line-item table is not reconciled from API writes yet. |
At least one field must be supplied.
| Field | Type | Required | Description |
|---|---|---|---|
| status | string | No | One of: draft, sent, viewed, accepted, declined, expired, converted. |
| total | number | No | Min: 0. |
| valid_until | string (date-time) | No | — |
API keys are created in the dashboard under Settings → API keys and require developer-access approval. Webhooks, key scopes and delivery logs are covered on the developer overview.