Your venue, your limits, and the categories you can post under.
Submit an experience for review.
Your submissions, newest first.
One submission and its review status.
Performance for every experience at your venue, by experience and by day.
Request access
Keys are issued per venue to operators SplitClub works with. The quickest way in is the Partner console: sign in with Google or your work email, request access, and once we link you to your venue you create and revoke keys there yourself. Or tell us about you below and we'll be in touch. It's shown once, so store it as a secret on your servers. If it ever leaks, we revoke it and issue a new one.
Authentication
Send the key as a bearer token on every request. Calls go from your servers, never from a browser or an app your customers download.
curl https://splitclubapp.com/api/v1/me \
-H "Authorization: Bearer sc_live_…"
{
"data": {
"venue": { "id": "9b2dc857-…", "name": "Your venue" },
"limits": { "writes_per_hour": 60, "reads_per_hour": 600 },
"categories": ["adventure", "holidays", "nightlife", "social", "wellness"]
}
}
Rate limits
Limits are per key, over a rolling hour.
Every response says where you stand: X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset (Unix seconds). Over the limit, you get 429 with a Retry-After header in seconds. If your volume needs more, tell your SplitClub contact.
Post an experience
A post is a submission. SplitClub curates what each city shows, so every experience is reviewed before members see it; approved ones go live at your venue, in your city. The response comes back at once with an id and "status": "pending".
curl https://splitclubapp.com/api/v1/experiences \
-H "Authorization: Bearer sc_live_…" \
-H "Content-Type: application/json" \
-d '{
"external_id": "evt_20261108_supper",
"title": "Saturday supper club",
"description": "Five courses, then the room turns into a party at eleven.",
"category": "nightlife",
"starts_at": "2026-11-08T20:00:00-05:00",
"ends_at": "2026-11-09T01:00:00-05:00",
"price_per_person": 145,
"capacity": 40,
"photo_urls": ["https://yourcdn.example/supper-club.jpg"],
"booking_url": "https://yoursite.example/supper-club"
}'
| Field | Type | Notes |
|---|---|---|
titlerequired | string | Up to 120 characters. |
starts_atrequired | ISO 8601 | In the future, at most two years ahead. Include the offset. |
external_id | string | Your own ID, up to 128 characters. Posting the same one again returns the original with "duplicate": true and changes nothing, so retries are safe. |
description | string | Up to 4,000 characters. |
category | string | One of the categories from /me. |
ends_at | ISO 8601 | After starts_at. |
price_per_person | number | US dollars, 0 to 100,000. |
capacity | integer | People, 1 to 5,000. |
photo_urls | array | Up to 10 https image URLs. |
booking_url | string | An https link to the experience on your site. |
A new submission answers 201; a repeated external_id answers 200. Either way the body is the submission:
{
"data": {
"id": "a2daa945-58ea-490f-99e0-d79519c3f01a",
"external_id": "evt_20261108_supper",
"status": "pending",
"title": "Saturday supper club",
"starts_at": "2026-11-09T01:00:00+00:00",
"price_per_person": 145,
"capacity": 40,
"experience_id": null,
"review_note": null,
"created_at": "2026-10-12T21:58:23Z",
"reviewed_at": null
},
"duplicate": false
}
Read them back
List your submissions, or fetch one to follow its review. status moves from pending to approved, with the live experience_id, or to rejected, with a review_note saying why.
curl "https://splitclubapp.com/api/v1/experiences?status=approved&limit=50" \
-H "Authorization: Bearer sc_live_…"
# One submission
curl https://splitclubapp.com/api/v1/experiences/a2daa945-58ea-490f-99e0-d79519c3f01a \
-H "Authorization: Bearer sc_live_…"
Lists return up to 100 at a time. When there may be more, the response includes next_before; pass it back as ?before= for the next page.
Analytics
Analytics cover the experiences you posted, once they're approved, plus views of your venue's own page. Pass from and to (ISO 8601, up to 366 days apart; the default is the last 30 days), and experience_id to narrow it to one.
curl "https://splitclubapp.com/api/v1/analytics?from=2026-09-01T00:00:00Z&to=2026-10-01T00:00:00Z" \
-H "Authorization: Bearer sc_live_…"
{
"data": {
"from": "2026-09-01T00:00:00+00:00",
"to": "2026-10-01T00:00:00+00:00",
"totals": {
"experiences": 12, "views": 1840, "unique_viewers": 912, "booking_starts": 141,
"saves": 77, "bookings": 63, "guests": 118, "booked_value": 9135,
"checked_in": 57, "view_to_booking_rate": 0.0691, "show_rate": 0.9048,
"venue_page_views": 406
},
"experiences": [
{ "experience_id": "…", "title": "Saturday supper club", "starts_at": "…",
"views": 512, "unique_viewers": 270, "booking_starts": 44, "saves": 21,
"bookings": 19, "guests": 36, "booked_value": 2755, "checked_in": 18,
"view_to_booking_rate": 0.0704 }
],
"daily": [ { "date": "2026-09-01", "views": 54, "bookings": 2 } ]
}
}
Example figures, for shape only.
| Metric | What it counts |
|---|---|
views | Times the experience's page was opened in the SplitClub app. |
unique_viewers | Different people who opened it. |
booking_starts | Different people who started booking. |
saves | Times it was liked or saved for later. |
bookings | Paid places. |
guests | People those bookings bring, including the guests they add. |
booked_value | US dollars paid for those places, before SplitClub's service fee. |
checked_in | Bookings checked in at the door. |
view_to_booking_rate | Bookings divided by unique viewers. |
show_rate | Check-ins divided by bookings. |
venue_page_views | Times your venue's own page was opened. |
Figures are totals. They never identify a member, and test payments are left out.
Errors
Errors share one shape. field appears when a specific input is wrong; quote request_id if you contact us.
{
"error": {
"code": "invalid_request",
"message": "must be in the future",
"field": "starts_at",
"request_id": "86f24adb-a41f-4320-bba1-00a9cdae696b"
}
}
| Status | Code | When |
|---|---|---|
| 400 | invalid_json | The body isn't JSON. |
| 401 | unauthorized | The key is missing, wrong or revoked. |
| 404 | not_found | No such route, or the experience isn't yours. |
| 405 | method_not_allowed | The route doesn't take that method. |
| 413 | payload_too_large | The body is over 64 KB. |
| 422 | invalid_request | A field failed validation; see field and message. |
| 429 | rate_limited | Over the hourly limit; wait Retry-After seconds. |
| 500 | internal_error | Our side. Retry with backoff. |
Versioning
This is version 1. We add fields to responses without notice, so ignore the ones you don't use; anything that would break an integration ships as a new version.