API reference

Every endpoint of the Webkio API, version 1, and every webhook it sends. The same description is at https://api.webkio.com/v1/openapi.json for your own tools. Prefer prose? Read the guide. Ready-made code is in Examples, and how deliveries work in Webhooks.

Sign in to try requests against your own account, or use Authorize in the explorer with an API key.
Use it in Postman or Insomnia. Import the description from its URL, https://api.webkio.com/v1/openapi.json: in Postman, Import and paste the link; in Insomnia, Import and From URL. Every endpoint arrives ready to send; set the collection's bearer token to your API key.

Conventions

Read a Webkio account's sites, orders and contacts; add contacts, email subscribers and blog post drafts; and subscribe URLs to its events.

Blank fields: in a request body, a field you leave out or send empty changes nothing.

Authentication: an API key (Settings > API & webhooks, or the developer console) as Authorization: Bearer wk_....

Times: every timestamp is ISO 8601 in UTC. The account and each site carry a timezone (IANA) for display; booking and reservation dates and times are the site's local ones.

Lists are cursor-paginated: limit (1-100, default 25) and cursor (the previous page's meta.next_cursor) until meta.has_more is false.

Errors are {"success": false, "error": {"code": "...", "message": "..."}}. Branch on the code:

  • missing_api_key: No key was sent.
  • invalid_api_key: The key is unknown or revoked.
  • console_token_expired: The developer site's temporary token has expired; reload the explorer.
  • account_unavailable: The account is deleted, suspended or banned.
  • plan_required: The account's plan does not include integrations, or the feature the endpoint uses (the CRM, the blog).
  • plan_limit_reached: A limit of the plan is reached: new subscribers this month, or blog posts on a site.
  • read_only_demo: The demo account cannot change anything.
  • rate_limited: Over 200 requests a minute. Retry-After says when to come back.
  • not_found: No such endpoint.
  • resource_not_found: No such record on this account.
  • unknown_event: The event type is not one GET /v1/event-types lists.
  • invalid_target_url: The webhook URL is not https, not public, or too long.
  • invalid_project: project_id is not one of this account's sites.
  • invalid_list: list_id is not one of the site's email lists.
  • email_rejected: Webkio does not send email to that address: it bounced or complained before, or it is a throwaway address.
  • webhook_limit_reached: The account already has 50 webhooks.
  • invalid_cursor: The cursor was not one this API gave out.
  • validation_failed: The request was understood but not accepted; the message says why.
  • server_error: Something failed on our side.

200 requests a minute per account. Guide: https://webkio.com/docs/api-and-webhooks

Account

Who the key belongs to, and their sites.

GET /v1/me #

The account the key belongs to

Integrations call this to test a connection.

  • 200 The account.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/projects #

The account's sites

ParameterInTypeDescription
limitqueryinteger
cursorquerystringThe previous page's meta.next_cursor.
  • 200 Sites, oldest first.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/openapi.json #

This description

No key needed.

  • 200 The OpenAPI document.

Webhooks

Event types, sample data, and subscriptions.

GET /v1/event-types #

The events a webhook can subscribe to

The whole list; it is short and not paginated.

  • 200 Every event type.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/event-types/{type}/samples #

Newest records for an event type

Your own newest records, in exactly the shape a webhook delivers them.

ParameterInTypeDescription
typerequiredpathone of order.created, order.paid, booking.created, rental.reserved, subscriber.created, property_enquiry.created, review.submitted
project_idquerystringOnly this site.
limitqueryinteger
  • 200 Newest first.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/webhooks #

The account's webhooks

ParameterInTypeDescription
limitqueryinteger
cursorquerystringThe previous page's meta.next_cursor.
  • 200 Newest first.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
POST /v1/webhooks #

Subscribe a URL to an event

The URL must be https and public. Subscribing the same URL to the same event again returns the existing webhook. The signing secret is returned only here.

Body fieldTypeDescription
eventrequiredone of order.created, order.paid, booking.created, rental.reserved, subscriber.created, property_enquiry.created, review.submitted
target_urlrequiredstring (uri)
project_idstringOnly this site. Leave out for every site.
  • 201 The webhook, with its secret.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/webhooks/{id} #

One webhook

ParameterInTypeDescription
idrequiredpathstring
  • 200 The webhook (without its secret).
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
DELETE /v1/webhooks/{id} #

Remove a webhook

ParameterInTypeDescription
idrequiredpathstring
  • 200 Removed.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.

Contacts

The CRM's people, matched on email within a site. Plans with the CRM.

GET /v1/contacts #

Find contacts

Newest first. Pass email to find one person.

ParameterInTypeDescription
project_idquerystringOnly this site.
emailquerystring (email)Only the contact with this email. Not case-sensitive.
limitqueryinteger
cursorquerystringThe previous page's meta.next_cursor.
  • 200 Contacts, newest first.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
POST /v1/contacts #

Create or update a contact

Matched on email within the site: an email the site does not know creates a contact (201), a known one updates it (200). name, phone and notes replace what is stored; tags are added to the contact's own.

Body fieldTypeDescription
project_idrequiredstringThe site, from GET /v1/projects.
emailrequiredstring (email)What the contact is matched on.
namestring
phonestring
notesstringReplaces the contact's notes.
tagslist of string or stringA list, or one text with commas between the tags.
  • 200 The updated contact.
  • 201 The new contact.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/contacts/{id} #

One contact

ParameterInTypeDescription
idrequiredpathstring
  • 200 The contact.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.

Email

Email subscribers and lists.

POST /v1/subscribers #

Add an email subscriber

Adds the address to the site's subscribers, active at once, and to list_id when sent. Only send people who agreed to hear from the site. Someone already subscribed is not added twice (200): they join the list, gain the tags and keep their status, so an address that unsubscribed stays unsubscribed. A new subscriber (201) counts toward the plan's monthly limit and starts the site's welcome automation.

Body fieldTypeDescription
project_idrequiredstringThe site, from GET /v1/projects.
emailrequiredstring (email)
namestring
tagslist of string or stringA list, or one text with commas between the tags.
list_idstringAlso add them to this list, from GET /v1/email-lists.
  • 200 Already subscribed.
  • 201 The new subscriber.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/email-lists #

Email lists

ParameterInTypeDescription
project_idquerystringOnly this site.
limitqueryinteger
cursorquerystringThe previous page's meta.next_cursor.
  • 200 Lists, oldest first.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.

Blog

Blog post drafts, to publish from the dashboard.

POST /v1/blog-posts #

Create a blog post draft

Always a draft: it is published from the dashboard, where it is checked before it goes live. The slug is made from the title unless you send one, and kept unique on the site. content is HTML; scripts and unsafe markup are removed.

Body fieldTypeDescription
project_idrequiredstringThe site, from GET /v1/projects.
titlerequiredstring
contentstringHTML. Scripts and unsafe markup are removed.
excerptstring
slugstringMade from the title when left out.
tagslist of string or stringA list, or one text with commas between the tags.
meta_titlestring
meta_descriptionstring
featured_imagestring (uri)
  • 201 The draft.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.

Orders

Orders, read only.

GET /v1/orders #

Find orders

Newest first. Each order reads as the order webhooks send it.

ParameterInTypeDescription
project_idquerystringOnly this site.
numberquerystringThe order number, exactly.
emailquerystring (email)The customer's email. Not case-sensitive.
statusqueryone of pending, paid, processing, shipped, delivered, refunded, cancelled
limitqueryinteger
cursorquerystringThe previous page's meta.next_cursor.
  • 200 Orders, newest first.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/orders/{id} #

One order

ParameterInTypeDescription
idrequiredpathstring
  • 200 The order.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
PATCH /v1/orders/{id} #

Move an order's status on

Moves the order and does what goes with it: tracking details are saved, shipping is timestamped, a cancellation puts the stock back, and the customer is emailed - the same as a change made in the dashboard. An order is marked paid by the payment flow and refunded by the refund action, so neither is settable here.

ParameterInTypeDescription
idrequiredpathstring
Body fieldTypeDescription
statusrequiredone of processing, shipped, delivered, cancelled
tracking_numberstringSaved against the order; usually sent with shipped.
tracking_urlstring (uri)
  • 200 The updated order.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.

Products

GET /v1/products #

Find products

Newest first. Includes products that have been switched off, so a catalogue sync can withdraw them too - filter with active if you only want the ones on sale. Stock lives on the variant for anything sold by size or colour, so read variants[].stock when variants is not empty.

ParameterInTypeDescription
project_idquerystringOnly this site.
skuquerystringThe SKU, exactly. How you find the product behind an order line.
typequeryone of physical, digital, service, bundle
category_idquerystring
activequerybooleanOmit for both.
searchquerystringMatches name or SKU.
limitqueryinteger
cursorquerystringThe previous page's meta.next_cursor.
  • 200 Products, newest first.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/products/{id} #

One product

ParameterInTypeDescription
idrequiredpathstring
  • 200 The product.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
PUT /v1/products/{id}/stock #

Set what is in stock

States the real count rather than adjusting by a difference, because every caller retries: a repeated -3 destroys the figure, a repeated = 42 is simply true again. Pass variant_id for anything sold by size or colour. The owner is warned when a product drops INTO its low-stock window, and not again while it stays there, so a nightly sync does not email them nightly. Refused on a product that does not track stock.

ParameterInTypeDescription
idrequiredpathstring
Body fieldTypeDescription
quantityrequiredintegerWhole number, zero or more.
variant_idstringRequired for a product with variants, since stock lives there.
  • 200 The updated product.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.

Bookings

GET /v1/bookings #

Find bookings

Newest first. Each booking reads as the booking.created webhook sends it. from/to filter the APPOINTMENT date, not when it was made.

ParameterInTypeDescription
project_idquerystringOnly this site.
emailquerystring (email)The customer's email. Not case-sensitive.
statusqueryone of pending, confirmed, cancelled, completed, no-show
fromquerystring (date)Appointments on or after this date (YYYY-MM-DD).
toquerystring (date)Appointments on or before this date (YYYY-MM-DD).
limitqueryinteger
cursorquerystringThe previous page's meta.next_cursor.
  • 200 Bookings, newest first.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/bookings/{id} #

One booking

ParameterInTypeDescription
idrequiredpathstring
  • 200 The booking.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
PATCH /v1/bookings/{id} #

Change a booking's status

Moves the booking and does everything that goes with it: a cancellation refunds a card payment where the policy allows, and the customer is emailed - the same as a change made in the dashboard.

ParameterInTypeDescription
idrequiredpathstring
Body fieldTypeDescription
statusrequiredone of pending, confirmed, cancelled, completed, no-show
  • 200 The updated booking.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.

Reservations

GET /v1/reservations #

Find rental reservations

Newest first. Each reservation reads as the rental.reserved webhook sends it. from/to filter the PICKUP date, not when the reservation was taken.

ParameterInTypeDescription
project_idquerystringOnly this site.
referencequerystringThe reservation reference, exactly.
emailquerystring (email)The customer's email. Not case-sensitive.
statusqueryone of pending, confirmed, cancelled, completed
fromquerystring (date)Pick-ups on or after this date (YYYY-MM-DD).
toquerystring (date)Pick-ups on or before this date (YYYY-MM-DD).
limitqueryinteger
cursorquerystringThe previous page's meta.next_cursor.
  • 200 Reservations, newest first.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
GET /v1/reservations/{id} #

One reservation

ParameterInTypeDescription
idrequiredpathstring
  • 200 The reservation.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.
PATCH /v1/reservations/{id} #

Change a reservation's status

Moves the reservation and does everything that goes with it: a cancellation refunds a card payment where the policy allows, releases the deposit hold, and emails the customer - the same as a change made in the dashboard.

ParameterInTypeDescription
idrequiredpathstring
Body fieldTypeDescription
statusrequiredone of pending, confirmed, cancelled, completed
  • 200 The updated reservation.
  • 401 missing_api_key, invalid_api_key or console_token_expired.
  • 403 account_unavailable, plan_required, plan_limit_reached or read_only_demo.
  • 404 resource_not_found, unknown_event or not_found.
  • 422 unknown_event, invalid_target_url, invalid_project, invalid_list, email_rejected, webhook_limit_reached, invalid_cursor or validation_failed.
  • 429 rate_limited: over 200 requests a minute. Retry-After says when to come back.

Webhook events

What Webkio sends to a URL you subscribe with POST /v1/webhooks. The payload of each, its headers and the signature check are on Webhooks.

EventSent when
order.createdAn order is placed in your shop. Card payments may still be pending. Sent to every URL subscribed to order.created, signed with that subscription's secret.
order.paidPayment for an order is confirmed. Sent to every URL subscribed to order.paid, signed with that subscription's secret.
booking.createdA customer books an appointment. Sent to every URL subscribed to booking.created, signed with that subscription's secret.
rental.reservedA customer reserves a rental item. Sent to every URL subscribed to rental.reserved, signed with that subscription's secret.
subscriber.createdSomeone joins your email list. Sent to every URL subscribed to subscriber.created, signed with that subscription's secret.
property_enquiry.createdA visitor enquires about a property listing. Sent to every URL subscribed to property_enquiry.created, signed with that subscription's secret.
review.submittedA customer reviews a product. Sent to every URL subscribed to review.submitted, signed with that subscription's secret.