API Reference

REST + GraphQL · 120 endpoints · 12 SDKs · webhooks for everything.

Base URL

Production:  https://api.ideadunes.com/v2
Sandbox:     https://sandbox-api.ideadunes.com/v2
GraphQL:     https://api.ideadunes.com/v2/graphql
Webhooks:    https://api.ideadunes.com/v2/webhooks

Authentication

All API requests require an Authorization header with a Bearer token. Tokens come in two types:

  • sk_live_... — server-side secret keys (full access)
  • pk_live_... — public keys (limited, for client-side embed widgets)
  • test_ prefix — sandbox keys (e.g. sk_test_...)
Authorization: Bearer sk_live_4eC39HqLyjWDarjtT1zdp7dc
X-Tenant-Id: tnt_ideadunes
X-Idempotency-Key: idem_01HXYZ123ABC

Common request format

// Create a booking
POST /v2/bookings
Authorization: Bearer sk_live_...
X-Tenant-Id: tnt_clinic
X-Idempotency-Key: idem_unique_per_request
Content-Type: application/json

{
  "customer_id": "cust_priya_01",
  "service_id": "svc_consult_30",
  "resource_id": "res_dr_niket",
  "start_at": "2026-04-20T05:00:00Z",
  "channel": "video_zoom",
  "notes": "Follow-up · cardiology",
  "send_confirmation": true
}

Common response format

// Success response
HTTP/2 201 Created
Content-Type: application/json
X-Request-Id: req_01HXYZ
X-Rate-Limit-Remaining: 4998

{
  "id": "bk_01HXYZ234",
  "tenant_id": "tnt_clinic",
  "customer_id": "cust_priya_01",
  "service_id": "svc_consult_30",
  "resource_id": "res_dr_niket",
  "status": "confirmed",
  "start_at": "2026-04-20T05:00:00Z",
  "end_at": "2026-04-20T05:30:00Z",
  "created_at": "2026-04-15T09:42:11Z",
  "links": {
    "self": "/v2/bookings/bk_01HXYZ234",
    "customer": "/v2/customers/cust_priya_01",
    "ics": "/v2/bookings/bk_01HXYZ234/ics"
  }
}

Error format

HTTP/2 422 Unprocessable Entity

{
  "error": {
    "code": "resource_unavailable",
    "message": "Resource res_dr_niket is not available at the requested time",
    "doc_url": "https://docs.ideadunes.com/errors/resource_unavailable",
    "request_id": "req_01HXYZ",
    "details": {
      "conflicts": [
        { "type": "existing_booking", "id": "bk_01HXYW999" },
        { "type": "outside_working_hours" }
      ],
      "suggestions": [
        { "start_at": "2026-04-20T05:30:00Z", "available": true },
        { "start_at": "2026-04-20T06:00:00Z", "available": true }
      ]
    }
  }
}

Rate limits

PlanPer secondPer minutePer day
Free / Solo520010,000
Starter1050050,000
Business502,000200,000
Scale20010,0001,000,000
EnterpriseNegotiatedNegotiatedNegotiated

When rate-limited, you'll receive HTTP 429 with a Retry-After header. We use leaky-bucket; bursts up to 2× steady rate are allowed.

Webhook events (48 types)

Booking

  • booking.created
  • booking.confirmed
  • booking.cancelled
  • booking.rescheduled
  • booking.no_show
  • booking.completed
  • booking.payment_received

Customer

  • customer.created
  • customer.updated
  • customer.merged
  • customer.deleted
  • customer.consent_changed

Resource

  • resource.created
  • resource.availability_changed
  • resource.taken_offline
  • resource.skill_added

Schedule

  • schedule.optimization_started
  • schedule.optimization_finished
  • schedule.committed
  • schedule.violation_detected

Payment

  • payment.succeeded
  • payment.failed
  • payment.refunded
  • payment.disputed

Compliance

  • data_request.received
  • consent.changed
  • audit.access_review_due
  • breach.detected

Pagination

GET /v2/bookings?cursor=eyJpZCI6ImJrXzAxIn0&limit=50

{
  "data": [...],
  "has_more": true,
  "next_cursor": "eyJpZCI6ImJrXzUwIn0",
  "prev_cursor": null
}

All list endpoints use cursor-based pagination. Default limit 25, maximum 100.

SDKs

Node.js / TypeScript
@ideadunes/sdk
v2.3 · stable
Python
ideadunes
v2.1 · stable
PHP
ideadunes/sdk
v1.8 · stable
Go
github.com/ideadunes/go
v1.4 · stable
Ruby
ideadunes
v1.6 · stable
Java / Kotlin
com.ideadunes:sdk
v1.3 · stable

Want to dive deeper?

View all 120 endpoints with filters, examples in 6 languages, and try them in our interactive sandbox.

Explore endpoints Read full docs