REST API reference

Joy API

15 endpoints for Joy. Each one is a POST with a JSON body, called with your API key.

Base URL
https://cotlet.dev/api/v1/joy
Connects with
Your own Joy account, as the event owner or a collaborator
Integration page
Joy
Joy Endpoints
Endpoint Access Description
list_events read Joy events you own or collaborate on, with name, date and website URL.
list_guests read Guest list with party, plus-ones, tags, contact details and RSVP answers per question.
get_guest read One guest profile: contact details, party, tags, all RSVP answers and email tracking history.
get_rsvp_summary read Attending, declined and pending counts, with a breakdown of answers to each RSVP question.
list_schedule read Events on your Schedule page with time, time zone, venue, dress code and privacy.
list_registry_gifts read Registry items and cash funds with price, quantity, Our Most Wanted flag and purchased or reserved status.
list_received_gifts read The gift tracker: who bought each gift, order info, cash fund contributions and whether you sent a thank-you.
add_guest write Add a guest to the guest list, optionally into a party with blank plus-ones. Sends nothing.
update_guest write Change contact details, party or plus-ones, or set or remove an RSVP answer for a guest.
assign_guest_tags write Add or remove guest tags on several guests at once. Tags control private events and RSVP questions.
update_schedule_event write Change an event on your Schedule page. Guests see it on your website right away.
add_registry_gift write Add a gift from any store by product URL. Joy fills in the title and price when it can.
send_rsvp_reminder write RSVP reminder with a link to your RSVP page, by default to every guest who has not responded.
send_email_message write Email update to selected guests or tags, with a button linking to your event website.
send_thank_you_note write Digital thank-you email to the guest who gave a gift, sent from the gift tracker.

POST https://cotlet.dev/api/v1/joy/list_events

Returns every Joy event your account can open, as owner or collaborator. Use event_id from each item as the event_id parameter of the other endpoints.

Parameters

No parameters.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/list_events \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("joy", "list_events")
Node.js
const result = await cotlet.call('joy', 'list_events');
CLI
cotlet call joy list_events

Example response

{
  "events": [
    {
      "event_id": "evt_8KQ2mZ",
      "name": "Maria and Tom",
      "date": "2027-06-12",
      "role": "owner",
      "website": "https://withjoy.com/maria-and-tom"
    }
  ]
}

POST https://cotlet.dev/api/v1/joy/list_guests

Returns guests in guest list order with their party, tags and answers to each RSVP question. Filter by RSVP status, tag or name to narrow it down. Pages hold up to 500 guests; pass next_cursor back as cursor.

Parameters

Parameters: list_guests
NameTypeDescription
event_id required string Event ID from list_events.
rsvp enum all, attending, declined or no_response. Default: all.
tag string Only guests with this guest tag.
search string Match on guest name or email.
limit integer 1 to 500. Default: 100.
cursor string Next page cursor from the previous call.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/list_guests \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"evt_8KQ2mZ","rsvp":"attending","tag":"Reception","limit":500}'
Python
result = client.call("joy", "list_guests", {"event_id":"evt_8KQ2mZ","rsvp":"attending","tag":"Reception","limit":500})
Node.js
const result = await cotlet.call('joy', 'list_guests', {"event_id":"evt_8KQ2mZ","rsvp":"attending","tag":"Reception","limit":500});
CLI
cotlet call joy list_guests --data '{"event_id":"evt_8KQ2mZ","rsvp":"attending","tag":"Reception","limit":500}'

Example response

{
  "guests": [
    {
      "guest_id": "g_4d21",
      "first_name": "Ana",
      "last_name": "Lopez",
      "email": "ana@example.com",
      "party": "Lopez",
      "tags": [
        "friends"
      ],
      "rsvp": "attending",
      "answers": {
        "Meal choice": "Vegetarian"
      }
    },
    {
      "guest_id": "g_4d22",
      "first_name": "Luis",
      "last_name": "Lopez",
      "email": null,
      "party": "Lopez",
      "tags": [
        "friends"
      ],
      "rsvp": "attending",
      "answers": {
        "Meal choice": "Fish"
      }
    }
  ],
  "next_cursor": null
}

Get guest

read

POST https://cotlet.dev/api/v1/joy/get_guest

Returns one guest with the full set of RSVP answers and which emails were sent to them. Use it before changing an RSVP or contacting the guest.

Parameters

Parameters: get_guest
NameTypeDescription
event_id required string Event ID from list_events.
guest_id required string Guest ID from list_guests.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/get_guest \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2","guest_id":"guest_8c41d2"}'
Python
result = client.call("joy", "get_guest", {"event_id":"event_8c41d2","guest_id":"guest_8c41d2"})
Node.js
const result = await cotlet.call('joy', 'get_guest', {"event_id":"event_8c41d2","guest_id":"guest_8c41d2"});
CLI
cotlet call joy get_guest --data '{"event_id":"event_8c41d2","guest_id":"guest_8c41d2"}'

Example response

{
  "guest_id": "g_4d21",
  "first_name": "Ana",
  "last_name": "Lopez",
  "email": "ana@example.com",
  "phone": null,
  "party": "Lopez",
  "plus_ones": 0,
  "tags": [
    "friends"
  ],
  "rsvp": "attending",
  "answers": {
    "Meal choice": "Vegetarian",
    "Dietary notes": "No nuts"
  },
  "emails": [
    {
      "subject": "Two weeks left to RSVP",
      "sent_at": "2027-05-29T10:00:00Z",
      "opened": true
    }
  ]
}

POST https://cotlet.dev/api/v1/joy/get_rsvp_summary

Returns counts of guests who are attending, declined or have not responded, and for each RSVP question how many guests gave each answer. The counts match the Guest List screen.

Parameters

Parameters: get_rsvp_summary
NameTypeDescription
event_id required string Event ID from list_events.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/get_rsvp_summary \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2"}'
Python
result = client.call("joy", "get_rsvp_summary", {"event_id":"event_8c41d2"})
Node.js
const result = await cotlet.call('joy', 'get_rsvp_summary', {"event_id":"event_8c41d2"});
CLI
cotlet call joy get_rsvp_summary --data '{"event_id":"event_8c41d2"}'

Example response

{
  "event_id": "evt_8KQ2mZ",
  "guests_total": 120,
  "attending": 74,
  "declined": 9,
  "no_response": 37,
  "questions": [
    {
      "question": "Meal choice",
      "answers": {
        "Beef": 31,
        "Fish": 24,
        "Vegetarian": 19
      }
    }
  ]
}

POST https://cotlet.dev/api/v1/joy/list_schedule

Returns the events on your Schedule page in time order. Privacy says whether everyone or only specific guests see an event. Use schedule_item_id with update_schedule_event.

Parameters

Parameters: list_schedule
NameTypeDescription
event_id required string Event ID from list_events.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/list_schedule \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2"}'
Python
result = client.call("joy", "list_schedule", {"event_id":"event_8c41d2"})
Node.js
const result = await cotlet.call('joy', 'list_schedule', {"event_id":"event_8c41d2"});
CLI
cotlet call joy list_schedule --data '{"event_id":"event_8c41d2"}'

Example response

{
  "schedule": [
    {
      "schedule_item_id": "sch_41",
      "name": "Welcome dinner",
      "start": "2027-06-11T18:00:00",
      "time_zone": "Europe/Rome",
      "venue": "Osteria del Ponte",
      "dress_code": "Smart casual",
      "privacy": "everyone"
    }
  ]
}

POST https://cotlet.dev/api/v1/joy/list_registry_gifts

Returns everything on your registry: gifts from any store and cash funds. Each item shows how many are still wanted and whether any were purchased or reserved.

Parameters

Parameters: list_registry_gifts
NameTypeDescription
event_id required string Event ID from list_events.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/list_registry_gifts \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2"}'
Python
result = client.call("joy", "list_registry_gifts", {"event_id":"event_8c41d2"})
Node.js
const result = await cotlet.call('joy', 'list_registry_gifts', {"event_id":"event_8c41d2"});
CLI
cotlet call joy list_registry_gifts --data '{"event_id":"event_8c41d2"}'

Example response

{
  "gifts": [
    {
      "gift_id": "gft_7731",
      "title": "Stand mixer",
      "store": "example-store.com",
      "price": "329.00",
      "quantity": 1,
      "purchased": 1,
      "most_wanted": true
    },
    {
      "gift_id": "gft_7740",
      "title": "Honeymoon fund",
      "type": "cash_fund",
      "raised": "450.00"
    }
  ]
}

POST https://cotlet.dev/api/v1/joy/list_received_gifts

Returns what the Track tab of your Registry shows: the guest who bought each physical gift, the quantity and order info, and what each guest put into a cash fund. Each row says whether a thank-you was sent.

Parameters

Parameters: list_received_gifts
NameTypeDescription
event_id required string Event ID from list_events.
since date Only gifts received on or after this date.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/list_received_gifts \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2"}'
Python
result = client.call("joy", "list_received_gifts", {"event_id":"event_8c41d2"})
Node.js
const result = await cotlet.call('joy', 'list_received_gifts', {"event_id":"event_8c41d2"});
CLI
cotlet call joy list_received_gifts --data '{"event_id":"event_8c41d2"}'

Example response

{
  "gifts": [
    {
      "gift_id": "gft_7731",
      "item": "Stand mixer",
      "from": "Ana Lopez",
      "quantity": 1,
      "received_at": "2027-05-20",
      "thank_you_sent": false
    },
    {
      "gift_id": "gft_7740",
      "item": "Honeymoon fund",
      "from": "Luis Lopez",
      "amount": "100.00",
      "received_at": "2027-05-22",
      "thank_you_sent": true
    }
  ]
}

Add guest

write

POST https://cotlet.dev/api/v1/joy/add_guest

Adds one guest to the guest list. Guests with the same party value are grouped and can RSVP for each other. It sends nothing to the guest and is undone by removing the guest, so it runs without asking.

Parameters

Parameters: add_guest
NameTypeDescription
event_id required string Event ID from list_events.
first_name required string First name, no symbols.
last_name string Last name, no symbols.
email string Needed for digital cards and email messages.
phone string Mobile number, for text messages with Messaging Plus.
party string Party name. Guests with the same party are grouped and can RSVP for each other.
plus_ones integer Number of blank plus-ones. Default: 0.
name_on_envelope string How the party is addressed on envelopes, e.g. The Porter Family.
tags string[] Guest tags to assign. New tags are created.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/add_guest \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"evt_8KQ2mZ","first_name":"Ada","last_name":"Okafor","email":"ada.okafor@example.com","party":"Okafor","name_on_envelope":"The Okafor Family","tags":["Bride family"]}'
Python
result = client.call("joy", "add_guest", {"event_id":"evt_8KQ2mZ","first_name":"Ada","last_name":"Okafor","email":"ada.okafor@example.com","party":"Okafor","name_on_envelope":"The Okafor Family","tags":["Bride family"]})
Node.js
const result = await cotlet.call('joy', 'add_guest', {"event_id":"evt_8KQ2mZ","first_name":"Ada","last_name":"Okafor","email":"ada.okafor@example.com","party":"Okafor","name_on_envelope":"The Okafor Family","tags":["Bride family"]});
CLI
cotlet call joy add_guest --data '{"event_id":"evt_8KQ2mZ","first_name":"Ada","last_name":"Okafor","email":"ada.okafor@example.com","party":"Okafor","name_on_envelope":"The Okafor Family","tags":["Bride family"]}'

Example response

{
  "guest_id": "g_4e08",
  "first_name": "Maria",
  "last_name": "Porter",
  "party": "Porter family",
  "name_on_envelope": "The Porter Family",
  "tags": [
    "family"
  ],
  "rsvp": "no_response"
}

Update guest

write

POST https://cotlet.dev/api/v1/joy/update_guest

Changes the fields you pass and leaves the rest. Setting rsvp_answers records the answer as if the guest gave it; null removes an answer. It sends nothing to the guest and one more call reverts it, so it runs without asking.

Parameters

Parameters: update_guest
NameTypeDescription
event_id required string Event ID from list_events.
guest_id required string Guest ID from list_guests.
fields required object Any of first_name, last_name, email, phone, party, plus_ones, name_on_envelope, rsvp_answers ({question: answer or null to remove}).

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/update_guest \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2","guest_id":"guest_8c41d2","fields":"fields"}'
Python
result = client.call("joy", "update_guest", {"event_id":"event_8c41d2","guest_id":"guest_8c41d2","fields":"fields"})
Node.js
const result = await cotlet.call('joy', 'update_guest', {"event_id":"event_8c41d2","guest_id":"guest_8c41d2","fields":"fields"});
CLI
cotlet call joy update_guest --data '{"event_id":"event_8c41d2","guest_id":"guest_8c41d2","fields":"fields"}'

Example response

{
  "guest_id": "g_4d22",
  "email": "luis@example.com",
  "rsvp": "attending",
  "answers": {
    "Meal choice": "Fish"
  }
}

POST https://cotlet.dev/api/v1/joy/assign_guest_tags

Adds or removes tags on many guests in one call. New tags are created. Tags can limit who sees a private event or an RSVP question, so check them before the next send. It sends nothing and is undone with one call.

Parameters

Parameters: assign_guest_tags
NameTypeDescription
event_id required string Event ID from list_events.
guest_ids required string[] Guest IDs from list_guests.
add string[] Tags to assign. New tags are created.
remove string[] Tags to take off these guests.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/assign_guest_tags \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2","guest_ids":["guest ids"]}'
Python
result = client.call("joy", "assign_guest_tags", {"event_id":"event_8c41d2","guest_ids":["guest ids"]})
Node.js
const result = await cotlet.call('joy', 'assign_guest_tags', {"event_id":"event_8c41d2","guest_ids":["guest ids"]});
CLI
cotlet call joy assign_guest_tags --data '{"event_id":"event_8c41d2","guest_ids":["guest ids"]}'

Example response

{
  "updated": 12,
  "added": [
    "family"
  ],
  "removed": []
}

Update schedule event

write Confirm

POST https://cotlet.dev/api/v1/joy/update_schedule_event

Changes the fields you pass on one Schedule event. The new time or venue shows on your public website at once, so guests can see it before any email goes out. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: update_schedule_event
NameTypeDescription
event_id required string Event ID from list_events.
schedule_item_id required string Schedule item ID from list_schedule.
fields required object Any of name, description, start, end, time_zone, venue, dress_code, privacy (everyone or specific_guests).

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/update_schedule_event \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2","schedule_item_id":"schedule_item_8c41d2","fields":"fields"}'
Python
result = client.call("joy", "update_schedule_event", {"event_id":"event_8c41d2","schedule_item_id":"schedule_item_8c41d2","fields":"fields"})
Node.js
const result = await cotlet.call('joy', 'update_schedule_event', {"event_id":"event_8c41d2","schedule_item_id":"schedule_item_8c41d2","fields":"fields"});
CLI
cotlet call joy update_schedule_event --data '{"event_id":"event_8c41d2","schedule_item_id":"schedule_item_8c41d2","fields":"fields"}'

Example response

{
  "schedule_item_id": "sch_41",
  "name": "Welcome dinner",
  "start": "2027-06-11T19:00:00",
  "time_zone": "Europe/Rome",
  "privacy": "everyone",
  "status": "updated"
}

POST https://cotlet.dev/api/v1/joy/add_registry_gift

Adds a gift to your registry from a product page. Joy reads the title and price from the page when it can; set them yourself otherwise. Mark it Our Most Wanted to highlight it. It reaches no one directly and one removal undoes it, so it runs without asking.

Parameters

Parameters: add_registry_gift
NameTypeDescription
event_id required string Event ID from list_events.
product_url required string Product page on any retailer site.
title string Overrides the title Joy reads from the page.
price string MSRP price in your registry currency, e.g. 89.00.
quantity integer How many you want. Default: 1.
most_wanted boolean Mark as Our Most Wanted. Default: false.
note string Note to Family and Friends shown with the gift.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/add_registry_gift \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2","product_url":"https://example.com"}'
Python
result = client.call("joy", "add_registry_gift", {"event_id":"event_8c41d2","product_url":"https://example.com"})
Node.js
const result = await cotlet.call('joy', 'add_registry_gift', {"event_id":"event_8c41d2","product_url":"https://example.com"});
CLI
cotlet call joy add_registry_gift --data '{"event_id":"event_8c41d2","product_url":"https://example.com"}'

Example response

{
  "gift_id": "gft_7752",
  "title": "Cast iron pan",
  "price": "89.00",
  "quantity": 1,
  "most_wanted": false
}

Send RSVP reminder

write Confirm

POST https://cotlet.dev/api/v1/joy/send_rsvp_reminder

Sends the Joy RSVP reminder. Without guest_ids it goes to every guest with no response. Guests with no email are skipped and counted in the response. Email is free; text needs Messaging Plus. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: send_rsvp_reminder
NameTypeDescription
event_id required string Event ID from list_events.
guest_ids string[] Recipients. Default: guests with no response.
delivery enum email, text or both. Text needs Messaging Plus. Default: email.
subject string Email subject line.
message string Message body. Default: the Joy reminder text.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/send_rsvp_reminder \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"evt_8KQ2mZ","delivery":"email","subject":"Two weeks left to RSVP"}'
Python
result = client.call("joy", "send_rsvp_reminder", {"event_id":"evt_8KQ2mZ","delivery":"email","subject":"Two weeks left to RSVP"})
Node.js
const result = await cotlet.call('joy', 'send_rsvp_reminder', {"event_id":"evt_8KQ2mZ","delivery":"email","subject":"Two weeks left to RSVP"});
CLI
cotlet call joy send_rsvp_reminder --data '{"event_id":"evt_8KQ2mZ","delivery":"email","subject":"Two weeks left to RSVP"}'

Example response

{
  "event_id": "evt_8KQ2mZ",
  "status": "sent",
  "delivery": "email",
  "recipients": 35,
  "skipped_missing_email": 2,
  "rsvp_url": "https://withjoy.com/maria-and-tom/rsvp"
}

Send email message

write Confirm

POST https://cotlet.dev/api/v1/joy/send_email_message

Sends a freeform email to the guests you pick by ID or tag, with a button to your event website. Guests without an email address do not get it. Scheduling for later needs Messaging Plus. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: send_email_message
NameTypeDescription
event_id required string Event ID from list_events.
guest_ids string[] Recipients by guest ID.
tags string[] Recipients by guest tag. Use guest_ids or tags.
subject required string Email subject line.
message required string Message body.
send_at datetime Schedule for later, ISO 8601. Needs Messaging Plus. Default: now.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/send_email_message \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"event_8c41d2","subject":"subject","message":"message"}'
Python
result = client.call("joy", "send_email_message", {"event_id":"event_8c41d2","subject":"subject","message":"message"})
Node.js
const result = await cotlet.call('joy', 'send_email_message', {"event_id":"event_8c41d2","subject":"subject","message":"message"});
CLI
cotlet call joy send_email_message --data '{"event_id":"event_8c41d2","subject":"subject","message":"message"}'

Example response

{
  "message_id": "msg_2290",
  "status": "sent",
  "recipients": 74,
  "skipped_missing_email": 1
}

Send thank-you note

write Confirm

POST https://cotlet.dev/api/v1/joy/send_thank_you_note

Sends one thank-you to the guest who gave the gift, and marks the gift as thanked in the tracker. By default you confirm each call; you can switch that off for this tool.

Parameters

Parameters: send_thank_you_note
NameTypeDescription
event_id required string Event ID from list_events.
gift_id required string Gift ID from list_received_gifts.
message required string Thank-you text.
subject string Email subject line.

Request

cURL
curl -X POST https://cotlet.dev/api/v1/joy/send_thank_you_note \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"event_id":"evt_8KQ2mZ","gift_id":"gft_7731","subject":"Thank you, Ana","message":"Ana, thank you for the stand mixer and for the gift to our honeymoon fund. The mixer has made bread every weekend since we got home. Maria and Tom"}'
Python
result = client.call("joy", "send_thank_you_note", {"event_id":"evt_8KQ2mZ","gift_id":"gft_7731","subject":"Thank you, Ana","message":"Ana, thank you for the stand mixer and for the gift to our honeymoon fund. The mixer has made bread every weekend since we got home. Maria and Tom"})
Node.js
const result = await cotlet.call('joy', 'send_thank_you_note', {"event_id":"evt_8KQ2mZ","gift_id":"gft_7731","subject":"Thank you, Ana","message":"Ana, thank you for the stand mixer and for the gift to our honeymoon fund. The mixer has made bread every weekend since we got home. Maria and Tom"});
CLI
cotlet call joy send_thank_you_note --data '{"event_id":"evt_8KQ2mZ","gift_id":"gft_7731","subject":"Thank you, Ana","message":"Ana, thank you for the stand mixer and for the gift to our honeymoon fund. The mixer has made bread every weekend since we got home. Maria and Tom"}'

Example response

{
  "gift_id": "gft_7731",
  "to": "Ana Lopez",
  "status": "sent",
  "thank_you_sent": true
}