Booking
Sell scheduled access — 1-on-1 sessions, live classes, and cohorts. Buyers checkout via the public storefront; you manage the catalogue, availability, and discount codes via this API.
Read-only on bookings. Bookings are created by customers via the public checkout flow (Stripe Checkout-backed). The Partner API only lets you list / read incoming bookings — not create them on a customer's behalf, because that would bypass the payment + consent capture step.
Products
A product is your bookable offering. type picks the shape:
ONE_TO_ONE— single buyer fills a single slot (consults, lessons).LIVE_CLASS— many buyers join one scheduled session (workshops).COHORT— a multi-session program with drip content (courses).
# Create
curl -s -X POST https://api.dcast.pro/api/v1/booking/products \
-H "Authorization: Bearer pk_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"type": "ONE_TO_ONE",
"title": "30-min strategy call",
"description": "Pricing strategy review for your video catalogue.",
"priceCents": 12500,
"currency": "USD",
"durationMin": 30,
"bufferMin": 15,
"capacity": 1,
"recordable": true,
"refundPolicyDays": 7
}'
# → 201 { data: { id, slug (auto from title, unique per creator), isPublished: false, ... } }
# Publish (storefront-visible)
POST https://api.dcast.pro/api/v1/booking/products/{productId}/publish
# Unpublish
POST https://api.dcast.pro/api/v1/booking/products/{productId}/unpublish
# Update — partial
PATCH https://api.dcast.pro/api/v1/booking/products/{productId}
{ "priceCents": 9900, "description": "Updated copy" }
# Delete — only if no bookings exist (409 PRODUCT_HAS_BOOKINGS otherwise; unpublish instead)
DELETE https://api.dcast.pro/api/v1/booking/products/{productId}| Method | Path | Notes |
|---|---|---|
| GET | https://api.dcast.pro/api/v1/booking/products | ?type=, ?published=true |
| POST | https://api.dcast.pro/api/v1/booking/products | Idempotent; slug auto-generated |
| GET | https://api.dcast.pro/api/v1/booking/products/{id} | Owner-scoped |
| PATCH | https://api.dcast.pro/api/v1/booking/products/{id} | Partial update |
| POST | https://api.dcast.pro/api/v1/booking/products/{id}/publish | Sets publishedAt |
| POST | https://api.dcast.pro/api/v1/booking/products/{id}/unpublish | Storefront hides; existing bookings unaffected |
| DELETE | https://api.dcast.pro/api/v1/booking/products/{id} | 409 if bookings exist |
Availability
One Availability rule-set per creator drives slot generation. The storefront combines weeklyJson (weekly recurring windows), blackoutsJson (specific date ranges to exclude), timezone, minNoticeMin (minimum lead time before booking), and maxAdvanceDays (how far ahead bookers can schedule) into the slot calendar.
PUT https://api.dcast.pro/api/v1/booking/availability
{
"weeklyJson": {
"mon": [{ "start": "09:00", "end": "12:00" }, { "start": "14:00", "end": "17:00" }],
"tue": [{ "start": "09:00", "end": "17:00" }],
"wed": [],
"thu": [{ "start": "10:00", "end": "16:00" }],
"fri": [{ "start": "09:00", "end": "13:00" }]
},
"blackoutsJson": [
{ "startsAt": "2026-07-01T00:00Z", "endsAt": "2026-07-15T00:00Z", "reason": "vacation" }
],
"timezone": "America/Los_Angeles",
"minNoticeMin": 120,
"maxAdvanceDays": 60
}
# → 200 { data: { ...upserted Availability... } }Bookings (read-only)
# List incoming bookings on your products
curl -s -H "Authorization: Bearer pk_YOUR_KEY_HERE" \
"https://api.dcast.pro/api/v1/booking/bookings?status=CONFIRMED&page=1&limit=25"
# Read one (with product + slot include)
curl -s -H "Authorization: Bearer pk_YOUR_KEY_HERE" \
https://api.dcast.pro/api/v1/booking/bookings/{bookingId}?status accepts PENDING / CONFIRMED / IN_PROGRESS / COMPLETED / CANCELED / REFUNDED / NO_SHOW.
Discount codes
Issue percent-off or fixed-amount codes. Codes are upper-cased and unique per creator. Optionally scope to a single product.
POST https://api.dcast.pro/api/v1/booking/discount-codes
{
"code": "EARLYBIRD20", // stored upper-cased
"percentOff": 20, // OR amountCentsOff: 500 — not both
"productId": null, // scope to product or leave null for all
"maxUses": 100,
"expiresAt": "2026-08-01T00:00:00Z"
}
# → 201 { data: { ... } } | 409 CODE_EXISTS on collision
PATCH https://api.dcast.pro/api/v1/booking/discount-codes/{id}
{ "enabled": false, "maxUses": 50, "expiresAt": "..." }
DELETE https://api.dcast.pro/api/v1/booking/discount-codes/{id}Errors
| Code | HTTP | Meaning |
|---|---|---|
BAD_REQUEST | 400 | missing/invalid type, title, priceCents, durationMin |
INVALID_REF | 400 | discount productId not yours |
NOT_FOUND | 404 | product / booking / discount not yours |
PRODUCT_HAS_BOOKINGS | 409 | cannot delete product with bookings — unpublish instead |
CODE_EXISTS | 409 | discount code already exists for your account (unique per creator) |
Cohorts (under a product of type COHORT)
Cohorts are scheduled programs run under a COHORT-typed product. Each cohort has a start/end window, a max-size cap, and an optional sequence of drip-released videos (CohortVideo rows).
# Create a cohort under a COHORT product
POST https://api.dcast.pro/api/v1/booking/products/{productId}/cohorts
{
"title": "Spring 2026 intake",
"startsAt": "2026-06-01T15:00:00Z",
"endsAt": "2026-06-30T17:00:00Z",
"sessionCount": 4,
"maxSize": 20,
"enrollmentOpensAt": null,
"enrollmentClosesAt": null
}
# → 201 | 400 WRONG_PRODUCT_TYPE (parent is ONE_TO_ONE or LIVE_CLASS)
# List under a product
GET https://api.dcast.pro/api/v1/booking/products/{productId}/cohorts
# Read one with videos[] + product included
GET https://api.dcast.pro/api/v1/booking/cohorts/{cohortId}
# Update (title / startsAt / endsAt / sessionCount / maxSize / enrollment* / description)
PATCH https://api.dcast.pro/api/v1/booking/cohorts/{cohortId}
# Delete — 409 COHORT_HAS_ENROLLMENTS if any
DELETE https://api.dcast.pro/api/v1/booking/cohorts/{cohortId}
# Attach drip-content video (you must own the video)
POST https://api.dcast.pro/api/v1/booking/cohorts/{cohortId}/videos
{
"videoId": "<your video id>",
"revealAt": "2026-06-08T15:00:00Z",
"title": "Week 1 — Setup",
"position": 1
}
# 409 VIDEO_ALREADY_ATTACHED on unique-constraint collision
# Detach
DELETE https://api.dcast.pro/api/v1/booking/cohorts/{cohortId}/videos/{cohortVideoId}Waitlist (read-only)
Customers enrol on a sold-out LIVE_CLASS slot via the public storefront. The Partner API exposes a read-only feed so you can monitor your incoming queue.
GET https://api.dcast.pro/api/v1/booking/waitlist?status=WAITING&page=1&limit=25
# → 200 paginated with slot { startAt, endAt, product { id, slug, title } } included.
# ?status accepts WAITING | OFFERED | ACCEPTED | EXPIRED | CANCELED.Deferred (roadmap)
Email sequence builder (Phase 6 monetization-v2 § B3 — drip emails after a booking) and slot-level direct CRUD are on the roadmap. Slots are auto-generated from Availability + product.durationMin; direct slot mutation is intentionally out of scope. File a request via support if either is blocking your integration.
