Rizz Invites developer platform
One event contract, now over REST.
Use the same OAuth grants or host PATs as MCP. Scopes, tenant isolation, confirmations, idempotency, rate limits, sandbox behavior, and audit policy are shared by both transports.
API origin
https://rizzinvites.com
Every operation path below starts with /api/v1.
Start here
Make your first authenticated request
Send a bearer token in the Authorization header. Browser cookies and web sessions never authorize API calls. JSON fields use snake_case and unknown fields are rejected at every nesting level.
curl https://rizzinvites.com/api/v1/account \
-H 'Authorization: Bearer $RIZZ_ACCESS_TOKEN' \
-H 'Accept: application/json'
curl https://rizzinvites.com/api/v1/events \
-H 'Authorization: Bearer $RIZZ_ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"Birthday dinner","party_date":"2026-09-12","time_from":"18:00:00","timezone":"America/New_York"}'
OAuth and PATs
Sign in or create an account in the browser
Start OAuth at /oauth/authorize with the canonical https://rizzinvites.com resource and PKCE S256. If the host has no account, the existing magic-link or Google browser flow creates one, preserves the validated OAuth request, resumes consent, and returns the code only to the registered redirect URI. There is no MCP or REST signup endpoint.
Admin boundary
The /api/v1/admin scope accepts admin-audience PATs only. OAuth, host PATs, non-admin users, and browser sessions are rejected.
Golden workflow
Draft, design, guests, entitlement, delivery
The free path never opens checkout. Create checkout only when the current event response indicates that the guest count or selected capability requires a paid tier.
-
1
create_eventCreate a draft with local date/time and an explicit timezone.
-
2
add_guestsImport 1–100 contactable guests atomically with Idempotency-Key.
-
3
search_templates / generate_coverChoose an active template or queue a cover, then select exactly one design.
-
4
create_checkout_link (conditional)Only create checkout if the event needs a paid tier; reconcile it with POST.
-
5
send_invitesRequest the delivery preview, review it, then retry identically with RizzInvites-Confirmation.
-
6
get_event / list_guestsRe-read canonical state and delivery outcomes after the queue commits.
Retry safety
Headers bind consequential work
Header values are normalized into the same internal arguments as MCP before hashing. Transport is excluded from the binding, so a retry can cross from MCP to REST when it uses the same actor and normalized business arguments.
RizzInvites-Confirmation
A protected mutation without this header returns 409 confirmation_required with a preview and token. Send, cancel, and delete tokens expire after 15 minutes; other confirmation tokens expire after 5. Only send_invites, cancel_event, and delete_event may replay a stored confirmed response for 24 hours.
Idempotency-Key
Required for guest batches, cover generation, checkout creation, and guest messaging. Matching completed results replay for 24 hours; changed arguments return 409 idempotency_conflict.
# First request returns 409 confirmation_required with a preview and token.
curl -X POST https://rizzinvites.com/api/v1/events/123/invitation-deliveries \
-H 'Authorization: Bearer $RIZZ_ACCESS_TOKEN'
# Retry the identical request with the returned token.
curl -X POST https://rizzinvites.com/api/v1/events/123/invitation-deliveries \
-H 'Authorization: Bearer $RIZZ_ACCESS_TOKEN' \
-H 'RizzInvites-Confirmation: rzi_cfm_...'
Generated reference
Every canonical route
Operation metadata below comes from the same contract used for MCP discovery, REST dispatch, schema validation, and OpenAPI generation.
Host API
Host PAT or OAuth token; the public OpenAPI document contains only the 17 launch-enabled host operations and four content routes.
/api/v1/events
list_events
events:read
Validated request and response example
{
"limit": 50
}
{
"data": {
"events": []
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id
get_event
events:read
Validated request and response example
{
"event_id": 42
}
{
"data": {
"allow_plus_ones": true,
"created_at": "2026-08-08T12:00:00Z",
"design": {
"type": "none"
},
"guest_count": 0,
"host_message": "Join us!",
"id": 42,
"name": "Maya's birthday",
"party_date": "2026-09-12",
"role": "owner",
"rsvp_summary": {
"confirmed": 0,
"declined": 0,
"pending": 0,
"plus_ones_total": 0
},
"status": "draft",
"tier": "free",
"time_from": "15:00:00",
"timezone": "America/New_York",
"timezone_inferred": false,
"updated_at": "2026-08-08T12:00:00Z"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/guests
list_guests
guests:read
Validated request and response example
{
"event_id": 42,
"limit": 50
}
{
"data": {
"guests": [
{
"contacts_revealed": false,
"delivery_status": "pending",
"id": 7,
"masked_email": "s***@example.com",
"name": "Sam",
"plus_ones": 0,
"rsvp_status": "pending"
}
]
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/templates
search_templates
events:read
Validated request and response example
{
"category": "kids_birthday",
"limit": 20
}
{
"data": {
"templates": [
{
"category": "kids_birthday",
"id": 3,
"name": "Garden",
"preview_url": "https://cdn.example.com/template.png",
"tags": [
"garden"
]
}
]
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/account
get_account
account:read
Validated request and response example
{}
{
"data": {
"account_mode": "production",
"ai_pro_active": false,
"email": "h***@example.com",
"id": 1,
"name": "Host",
"timezone": "America/New_York"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events
create_event
events:write
Validated request and response example
{
"name": "Maya's birthday",
"party_date": "2026-09-12",
"time_from": "15:00",
"timezone": "America/New_York"
}
{
"data": {
"allow_plus_ones": true,
"created_at": "2026-08-08T12:00:00Z",
"design": {
"type": "none"
},
"guest_count": 0,
"host_message": "Join us!",
"id": 42,
"name": "Maya's birthday",
"party_date": "2026-09-12",
"role": "owner",
"rsvp_summary": {
"confirmed": 0,
"declined": 0,
"pending": 0,
"plus_ones_total": 0
},
"status": "draft",
"tier": "free",
"time_from": "15:00:00",
"timezone": "America/New_York",
"timezone_inferred": false,
"updated_at": "2026-08-08T12:00:00Z"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id
update_event
events:write
Validated request and response example
{
"event_id": 42,
"name": "Updated party"
}
{
"data": {
"allow_plus_ones": true,
"created_at": "2026-08-08T12:00:00Z",
"design": {
"type": "none"
},
"guest_count": 0,
"host_message": "Join us!",
"id": 42,
"name": "Updated party",
"party_date": "2026-09-12",
"role": "owner",
"rsvp_summary": {
"confirmed": 0,
"declined": 0,
"pending": 0,
"plus_ones_total": 0
},
"status": "draft",
"tier": "free",
"time_from": "15:00:00",
"timezone": "America/New_York",
"timezone_inferred": false,
"updated_at": "2026-08-08T12:01:00Z"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/guests
add_guests
guests:write
Validated request and response example
{
"event_id": 42,
"guests": [
{
"email": "sam@example.com",
"name": "Sam"
}
],
"idempotency_key": "guest-import-42-v1"
}
{
"data": {
"count": 1,
"guests": [
{
"id": 7,
"name": "Sam"
}
]
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/guests/:guest_id
update_guest
guests:write
Validated request and response example
{
"event_id": 42,
"guest_id": 7,
"name": "Sam Lee"
}
{
"data": {
"id": 7,
"name": "Sam Lee"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/guests/:guest_id
remove_guest
guests:write
Validated request and response example
{
"event_id": 42,
"guest_id": 7
}
{
"data": {
"deleted": true
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/invitation-deliveries
send_invites
messaging:send
Validated request and response example
{
"confirmation_token": "rzi_cfm_fixture",
"event_id": 42
}
{
"data": {
"event_id": 42,
"queued_count": 1,
"sent_at": "2026-08-08T12:00:00Z",
"skipped": []
},
"meta": {
"next_cursor": null,
"request_id": "req_send_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/covers
generate_cover
ai:generate
Validated request and response example
{
"event_id": 42,
"idempotency_key": "cover-42-v1",
"theme": "enchanted garden"
}
{
"data": {
"created_at": "2026-08-08T12:00:00Z",
"event_id": 42,
"id": 9,
"selected": false,
"status": "queued",
"theme": "enchanted garden"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/covers/:generation_id
get_cover_status
events:read
Validated request and response example
{
"event_id": 42,
"generation_id": 9
}
{
"data": {
"cover_url": "https://cdn.example.com/cover.png",
"created_at": "2026-08-08T12:00:00Z",
"event_id": 42,
"id": 9,
"selected": true,
"status": "succeeded",
"theme": "enchanted garden"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/design
set_event_design
events:write
Validated request and response example
{
"event_id": 42,
"generation_id": 9
}
{
"data": {
"allow_plus_ones": true,
"created_at": "2026-08-08T12:00:00Z",
"design": {
"cover_url": "https://cdn.example.com/cover.png",
"id": 9,
"type": "generation"
},
"guest_count": 0,
"host_message": "Join us!",
"id": 42,
"name": "Maya's birthday",
"party_date": "2026-09-12",
"role": "owner",
"rsvp_summary": {
"confirmed": 0,
"declined": 0,
"pending": 0,
"plus_ones_total": 0
},
"status": "draft",
"tier": "free",
"time_from": "15:00:00",
"timezone": "America/New_York",
"timezone_inferred": false,
"updated_at": "2026-08-08T12:00:00Z"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/share-link
get_event_link
events:read
Validated request and response example
{
"event_id": 42
}
{
"data": {
"url": "https://rizzinvites.com/event/example"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/checkouts
create_checkout_link
billing:checkout
Validated request and response example
{
"event_id": 42,
"idempotency_key": "checkout-42-v1",
"tier": "pro"
}
{
"data": {
"amount_cents": 1499,
"checkout_id": "rzi_chk_fixture",
"currency": "usd",
"event_id": 42,
"expires_at": "2026-08-08T12:30:00Z",
"status": "open",
"tier": "pro",
"url": "https://checkout.stripe.com/example"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/checkouts/:checkout_id/reconcile
check_payment_status
billing:checkout
Validated request and response example
{
"checkout_id": "rzi_chk_fixture"
}
{
"data": {
"amount_cents": 1499,
"checkout_id": "rzi_chk_fixture",
"currency": "usd",
"event_id": 42,
"expires_at": "2026-08-08T12:30:00Z",
"status": "paid",
"tier": "pro"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/cancellations
cancel_event
events:write
Validated request and response example
{
"confirmation_token": "rzi_cfm_fixture",
"event_id": 42
}
{
"data": {
"allow_plus_ones": true,
"created_at": "2026-08-08T12:00:00Z",
"design": {
"id": 3,
"type": "template"
},
"guest_count": 1,
"host_message": "Join us!",
"id": 42,
"name": "Maya's birthday",
"party_date": "2026-09-12",
"role": "owner",
"rsvp_summary": {
"confirmed": 0,
"declined": 0,
"pending": 1,
"plus_ones_total": 0
},
"status": "cancelled",
"tier": "free",
"time_from": "15:00:00",
"timezone": "America/New_York",
"timezone_inferred": false,
"updated_at": "2026-08-08T12:01:00Z"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id
delete_event
events:write
Validated request and response example
{
"confirmation_token": "rzi_cfm_fixture",
"event_id": 42
}
{
"data": {
"deleted": true
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/guest-messages
message_guests
messaging:send
Validated request and response example
{
"confirmation_token": "rzi_cfm_fixture",
"event_id": 42,
"idempotency_key": "change-42-v1",
"message": "New venue"
}
{
"data": {
"event_id": 42,
"queued_count": 1
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/cohosts
add_cohost
events:write
Validated request and response example
{
"confirmation_token": "rzi_cfm_fixture",
"email": "sam@example.com",
"event_id": 42,
"name": "Sam"
}
{
"data": {
"id": 8,
"name": "Sam",
"status": "pending"
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/events/:event_id/cohosts/:cohost_id
remove_cohost
events:write
Validated request and response example
{
"cohost_id": 8,
"confirmation_token": "rzi_cfm_fixture",
"event_id": 42
}
{
"data": {
"deleted": true
},
"meta": {
"next_cursor": null,
"request_id": "req_fixture",
"warnings": []
}
}
/api/v1/pricing
get_pricing
events:read
Validated request and response example
{}
{
"data": {
"tiers": [
{
"id": "free",
"name": "Free",
"subtitle": "Up to 10 guests",
"price_cents": 0,
"max_guests": 10
}
]
},
"meta": {
"warnings": [],
"request_id": "req_example",
"next_cursor": null
}
}
/api/v1/guides/host-playbook
get_host_playbook
events:read
Validated request and response example
{}
{
"data": {
"content": "# Host playbook",
"media_type": "text/markdown"
},
"meta": {
"warnings": [],
"request_id": "req_example",
"next_cursor": null
}
}
/api/v1/prompts
list_prompts
Validated request and response example
{}
{
"data": {
"prompts": []
},
"meta": {
"warnings": [],
"request_id": "req_example",
"next_cursor": null
}
}
/api/v1/prompts/:prompt_name/render
render_prompt
Validated request and response example
{
"guest_count": 12,
"occasion": "birthday"
}
{
"data": {
"message": "Help me plan a safe draft event.",
"name": "plan_my_party"
},
"meta": {
"warnings": [],
"request_id": "req_example",
"next_cursor": null
}
}
Collections
Opaque cursor pagination
Events and guests default to 50 items and accept at most 100. Template search defaults to 20 and accepts at most 50. Pass the opaque meta.next_cursor value unchanged as cursor; an invalid cursor returns 422 validation_failed. A null next_cursor means the collection is complete.
curl 'https://rizzinvites.com/api/v1/events?limit=50&cursor=eyJhZnRlcl9pZCI6NDJ9' \
-H 'Authorization: Bearer $RIZZ_ACCESS_TOKEN'
# Reuse meta.next_cursor exactly; do not parse or modify it.
Operational contract
Envelopes, statuses, limits, and CORS
Success uses {data, meta}; failures use {error}. X-Request-ID mirrors meta.request_id and Retry-After accompanies 429 responses. Request bodies are capped at 1,000,000 bytes and responses at 100,000 bytes.
CORS: configured origins may use GET, POST, PATCH, PUT, DELETE, and OPTIONS with Authorization, Content-Type, Idempotency-Key, RizzInvites-Confirmation, and X-Request-ID. Cookies are never enabled.
Statuses: 200 reads/updates/deletes; 201 creates; 202 queued cover/delivery/message work; 400 syntax; 401 auth; 402 payment; 403 scope/origin; 404 inaccessible or disabled; 409 confirmation/state/idempotency; 413 size; 422 schema/blocklist; 429 limits; 503 temporary failure.
ai
10 / credential / hour
checkout
10 / credential / hour
event_messaging
3 / event / day
messaging
5 / credential / hour
mutation
30 / credential / minute
pre_auth
60 / IP / minute
read
120 / credential / minute
not_found
Use error.next_action and refresh current resource state.
malformed_request
Use error.next_action and refresh current resource state.
validation_failed
Use error.next_action and refresh current resource state.
invalid_state
Use error.next_action and refresh current resource state.
not_draft
Use error.next_action and refresh current resource state.
design_missing
Call set_event_design.
payment_required
Call create_checkout_link with details.required_tier, complete payment, poll, and retry.
guest_limit_reached
Use error.next_action and refresh current resource state.
quota_exceeded
Use error.next_action and refresh current resource state.
contact_blocked
Remove or correct the redacted row index.
confirmation_required
Review the preview and repeat identical arguments with its token.
confirmation_expired
Request a new preview.
rate_limited
Wait details.retry_after_seconds.
conflict
Use error.next_action and refresh current resource state.
idempotency_conflict
Use error.next_action and refresh current resource state.
request_too_large
Use error.next_action and refresh current resource state.
response_too_large
Use error.next_action and refresh current resource state.
insufficient_scope
Use error.next_action and refresh current resource state.
{
"data": {
"id": 42,
"name": "Birthday dinner"
},
"meta": {
"warnings": [],
"request_id": "req_01",
"next_cursor": null
}
}
{
"error": {
"code": "confirmation_required",
"message": "Confirm this action and retry with the confirmation token.",
"details": {
"expires_at": "2026-08-09T18:15:00Z",
"confirmation_token": "rzi_cfm_..."
},
"retryable": false,
"next_action": {
"retry": true
}
},
"meta": {
"request_id": "req_02"
}
}
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Retry later.",
"details": {
"retry_after_seconds": 60
},
"retryable": true,
"next_action": {}
},
"meta": {
"request_id": "req_03"
}
}
Version and availability
Stable v1, with post-beta routes visible but off.
Additive optional fields remain in /api/v1; breaking changes require /api/v2. Event deletion, cancellation, guest messaging, and cohost operations return 404 until post-beta is separately enabled. Production sandbox is disabled. The MCP_ENABLED kill switch disables MCP, OAuth execution, and REST execution while this documentation and its generated contracts remain public.
Changelog · 2026-08-09
v1 launch contract: canonical OAuth resource, REST/MCP parity, closed outputs, correlated error envelopes, and launch-only public OpenAPI publication.