Developers

API reference

Create and look up parties from your own booking form or CRM. Available to Owners with the API access module (Pro plan) - create a key under Settings → API keys.

Base URL

https://mypartyhub.com/api/v1 - served on the platform host only, not on Owner subdomains or custom domains.

Authentication

Send your key as a bearer token:

Authorization: Bearer 12|mph_...

Each key acts as the Owner who created it and only sees that Owner's parties. Keys don't expire. Revoking a key deletes it immediately.

A key stops working (403) while the Owner is suspended or no longer has the API module, for example after dropping to Starter. It works again if access returns.

Scopes

Scope Allows
party:read GET /parties, GET /parties/{id}
party:create POST /parties
rsvp:read GET /parties/{id}/rsvps
document:read GET /parties/{id}/documents
checklist:read GET /parties/{id}/checklists

POST /parties

Creates a draft party. The host (booker) is not emailed; the owner sends their magic link from the party page when ready. Requires party:create.

Field Type Rules
children array required, at least one
children[].name string required, max 255
children[].age integer required, 0–25
party_date string required, YYYY-MM-DD, today or later
start_time string required, HH:MM
end_time string required, HH:MM, after start_time
venue_address string optional, max 255
venue_name string optional, max 255
venue_line1 string optional, max 255
venue_city string optional, max 255
venue_postcode string optional, max 32
venue_country string optional, max 255
venue_lat number optional, -90 to 90
venue_lng number optional, -180 to 180
venue_place_id string optional, max 255
special_notes string optional, max 2000
booker_name string required, max 255
booker_email string required, email
booker_phone string required, max 40
rsvp_contact_name string optional, defaults to booker_name
rsvp_contact_phone string optional, defaults to booker_phone
curl -X POST https://mypartyhub.com/api/v1/parties \
  -H "Authorization: Bearer 12|mph_..." \
  -H "Content-Type: application/json" \
  -d '{
"children": [{"name": "Mia", "age": 5}, {"name": "Theo", "age": 7}],
"party_date": "2026-11-14",
"start_time": "14:00",
"end_time": "16:00",
"venue_address": "Old Vic Hall, Bristol",
"booker_name": "Sarah Jones",
"booker_email": "[email protected]",
"booker_phone": "07700 900123"
  }'

Returns 201 Created with the party:

{
  "data": {
"id": "9d2f6c1e-5b0a-4f7e-9d1c-2a3b4c5d6e7f",
"status": "draft",
"party_date": "2026-11-14",
"start_time": "14:00",
"end_time": "16:00",
"venue_address": "Old Vic Hall, Bristol",
"venue": {
  "name": null, "line1": null, "city": null, "postcode": null,
  "country": null, "lat": null, "lng": null, "place_id": null
},
"special_notes": null,
"children": [{"name": "Mia", "age": 5}, {"name": "Theo", "age": 7}],
"booker": {"name": "Sarah Jones", "email": "[email protected]", "phone": "07700 900123"},
"rsvp_contact": {"name": "Sarah Jones", "phone": "07700 900123"},
"guest_count": 0,
"booker_link_url": "https://acme.mypartyhub.com/my/auth/…",
"invite_url": null,
"confirmed_at": null,
"created_at": "2026-09-21T10:15:00+00:00",
"updated_at": "2026-09-21T10:15:00+00:00"
  }
}

booker_link_url is the host's private sign-in link; treat it like a password. Only this create response includes it. invite_url stays null until the host confirms the party. status is one of draft, pending_confirmation, confirmed. guest_count is the total guests across "yes" RSVPs only - a decline never adds to it.

Requests are not idempotent: retrying a create that timed out can create a second party.

GET /parties

Lists your parties, newest party date first. Requires party:read.

Query Notes
statusdraft, pending_confirmation or confirmed
date_fromYYYY-MM-DD, party date on or after
date_toYYYY-MM-DD, party date on or before
per_page1–100, default 25
pagepage number, default 1

Returns {"data": [...], "links": {...}, "meta": {...}}, where each item has the shape above (without booker_link_url) and meta carries current_page, last_page, per_page and total.

GET /parties/{id}

One party, same shape as above without booker_link_url. Requires party:read. Another Owner's party returns 404.

GET /parties/{id}/rsvps

Lists guest RSVPs on a party, newest first. Requires rsvp:read. Another Owner's party returns 404.

Query Notes
statusyes or no
per_page1–100, default 25
pagepage number, default 1
{
  "data": [
{
  "id": 42,
  "status": "yes",
  "guest_name": "Sarah Jones",
  "guest_count": 2,
  "attendees": ["Sarah Jones", "Tom Jones"],
  "notes": "Dairy-free please.",
  "created_at": "2026-09-21T10:15:00+00:00",
  "updated_at": "2026-09-21T10:15:00+00:00"
}
  ],
  "links": { "...": "..." },
  "meta": { "current_page": 1, "last_page": 1, "per_page": 25, "total": 1 }
}

The guest's email is never included, on any plan or scope - an Owner (and by extension their API key) never sees a guest's plaintext email address.

GET /parties/{id}/documents

Lists documents attached to a party, in display order. Requires document:read. Another Owner's party returns 404.

Query Notes
per_page1–100, default 25
pagepage number, default 1
{
  "data": [
{
  "id": "3f2a1b4c-...",
  "title": "Party pack",
  "description": "Everything you need to know.",
  "instruction_text": "Print two copies.",
  "display_order": 0,
  "file": {
    "filename": "party-pack.pdf",
    "mime_type": "application/pdf",
    "size_bytes": 412000
  },
  "release_rule": "immediate",
  "released_at": null,
  "visible_to_host": true,
  "created_at": "2026-09-21T10:15:00+00:00",
  "updated_at": "2026-09-21T10:15:00+00:00"
}
  ],
  "links": { "...": "..." },
  "meta": { "current_page": 1, "last_page": 1, "per_page": 25, "total": 1 }
}

No file download URL is included - the app never exposes direct file URLs, even to the Owner's own account; files are only ever streamed through an authenticated download route. visible_to_host tells you whether the Host can currently see this attachment given its release_rule (immediate, after_confirmation, or checklist_triggered), so you can replicate that gating without re-implementing the rule yourself.

GET /parties/{id}/checklists

Lists checklists assigned to a party, each with its items in section/sort order. Requires checklist:read. Another Owner's party returns 404.

Query Notes
per_page1–100, default 25
pagepage number, default 1
{
  "data": [
{
  "id": "7c1e...",
  "name": "Essentials",
  "allow_host_items": true,
  "allow_host_notes": true,
  "allow_host_complete_owner_items": false,
  "items": [
    {
      "id": "9a2f...",
      "section_title": "Two weeks before",
      "title": "Order the cake",
      "description": null,
      "responsibility": "booker",
      "visibility": "booker",
      "due": { "offset": 14, "unit": "days", "direction": "before" },
      "link_url": null,
      "completed": false,
      "completed_at": null,
      "completed_by": null,
      "notes": null,
      "is_booker_added": false
    }
  ],
  "assigned_at": "2026-09-21T10:15:00+00:00",
  "created_at": "2026-09-21T10:15:00+00:00",
  "updated_at": "2026-09-21T10:15:00+00:00"
}
  ],
  "links": { "...": "..." },
  "meta": { "current_page": 1, "last_page": 1, "per_page": 25, "total": 1 }
}

responsibility is the raw value (owner, booker or either), not a display name - the app UI shows the owner's business name or the Host's real name instead of these words, but that's a presentation choice; resolve it yourself against the party's own booker_name if you need a display label. completed_by is owner, booker, or null if not yet completed. Read-only - items can't be created or ticked via the API yet.

Errors

Every error is JSON, whatever Accept header you send.

Status When
401Missing, invalid or revoked key
403Key lacks the scope, API module not enabled, or account suspended
404Party not found, or request sent to a non-platform host
422Validation failed
429Rate limit exceeded
{
  "message": "The party date cannot be in the past.",
  "errors": {
"party_date": ["The party date cannot be in the past."]
  }
}

Rate limits

60 requests a minute per key. Responses carry X-RateLimit-Limit and X-RateLimit-Remaining; a 429 adds Retry-After (seconds).