API and webhooks

OpenAPI

Browse the machine-readable contract at /api/v1/openapi. Use it to generate clients or inspect paths for catalog, availability, estimate, bookings, deposit-intents, portfolio, clients, and webhook registration.

Authentication

Open Settings → Website & embed → Developers for API keys. Use sk_ keys only on servers. Use pk_ keys in browsers with origin allowlists. Connect / Go live issues embed materials so shop owners are not stuffing secrets into CMS fields.

Website & embed · Developers
Publishablepk_live_••••a91f
Secretsk_live_•••• · server only
Allowed originsRotate key
Website & embed → Developers — publishable/secret keys and allowed origins.

Webhooks

Add endpoints under Settings → Website & embed → Webhooks (or POST /api/v1/webhooks). Verify X-Inkdesk-Signature (HMAC) before trusting payloads—SDK helpers include verifyWebhook where available.

Website & embed · Webhooks
URLhooks.zapier.com/…
Eventsbooking.created · waitlist.filled
HMAC X-Inkdesk-Signature
Website & embed → Webhooks — URL, events, HMAC secret for Zapier/Make.

Zapier and Make integrate through these webhooks (see integrations/zapier and integrations/make scaffolds). Use them for Slack, sheets, and side effects when bookings or deposits change.

When to use API vs widget

Widget/hosted: default for shops. API: agencies building custom UI while Inkdesk remains CRM, deposits, and floor ops. Subscription remains $50/shop/month; Stripe fees still apply on charges.

Install surfaces
  • 1
    Plugin / blockWordPress · Download plugin → Generate connect code
  • 2
    App or snippetShopify/Wix Add to… · or Create snippet for Code/Embed
  • 3
    Hosted book pageNo website · Create hosted link + QR → /{salon}/book
Three install surfaces — WordPress plugin, app/snippet, or hosted book link + QR.

Endpoint reference

Generated from the OpenAPI 3 contract (Inkdesk Public API v1.0.0). Base path: /api/v1. Machine-readable copy: /api/v1/openapi.

Salon-scoped booking API and Telegram bot messaging API. Authenticate with Bearer pk_… / sk_…. Per-bot keys are secret keys scoped to read:messaging + write:messaging only. Owners bind sites via connect codes (never paste raw keys).

Availability

  • GET/api/v1/availability

    Bookable slots

    • artist (query, required) · string
    • from (query, required) · string
    • to (query, required) · string

    Response: Slots

Bookings

  • POST/api/v1/bookings

    Create booking or request

    Required body (application/json)

    Response: Created

  • GET/api/v1/bookings/{id}

    Get booking

    • id (path, required) · string

    Response: Booking

  • PATCH/api/v1/bookings/{id}

    Cancel or reschedule

    • id (path, required) · string

    Optional body (application/json)

    Response: Updated

  • POST/api/v1/references/presign

    Presign reference image upload

    Optional body (application/json)

    Response: Upload URL

Catalog

  • GET/api/v1/catalog

    List artists and styles

    Response: Catalog

Clients

  • POST/api/v1/clients

    Upsert client by phone (secret key)

    Required body (application/json)

    Response: Client

Connections

  • POST/api/v1/connect/exchange

    Exchange a one-time connect code for a publishable key

    Used by the WordPress plugin / snippet binder. No prior auth required.

    Required body (application/json)

    Response: Publishable key (shown once to the plugin)

  • POST/api/v1/connections/{id}/seen

    Verification beacon from widget/embed

    • id (path, required) · string

    Response: Marked verified / last_seen updated

Deposits

  • POST/api/v1/deposit-intents

    Start deposit PaymentIntent

    Optional body (application/json)

    Response: Client secret

Estimate

  • POST/api/v1/estimate

    Price calculator estimate

    Required body (application/json)

    Response: Estimate range + deposit preview

  • GET/api/v1/pricing/calculator-config

    Calculator config (types, sizes, artists, resolved hours)

    • artistId (query) · string

    Response: Widget calculator options

Messaging

  • GET/api/v1/messaging/booking-link

    Public /{salon}/book URL for Mini App / deep-link

    Response: url + slug

  • POST/api/v1/messaging/inbound

    Push an inbound Telegram DM (bot secret key)

    Idempotent by externalEventId. Tenant is bound from the per-bot key; externalAccountId is a cross-check only. Poll+ack outbound — Inkdesk does not push to the bot.

    Required body (application/json)

    Response: received (including duplicate and anomaly)

  • GET/api/v1/messaging/outbound

    Poll queued staff replies for this bot

    • limit (query) · integer

    Response: Queued outbound messages

  • POST/api/v1/messaging/outbound/{id}/ack

    Acknowledge that the bot sent a queued reply

    • id (path, required) · string

    Optional body (application/json)

    Response: Marked sent

  • POST/api/v1/messaging/outbound/{id}/delivery

    Mark outbound delivery status

    • id (path, required) · string

    Required body (application/json)

    Response: Updated

  • GET/api/v1/messaging/salon

    Minimal salon context (name, hours)

    Response: Salon context

Portfolio

  • GET/api/v1/portfolio

    Portfolio gallery

    Response: Items

Waitlist

  • GET/api/v1/waitlist

    List waitlist entries (secret key)

    Response: Entries

  • POST/api/v1/waitlist

    Join waitlist, or ?action=fill to book from waitlist (secret)

    Required body (application/json)

    Response: Created or filled

Webhooks

  • DELETE/api/v1/webhooks

    Deactivate webhook by id query param

    • id (query, required) · string

    Response: Deactivated

  • GET/api/v1/webhooks

    List webhook subscriptions (secret key)

    Response: Webhooks

  • POST/api/v1/webhooks

    Create webhook subscription (Zapier/Make REST Hooks)

    Required body (application/json)

    Response: Created — raw secret returned once