# Joy API

> Every Joy endpoint on Cotlet: inputs, JSON Schema, cURL, Python and Node.js examples and an example response for each call.

Source: https://cotlet.dev/docs/api/joy

Docs sections: [Get started](https://cotlet.dev/docs.md) · [REST API](https://cotlet.dev/docs/api.md) · [MCP](https://cotlet.dev/docs/mcp.md) · [SDKs & CLI](https://cotlet.dev/docs/sdks.md) · [Integrations](https://cotlet.dev/docs/integrations.md)

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: https://cotlet.dev/integrations/joy-api-mcp-server

## 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. |

## List events

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

Access: read.

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**

```bash
curl -X POST https://cotlet.dev/api/v1/joy/list_events \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("joy", "list_events")
```

**Node.js**

```js
const result = await cotlet.call('joy', 'list_events');
```

**CLI**

```bash
cotlet call joy list_events
```

### Example response

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

## List guests

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

Access: read.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |
| `rsvp` | enum | no | all, attending, declined or no_response. Default: all. |
| `tag` | string | no | Only guests with this guest tag. |
| `search` | string | no | Match on guest name or email. |
| `limit` | integer | no | 1 to 500. Default: 100. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "list_guests", {"event_id":"evt_8KQ2mZ","rsvp":"attending","tag":"Reception","limit":500})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'list_guests', {"event_id":"evt_8KQ2mZ","rsvp":"attending","tag":"Reception","limit":500});
```

**CLI**

```bash
cotlet call joy list_guests --data '{"event_id":"evt_8KQ2mZ","rsvp":"attending","tag":"Reception","limit":500}'
```

### Example response

```json
{
  "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

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

Access: read.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |
| `guest_id` | string | yes | Guest ID from list_guests. |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "get_guest", {"event_id":"event_8c41d2","guest_id":"guest_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'get_guest', {"event_id":"event_8c41d2","guest_id":"guest_8c41d2"});
```

**CLI**

```bash
cotlet call joy get_guest --data '{"event_id":"event_8c41d2","guest_id":"guest_8c41d2"}'
```

### Example response

```json
{
  "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
    }
  ]
}
```

## Get RSVP summary

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

Access: read.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "get_rsvp_summary", {"event_id":"event_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'get_rsvp_summary', {"event_id":"event_8c41d2"});
```

**CLI**

```bash
cotlet call joy get_rsvp_summary --data '{"event_id":"event_8c41d2"}'
```

### Example response

```json
{
  "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
      }
    }
  ]
}
```

## List schedule

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

Access: read.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "list_schedule", {"event_id":"event_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'list_schedule', {"event_id":"event_8c41d2"});
```

**CLI**

```bash
cotlet call joy list_schedule --data '{"event_id":"event_8c41d2"}'
```

### Example response

```json
{
  "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"
    }
  ]
}
```

## List registry gifts

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

Access: read.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "list_registry_gifts", {"event_id":"event_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'list_registry_gifts', {"event_id":"event_8c41d2"});
```

**CLI**

```bash
cotlet call joy list_registry_gifts --data '{"event_id":"event_8c41d2"}'
```

### Example response

```json
{
  "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"
    }
  ]
}
```

## List received gifts

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

Access: read.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |
| `since` | date | no | Only gifts received on or after this date. |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "list_received_gifts", {"event_id":"event_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'list_received_gifts', {"event_id":"event_8c41d2"});
```

**CLI**

```bash
cotlet call joy list_received_gifts --data '{"event_id":"event_8c41d2"}'
```

### Example response

```json
{
  "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

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

Access: write.

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

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

### Request

**cURL**

```bash
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**

```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**

```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**

```bash
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

```json
{
  "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

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

Access: write.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |
| `guest_id` | string | yes | Guest ID from list_guests. |
| `fields` | object | yes | Any of first_name, last_name, email, phone, party, plus_ones, name_on_envelope, rsvp_answers ({question: answer or null to remove}). |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "update_guest", {"event_id":"event_8c41d2","guest_id":"guest_8c41d2","fields":"fields"})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'update_guest', {"event_id":"event_8c41d2","guest_id":"guest_8c41d2","fields":"fields"});
```

**CLI**

```bash
cotlet call joy update_guest --data '{"event_id":"event_8c41d2","guest_id":"guest_8c41d2","fields":"fields"}'
```

### Example response

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

## Assign guest tags

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

Access: write.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |
| `guest_ids` | string[] | yes | Guest IDs from list_guests. |
| `add` | string[] | no | Tags to assign. New tags are created. |
| `remove` | string[] | no | Tags to take off these guests. |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "assign_guest_tags", {"event_id":"event_8c41d2","guest_ids":["guest ids"]})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'assign_guest_tags', {"event_id":"event_8c41d2","guest_ids":["guest ids"]});
```

**CLI**

```bash
cotlet call joy assign_guest_tags --data '{"event_id":"event_8c41d2","guest_ids":["guest ids"]}'
```

### Example response

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

## Update schedule event

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

Access: write. Confirm: waits for the user's OK before it runs.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |
| `schedule_item_id` | string | yes | Schedule item ID from list_schedule. |
| `fields` | object | yes | Any of name, description, start, end, time_zone, venue, dress_code, privacy (everyone or specific_guests). |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "update_schedule_event", {"event_id":"event_8c41d2","schedule_item_id":"schedule_item_8c41d2","fields":"fields"})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'update_schedule_event', {"event_id":"event_8c41d2","schedule_item_id":"schedule_item_8c41d2","fields":"fields"});
```

**CLI**

```bash
cotlet call joy update_schedule_event --data '{"event_id":"event_8c41d2","schedule_item_id":"schedule_item_8c41d2","fields":"fields"}'
```

### Example response

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

## Add registry gift

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

Access: write.

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

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

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "add_registry_gift", {"event_id":"event_8c41d2","product_url":"https://example.com"})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'add_registry_gift', {"event_id":"event_8c41d2","product_url":"https://example.com"});
```

**CLI**

```bash
cotlet call joy add_registry_gift --data '{"event_id":"event_8c41d2","product_url":"https://example.com"}'
```

### Example response

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

## Send RSVP reminder

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

Access: write. Confirm: waits for the user's OK before it runs.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |
| `guest_ids` | string[] | no | Recipients. Default: guests with no response. |
| `delivery` | enum | no | email, text or both. Text needs Messaging Plus. Default: email. |
| `subject` | string | no | Email subject line. |
| `message` | string | no | Message body. Default: the Joy reminder text. |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "send_rsvp_reminder", {"event_id":"evt_8KQ2mZ","delivery":"email","subject":"Two weeks left to RSVP"})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'send_rsvp_reminder', {"event_id":"evt_8KQ2mZ","delivery":"email","subject":"Two weeks left to RSVP"});
```

**CLI**

```bash
cotlet call joy send_rsvp_reminder --data '{"event_id":"evt_8KQ2mZ","delivery":"email","subject":"Two weeks left to RSVP"}'
```

### Example response

```json
{
  "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

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

Access: write. Confirm: waits for the user's OK before it runs.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |
| `guest_ids` | string[] | no | Recipients by guest ID. |
| `tags` | string[] | no | Recipients by guest tag. Use guest_ids or tags. |
| `subject` | string | yes | Email subject line. |
| `message` | string | yes | Message body. |
| `send_at` | datetime | no | Schedule for later, ISO 8601. Needs Messaging Plus. Default: now. |

### Request

**cURL**

```bash
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**

```python
result = client.call("joy", "send_email_message", {"event_id":"event_8c41d2","subject":"subject","message":"message"})
```

**Node.js**

```js
const result = await cotlet.call('joy', 'send_email_message', {"event_id":"event_8c41d2","subject":"subject","message":"message"});
```

**CLI**

```bash
cotlet call joy send_email_message --data '{"event_id":"event_8c41d2","subject":"subject","message":"message"}'
```

### Example response

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

## Send thank-you note

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

Access: write. Confirm: waits for the user's OK before it runs.

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

| Name | Type | Required | Description |
|---|---|---|---|
| `event_id` | string | yes | Event ID from list_events. |
| `gift_id` | string | yes | Gift ID from list_received_gifts. |
| `message` | string | yes | Thank-you text. |
| `subject` | string | no | Email subject line. |

### Request

**cURL**

```bash
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**

```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**

```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**

```bash
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

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