# List all active brands
Source: https://developer.ongoody.com/api-reference/brands/list-all-active-brands
GET /v1/brands
# List all active cards
Source: https://developer.ongoody.com/api-reference/cards/list-all-active-cards
GET /v1/cards
# List all collections
Source: https://developer.ongoody.com/api-reference/collections/list-all-collections
GET /v1/collections
Retrieve all collections in all workspaces you have access to. Automation API only.
To filter to only published collections, use querystring `?published=true`.
# Retrieve a collection
Source: https://developer.ongoody.com/api-reference/collections/retrieve-a-collection
GET /v1/collections/{id}
Retrieve a collection's details. Automation API only.
To access the products in a collection, traverse:
collection > published\_version > collection\_categories > collection\_products > product.
# Create a commerce user payment method
Source: https://developer.ongoody.com/api-reference/commerce-user-payment-methods/create-a-commerce-user-payment-method
POST /v1/commerce_user_payment_methods
Only for the Commerce API.
Apps using the Commerce API can embed Goody's credit card form into their application to allow the app's end users to enter their credit card to save a payment method. Users can then use that payment method to pay for orders.
Call this endpoint to create a payment method associated with a commerce user; provide the user ID as `commerce_end_user_id`. Then, use the returned payment method `id` as the `payment_method_id` in the [Create an Order Batch](/api-reference/order-batches/create-an-order-batch) endpoint along with the `commerce_end_user_id`.
For more information, refer to [Embedded Payment Form](/commerce-api/embedded-payment-form).
# List all order activities
Source: https://developer.ongoody.com/api-reference/order-activities/list-all-order-activities
GET /v1/order_activities
# Calculate the price for an order batch
Source: https://developer.ongoody.com/api-reference/order-batches/calculate-the-price-for-an-order-batch
POST /v1/order_batches/price
You can calculate the total price for an order batch before you create it, given a cart, recipients, and send method. To use a specific address, pass the `direct_send` send method.
# Create an order batch
Source: https://developer.ongoody.com/api-reference/order-batches/create-an-order-batch
POST /v1/order_batches
For a guide on how to create an order batch, see the Getting Started guide for the [Automation API Getting Started](/automation-api/create-an-order) guide or the [Commerce API Getting Started](/commerce-api/create-an-order) guide.
### Order batches with 10 or fewer recipients
Order batches with 10 or fewer recipients are created synchronously, and the returned `status` field will be `completed`. The orders and order links are available immediately inside the `orders_preview` field (which returns the first 10 orders).
### Order batches with more than 10 recipients
Order batches with more than 10 recipients are created asynchronously, and the order batch will have a `status` of `pending`. The orders and gift links won't be available until the order batch is finished processing synchronously. You can check the status of the order batch by calling the [`/order_batches/:id`](retrieve-an-order-batch) endpoint, or by receiving a webhook notification on the [`order_batch.completed`](/webhooks/events/order_batch.completed) event.
Once an order batch is created, you can access all of the orders by calling the `/order_batches/:id/orders` endpoint, where you can paginate through the list of orders. If your use case always sends 10 or fewer orders at a time, you can just use the `orders_preview` field on the order batch which gives you the first 10 orders.
# List all order batches
Source: https://developer.ongoody.com/api-reference/order-batches/list-all-order-batches
GET /v1/order_batches
# Retrieve an order batch
Source: https://developer.ongoody.com/api-reference/order-batches/retrieve-an-order-batch
GET /v1/order_batches/{id}
# Retrieve orders for an order batch
Source: https://developer.ongoody.com/api-reference/order-batches/retrieve-orders-for-an-order-batch
GET /v1/order_batches/{id}/orders
# Retrieve recipients for an order batch
Source: https://developer.ongoody.com/api-reference/order-batches/retrieve-recipients-for-an-order-batch
GET /v1/order_batches/{id}/recipients
# Cancel an order
Source: https://developer.ongoody.com/api-reference/orders/cancel-an-order
POST /v1/orders/{id}/cancel
# List all orders
Source: https://developer.ongoody.com/api-reference/orders/list-all-orders
GET /v1/orders
# Retrieve an order
Source: https://developer.ongoody.com/api-reference/orders/retrieve-an-order
GET /v1/orders/{id}
# Update expiration for an order
Source: https://developer.ongoody.com/api-reference/orders/update-expiration-for-an-order
POST /v1/orders/{id}/update_expiration
# List all payment methods
Source: https://developer.ongoody.com/api-reference/payment-methods/list-all-payment-methods
GET /v1/payment_methods
# List all active products
Source: https://developer.ongoody.com/api-reference/products/list-all-active-products
GET /v1/products
# Retrieve a product
Source: https://developer.ongoody.com/api-reference/products/retrieve-a-product
GET /v1/products/{id}
# Retrieve current user
Source: https://developer.ongoody.com/api-reference/retrieve-current-user
GET /v1/me
# Brand
Source: https://developer.ongoody.com/api-reference/schemas/brand
# Cart
Source: https://developer.ongoody.com/api-reference/schemas/cart
# CartInput
Source: https://developer.ongoody.com/api-reference/schemas/cartinput
# CartItem
Source: https://developer.ongoody.com/api-reference/schemas/cartitem
# CartItemInput
Source: https://developer.ongoody.com/api-reference/schemas/cartiteminput
# Error
Source: https://developer.ongoody.com/api-reference/schemas/error
# Image
Source: https://developer.ongoody.com/api-reference/schemas/image
# ListMeta
Source: https://developer.ongoody.com/api-reference/schemas/listmeta
# MailingAddress
Source: https://developer.ongoody.com/api-reference/schemas/mailingaddress
# Me
Source: https://developer.ongoody.com/api-reference/schemas/me
# Order
Source: https://developer.ongoody.com/api-reference/schemas/order
# OrderBatch
Source: https://developer.ongoody.com/api-reference/schemas/orderbatch
# OrderBatchInput
Source: https://developer.ongoody.com/api-reference/schemas/orderbatchinput
# OrderBatchRecipient
Source: https://developer.ongoody.com/api-reference/schemas/orderbatchrecipient
# OrderBatchSendMethod
Source: https://developer.ongoody.com/api-reference/schemas/orderbatchsendmethod
# OrderBatchSendStatus
Source: https://developer.ongoody.com/api-reference/schemas/orderbatchsendstatus
# OrderStatus
Source: https://developer.ongoody.com/api-reference/schemas/orderstatus
# Product
Source: https://developer.ongoody.com/api-reference/schemas/product
# ProductImage
Source: https://developer.ongoody.com/api-reference/schemas/productimage
# ProductVariant
Source: https://developer.ongoody.com/api-reference/schemas/productvariant
# RecipientInput
Source: https://developer.ongoody.com/api-reference/schemas/recipientinput
# Sender
Source: https://developer.ongoody.com/api-reference/schemas/sender
# Shipment
Source: https://developer.ongoody.com/api-reference/schemas/shipment
# List all workspaces
Source: https://developer.ongoody.com/api-reference/workspaces/list-all-workspaces
GET /v1/workspaces
# Automation API: Access the product catalog
Source: https://developer.ongoody.com/automation-api/access-the-catalog
You don't need to access the product catalog to specify what product you want to send. You can find the product ID by enabling [Developer Mode](/introduction/developer-mode) on Goody's website, or you can use the product's URL in the create order batch payload.
However, you can still access the product catalog if your use case can benefit from it. To access the product catalog, make a request (using your API key) to:
```
GET https://api.sandbox.ongoody.com/v1/products
Authorization: Bearer YOUR_GOODY_API_KEY
```
This endpoint returns the products that are available to send. The list of products can change as products are added and removed. The product object includes the brand name, price, brand shipping price, copy like subtitles, variant information, and product imagery.
You can paginate the product catalog by passing the `?page=` query parameter (the first page is `1`) and the `?per_page` query parameter (maximum `100`) to paginate through the list.
An example response might look like:
```json theme={null}
{
"data": [
{
"id": "5821e50e-6a56-4144-bca2-3f41fbd699c0",
"name": "Dozen Cookies",
"brand": {
"id": "30e28df2-730e-4763-81bc-d528f0ac6a2a",
"name": "Cookie Company",
"shipping_price": 1000
},
"subtitle": null,
"subtitle_short": null,
"recipient_description": "",
"variants_label": "Flavor",
"variants_num_selectable": 1,
"variants": [
{
"id": "5eab976a-614c-41cf-a46f-8eca96748fbf",
"name": "Chocolate Chip",
"subtitle": "Classic chocolate chip.",
"image_large": {
"url": "https://assets.ongoody.com/image.png",
"width": 1000,
"height": 500
}
},
{
"id": "95592e6d-0bd3-49e9-ad2b-0112232e31d6",
"name": "Oatmeal",
"subtitle": "Delicious oatmeal.",
"image_large": {
"url": "https://assets.ongoody.com/image.png",
"width": 1000,
"height": 500
}
},
{
"id": "fe10b3ac-02b4-4b4e-b5cc-d16303fb1091",
"name": "Sugar",
"subtitle": "Tasty sugar.",
"image_large": {
"url": "https://assets.ongoody.com/image.png",
"width": 1000,
"height": 500
}
}
],
"images": [
{
"id": "4fdc04a5-35e8-4789-84b9-c84259918f36",
"image_large": {
"url": "https://assets.ongoody.com/image.png",
"width": 1000,
"height": 500
}
}
],
"price": 1000,
"price_is_variable": false,
"restricted_states": []
}
],
"list_meta": {
"total_count": 1
}
}
```
For more information, including the schema of the Product object, check out the [API reference for the products endpoint](/api-reference/products/list-all-active-products).
# Automation API: Authentication
Source: https://developer.ongoody.com/automation-api/authentication
Production and Sandbox accounts are separate, and you have different API keys for each environment for isolation.
## Create a Goody for Business account
To sign up for a Goody for Business account in production or sandbox, go to the corresponding link:
| Environment | API Keys Link |
| -------------- | ------------------------------------------------------------------------------------------ |
| **Production** | [https://www.ongoody.com/business/signup](https://www.ongoody.com/business/signup) |
| **Sandbox** | [https://sandbox.ongoody.com/business/signup](https://sandbox.ongoody.com/business/signup) |
## Create an API Key
Once you're signed up, to create an API key, go to the top-right account menu, and click **Account**, and then click the **API Keys** sub-menu. Or, use the links below.
| Environment | API Keys Link |
| -------------- | ------------------------------------------------------------------------------------------------------ |
| **Production** | [https://www.ongoody.com/plus/account/api-keys](https://www.ongoody.com/plus/account/api-keys) |
| **Sandbox** | [https://sandbox.ongoody.com/plus/account/api-keys](https://sandbox.ongoody.com/plus/account/api-keys) |
## Base URL
The base URL of the API depends on the environment you're using:
| Environment | API Keys Link |
| -------------- | ------------------------------------------------------------------ |
| **Production** | [https://api.ongoody.com](https://api.ongoody.com) |
| **Sandbox** | [https://api.sandbox.ongoody.com](https://api.sandbox.ongoody.com) |
## Authentication header
This API uses bearer authentication. Send your API key in the `Authorization` HTTP header preceded by `Bearer` :
```
Authorization: Bearer YOUR_GOODY_API_KEY
```
API keys are scoped to users, and any orders created with your API key show up in your Goody for Business account like orders created from the website. You can track them on the Track page.
## Calling `/me`
To check that you're authenticated, you can send a request to the `/me` endpoint:
```
GET https://api.sandbox.ongoody.com/v1/me
Authorization: Bearer YOUR_GOODY_API_KEY
```
And it should respond with:
```json theme={null}
{
"email": "example-email@ongoody.com"
}
```
# Automation API: Create an order
Source: https://developer.ongoody.com/automation-api/create-an-order
## Send a gift
One of the ways you can use the Automation API is to send a gift. When you send a gift, you can create an order without an address, and you'll get a gift link that you can send to the recipient. The recipient can then enter their own address and accept the gift.
To send a gift, you'll want to create what we call an **order batch**. Since Goody lets you send gifts to multiple recipients at once, the "container" for all gifts is an order batch.
When you create an order batch, you provide a list of recipients. Each recipient in the gift batch will have an order created for them.
If you're sending a single gift at a time, you'll also be creating an order batch – just with one recipient. Think of it as sending an email: whether you're sending an email to one recipient or multiple, you're still composing the same email.
The endpoint to create a gift batch is [POST /v1/order\_batches](/api-reference/order-batches/create-an-order-batch).
Let's take a look at an example payload for creating an order batch:
```json theme={null}
{
"from_name": "John",
"send_method": "link_multiple_custom_list",
"recipients": [
{
"first_name": "Alena",
"last_name": "Kenter",
"email": "alena@ongoody.com"
}
],
"cart": {
"items": [
{
"product_id": "9abf2d67-e4f3-4d43-9142-4a1f0d10aaa0",
"quantity": 1
}
]
},
"card_id": "ff957080-192d-4032-b4c5-fbb057141c4b",
"message": "Thank you!"
}
```
These fields are required in each order batch:
| Field | Meaning |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `from_name` | **Who is the gift from?** This name is the "from" when the gift is displayed. |
| `send_method` | **How do you want to send this gift?** Do you want Goody to send a gift notification email, or just get a link to send on your own? In this case, we're using `link_multiple_custom_list`, which means to get links only without sending an email. For more information, see the Send methods documentation page TK. |
| `recipients` | **Who is this gift going to?** If you only have one gift recipient, this array will just have one item. Only `first_name` is required (unless if you want us to send a gift email, in which case you'll also need to provide `email`). |
| `cart` | **What products do you want to send in your gift?** Each product you send is an item in the `cart.items` array. You can find Product IDs from the product catalog, or by using Developer Mode on the Goody website (TK). |
These fields are optional, but recommended:
| Field | Meaning |
| --------- | --------------------------------------------- |
| `card_id` | (optional) The ID of a digital greeting card. |
| `message` | (optional) A message to add to your gift. |
### Create order batch response
The response looks like:
```json theme={null}
{
"id": "f0903768-609c-4851-bc9a-c17ea245e120",
"send_status": "complete",
"from_name": "John",
"message": "Thank you!",
"orders_count": 1,
"orders_preview": [
{
"id": "a74adf4b-1837-43f5-8e51-f74803cd8832",
"status": "created",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"individual_gift_link": "https://gifts.ongoody.com/gift/gHBMKuXkiVgAFDyXx00h4XGs",
"card_id": "ff957080-192d-4032-b4c5-fbb057141c4b",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "f0903768-609c-4851-bc9a-c17ea245e120",
"cart": {
"id": "fad70b58-896e-4e11-b80b-d807f57e5e3d",
"items": [
{
"id": "0bc34fa6-d036-4300-a743-dec8eda7f2bd",
"quantity": 1,
"product": {
"id": "9abf2d67-e4f3-4d43-9142-4a1f0d10aaa0",
"name": "Cookies",
"brand": {
"id": "d8782dff-10b2-49ca-87ed-ed6c9d34e4bd",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15557426864@test.ongoody.com"
},
"workspace_id": "b99bf758-104f-4570-a3a9-bc59e64646b1",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "5NRQ9IKCVECOHFCUOZWJHTWW"
}
],
"recipients_count": 1,
"recipients_preview": [
{
"first_name": "Alena",
"last_name": "Kenter",
"email": "alena@ongoody.com"
}
],
"cart": {
"id": "fad70b58-896e-4e11-b80b-d807f57e5e3d",
"items": [
{
"id": "0bc34fa6-d036-4300-a743-dec8eda7f2bd",
"quantity": 1,
"product": {
"id": "9abf2d67-e4f3-4d43-9142-4a1f0d10aaa0",
"name": "Cookies",
"brand": {
"id": "d8782dff-10b2-49ca-87ed-ed6c9d34e4bd",
"name": "Cookie Company"
}
}
}
]
},
"is_scheduled_send": false,
"scheduled_send_on": null,
"expires_at": null,
"send_method": "link_multiple_custom_list",
"batch_name": "Alena Kenter",
"card_id": "ff957080-192d-4032-b4c5-fbb057141c4b",
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15557426864@test.ongoody.com"
},
"workspace_id": "b99bf758-104f-4570-a3a9-bc59e64646b1",
"workspace_name": "Test Team",
"reference_id": "XNYLJMW5JIFOFRM0PQIPNA56"
}
```
* **If you send an order batch with 10 or fewer recipients**, orders are processed right away, and you'll see that that `send_status` is `complete` and you'll receive the list of orders back in the `orders_preview` object.
* **If you send an order batch with more than 10 recipients**, creating orders happens asynchronously in the background, and you'll see that `send_status` is `pending`. You can hit the [`/order_batches/:id`](/api-reference/order-batches/retrieve-an-order-batch) endpoint to check the `send_status` for complete, or listen for the `order_batch.completed` webhook.
* The `orders_preview` endpoint only contains the first 10 orders. If you have more orders, you can paginate through all the orders using the [`/order_batches/:id/orders`](/api-reference/order-batches/retrieve-orders-for-an-order-batch) endpoint.
* **If you schedule an order batch for the future** using the `scheduled_send_on` parameter, the `send_status` will be `pending`, and `orders_preview` will be empty, until the scheduled send time, at which point the orders are created. Similarly to above, you can listen for the `order_batch.completed` webhook.
You can check the send\_status field to determine if your order batch is being asynchronously processed or is scheduled for the future (`send_status == pending`) or orders are ready (`send_status == complete`).
### The `orders_preview` field
The most important thing in the response is the order object. The `orders_preview` field displays the first 10 orders in your order batch. To determine the number of orders in the order batch, you can use the `orders_count` field.
```json theme={null}
"orders_count": 1,
"orders_preview": [
{
"id": "a74adf4b-1837-43f5-8e51-f74803cd8832",
"status": "created",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"individual_order_link": "https://gifts.ongoody.com/gift/gHBMKuXkiVgAFDyXx00h4XGs",
"card_id": "ff957080-192d-4032-b4c5-fbb057141c4b",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "f0903768-609c-4851-bc9a-c17ea245e120",
"cart": { ... },
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15557426864@test.ongoody.com"
},
"workspace_id": "b99bf758-104f-4570-a3a9-bc59e64646b1",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "5NRQ9IKCVECOHFCUOZWJHTWW"
},
]
```
If you always send single orders or fewer than 10 orders at once, great! You can use this array without having to make another request. But if you send more than 10 orders at once, you can also hit the `/order_batches/:id/orders` endpoint to paginate through the rest of your orders.
In the order object, there are a few fields to point out:
* `individual_gift_link` — This is the individual gift link for that recipient, which when opened goes directly to their gift. You can send this in an email or somewhere else so they can access their gift.
* `status` — This status is for the individual order itself. The list of order statuses can be viewed on the [order lifecycle guide](/introduction/order-lifecycle). You can set up webhooks to get notified on changes to the status.
* `amounts` — Contains the costs for this order, in cents.
Congratulations – you've sent a gift!
For more information on the order batch send endpoint, [visit the doc](/api-reference).
## Next steps
Now that you've sent your gift, you can now open the gift link and accept the gift to see what the experience looks like.
# Goody Automation API
Source: https://developer.ongoody.com/automation-api/overview
Goody for Business customers can use the Automation API to automate their gifting and sending. With the Automation API, you can programmatically create one-to-one or one-to-many gifts, retrieve information about orders, and get real-time webhook notifications on order events.
Some things you can build with the Automation API:
* **Trigger sending gifts on events in your CRM, HRIS, or another application.** Send a customer gift for client anniversaries, deals closed, and more.
* **Send Goody order information to other applications.** Trigger Slack messages on gift accepts, add tasks in your CRM when gifts are delivered, save order totals to a spreadsheet, and more.
## Getting started
In this guide, we'll walk through how to:
1. Set up an account on our sandbox environment
2. Obtain an API key
3. Send a gift
4. Set up webhooks for order events.
Let's start with setting up an account and authentication.
# Automation API: Retrieve order status
Source: https://developer.ongoody.com/automation-api/retrieve-order-status
## Get order
In most cases, you'll want to get information about an individual order. You can retrieve an order by calling the [GET /orders/:id](/api-reference/orders/retrieve-an-order) endpoint.
This will return all information about the order, in particular its status, such as notified, opened, shipped, delivered, etc. For more information on all of the available order statuses, visit the Order Lifecycle documentation page.
For more information about the other fields in the Order object, refer to the [Order schema](/api-reference/schemas/order).
## Cancel order
To cancel an order in created, notified, or opened status, call the [POST /orders/:id/cancel](/api-reference/orders/cancel-an-order) endpoint. For gifts that are in the accepted state or later, they are already processing; please contact Goody Support for these orders.
## Get order batch
You can retrieve an order batch by calling the [GET /order\_batches/:id](/api-reference/order-batches/retrieve-orders-for-an-order-batch) endpoint, or retrieve orders inside the order batch using the [GET /orders/:id/orders](/api-reference/order-batches/retrieve-orders-for-an-order-batch) endpoint.
For more information about the other fields in the OrderBatch object, refer to the [OrderBatch schema](/api-reference/schemas/orderbatch).
# Automation API: Webhooks
Source: https://developer.ongoody.com/automation-api/webhooks
Webhooks allow you to be notified when events happen on Goody orders and order batches. You can subscribe to all webhooks, or a subset of them. Webhooks are sent by the Svix platform.
In contrast to API keys (which can be created by anyone in the organization and are scoped to users), you must be an organization admin to set up and manage webhooks since they fire on every order and order batch in the organization.
## Set up webhooks
To set up webhooks, go to **Organization** on the top right, then **Automation API** in the sub-menu, or click the link for your environment:
| Environment | Webhooks Link |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Production** | [https://www.ongoody.com/plus/organization/api/automation](https://www.ongoody.com/plus/organization/api/automation) |
| **Sandbox** | [https://sandbox.ongoody.com/plus/organization/api/automation](https://sandbox.ongoody.com/plus/organization/api/automation) |
## Available webhooks
| Webhook | Description |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **[order\_batch.created](/webhooks/events/order_batch.created)** | When an order batch is newly created. The order batch could still be in process of sending, or scheduled for the future. |
| **[order\_batch.completed](/webhooks/events/order_batch.completed)** | When an order batch is fully processed and all orders have been created. |
| **[order.created](/webhooks/events/order.created)** | When an order is created and is ready to be opened. |
| **[order.gift\_opened](/webhooks/events/order.gift_opened)** | When a gift is opened by the recipient. |
| **[order.gift\_accepted](/webhooks/events/order.gift_accepted)** | When a gift has been accepted by the recipient. |
| **[order.thank\_you\_note\_added](/webhooks/events/order.thank_you_note_added)** | When a recipient adds a thank you note to a order after accepting it. |
| **[order.shipped](/webhooks/events/order.shipped)** | When an order starts shipping. If there are multiple shipments, this is called for the first. |
| **[order.delivered](/webhooks/events/order.delivered)** | When an order is fully delivered. If there are multiple shipments, this is called when all shipments are delivered. |
| **[order.canceled](/webhooks/events/order.canceled)** | When an order has been canceled. |
| **[order.refunded](/webhooks/events/order.refunded)** | When an order has been refunded. |
## Setting up a new webhook
Enter a URL to recieve webhooks in the **Endpoint URL** section.
You can leave **Message Filtering** blank to receive all events, or select specific events to receive.
## Webhook security
To ensure the integrity of the webhooks you receive, we recommend verifying the signatures of the webhooks you receive. Svix provides packages for multiple languages that make verifying signatures easy.
To see how, go to the [Webhook Security](/webhooks/webhook-security) page.
## Logs
You can view the logs for webhook delivery for each endpoint, and re-send any failed webhooks if needed.
# Automation API: Zapier
Source: https://developer.ongoody.com/automation-api/zapier
Create automations without code using Zapier workflows
Zapier allows you to connect Goody to more than 5,000+ apps to build automations without code.
Some things you can do with Zapier:
* Send a gift when a contact is added to a HubSpot list, a new row is added to a Google sheet, or other triggers
* Set up automatic rules for sending gifts for things like client anniversaries
* Send a Slack message, add to a spreadsheet, and more when a gift is opened, accepted, shipped, or delivered
Goody provides several triggers and actions that you can use to connect Goody to the other apps you use.
To get started, search for **Goody** when setting up an app as a trigger or action on Zapier.
Full documentation for Goody's Zapier app is available on Goody's help center.
Learn how to send a gift with Goody's Zapier app.
# Commerce API: Access the product catalog
Source: https://developer.ongoody.com/commerce-api/access-the-catalog
To access the product catalog, make a request (using your commerce API key) to:
```
GET https://api.sandbox.ongoody.com/v1/products
Authorization: Bearer YOUR_GOODY_COMMERCE_API_KEY
```
This endpoint returns the products that are available to send through the Commerce API. The list of products can change as products are added and removed. The product object includes the brand name, price, brand shipping price, copy like subtitles, variant information, and product imagery.
You can paginate the product catalog by passing the `?page=` query parameter (the first page is `1`) and the `?per_page` query parameter (maximum `100`) to paginate through the list.
An example response might look like:
```json theme={null}
{
"data": [
{
"id": "5821e50e-6a56-4144-bca2-3f41fbd699c0",
"name": "Dozen Cookies",
"brand": {
"id": "30e28df2-730e-4763-81bc-d528f0ac6a2a",
"name": "Cookie Company",
"shipping_price": 1000
},
"subtitle": null,
"subtitle_short": null,
"recipient_description": "",
"variants_label": "Flavor",
"variants_num_selectable": 1,
"variants": [
{
"id": "5eab976a-614c-41cf-a46f-8eca96748fbf",
"name": "Chocolate Chip",
"subtitle": "Classic chocolate chip.",
"image_large": {
"url": "https://assets.ongoody.com/image.png",
"width": 1000,
"height": 500
}
},
{
"id": "95592e6d-0bd3-49e9-ad2b-0112232e31d6",
"name": "Oatmeal",
"subtitle": "Delicious oatmeal.",
"image_large": {
"url": "https://assets.ongoody.com/image.png",
"width": 1000,
"height": 500
}
},
{
"id": "fe10b3ac-02b4-4b4e-b5cc-d16303fb1091",
"name": "Sugar",
"subtitle": "Tasty sugar.",
"image_large": {
"url": "https://assets.ongoody.com/image.png",
"width": 1000,
"height": 500
}
}
],
"images": [
{
"id": "4fdc04a5-35e8-4789-84b9-c84259918f36",
"image_large": {
"url": "https://assets.ongoody.com/image.png",
"width": 1000,
"height": 500
}
}
],
"price": 1000,
"price_is_variable": false,
"restricted_states": []
}
],
"list_meta": {
"total_count": 1
}
}
```
For more information, including the schema of the Product object, check out the [API reference for the products endpoint](/api-reference/products/list-all-active-products).
# Commerce API: Authentication
Source: https://developer.ongoody.com/commerce-api/authentication
Production and Sandbox accounts are separate, and you have different API keys for each environment for isolation.
## Create a Goody for Business account
To sign up for a Goody for Business account in production or sandbox, go to the corresponding link:
| Environment | API Keys link |
| -------------- | ------------------------------------------------------------------------------------------ |
| **Production** | [https://www.ongoody.com/business/signup](https://www.ongoody.com/business/signup) |
| **Sandbox** | [https://sandbox.ongoody.com/business/signup](https://sandbox.ongoody.com/business/signup) |
## Create a commerce app and API key
Once you're signed up, you'll need to create a commerce app and an API key. Next to your account button on the top right, click the **Organization** link, and then navigate to **Commerce API**.
| Environment | API Keys link |
| -------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Production** | [https://www.ongoody.com/plus/organization/api/commerce](https://www.ongoody.com/plus/organization/api/commerce) |
| **Sandbox** | [https://sandbox.ongoody.com/plus/organization/api/commerce](https://sandbox.ongoody.com/plus/organization/api/commerce) |
Start by setting a name for your commerce app, and click Create. Then, click **New API key** to generate an API key.
## Base URL
The base URL of the API depends on the environment you're using:
| Environment | Base URL |
| -------------- | ------------------------------------------------------------------ |
| **Production** | [https://api.ongoody.com](https://api.ongoody.com) |
| **Sandbox** | [https://api.sandbox.ongoody.com](https://api.sandbox.ongoody.com) |
## Authentication header
This API uses bearer authentication. Send your API key in the `Authorization` HTTP header preceded by `Bearer `:
```
Authorization: Bearer YOUR_GOODY_COMMERCE_API_KEY
```
## Calling `/me`
To check that you're authenticated, you can send a request to the `/me` endpoint:
```
GET https://api.sandbox.ongoody.com/v1/me
Authorization: Bearer YOUR_GOODY_COMMERCE_API_KEY
```
And it should respond with:
```json theme={null}
{
"public_app_id": "YOUR_PUBLIC_APP_ID"
}
```
# Commerce API: Create an order
Source: https://developer.ongoody.com/commerce-api/create-an-order
## Sending a gift
One of the ways you can use the Commerce API is to send a gift. When you send a gift, you can create an order without an address, and you'll get a gift link that you can send to the recipient. The recipient can then enter their own address and accept the gift.
To send a gift, you'll want to create what we call an **order batch**. Since Goody lets you send gifts to multiple recipients at once, the "container" for all gifts is an order batch.
When you create an order batch, you provide a list of recipients. Each recipient in the gift batch will have an order created for them.
If you're sending a single gift at a time, you'll also be creating an order batch – just with one recipient. Think of it as sending an email: whether you're sending an email to one recipient or multiple, you're still composing the same email.
The endpoint to create a gift batch is **[POST /v1/order\_batches](/api-reference/order-batches/create-an-order-batch)**:
```
POST https://api.sandbox.ongoody.com/v1/order_batches
Authorization: Bearer YOUR_GOODY_COMMERCE_API_KEY
```
Let's take a look at an example payload for creating an order batch:
```json theme={null}
{
"from_name": "John",
"send_method": "link_multiple_custom_list",
"recipients": [
{
"first_name": "Alena",
"last_name": "Kenter",
"email": "alena@ongoody.com"
}
],
"cart": {
"items": [
{
"product_id": "9abf2d67-e4f3-4d43-9142-4a1f0d10aaa0",
"quantity": 1
}
]
},
"payment_method_id": "COMMERCE_STORED_VALUE",
"card_id": "ff957080-192d-4032-b4c5-fbb057141c4b",
"message": "Thank you!",
}
```
These fields are required in each order batch:
| Field | Meaning |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `from_name` | **Who is the gift from?** This name is the "from" when the gift is displayed. |
| `send_method` | **How do you want to send this gift?** Do you want Goody to send a gift notification email, or just get a link to send on your own? In this case, we're using `link_multiple_custom_list`, which means to get links only without sending an email. For more information, see the Send methods documentation page TK. |
| `recipients` | **Who is this gift going to?** If you only have one gift recipient, this array will just have one item. Only `first_name` is required (unless if you want us to send a gift email, in which case you'll also need to provide `email`). |
| `cart` | **What products do you want to send in your gift?** Each product you send is an item in the `cart.items` array. You can find Product IDs from the product catalog, or by using [Developer Mode](/introduction/developer-mode) on the Goody website. |
| `payment_method_id` | **How do you want to pay for your order?** This is set to `COMMERCE_STORED_VALUE`, which is a special payment method for the Commerce API that gives you a drawdown account. In the sandbox, you have access to this account automatically. In production, you'll need to fund your account with Goody Support before using this. |
These fields are optional, but recommended:
| Field | Meaning |
| --------- | --------------------------------------------- |
| `card_id` | (optional) The ID of a digital greeting card. |
| `message` | (optional) A message to add to your gift. |
## Create order batch response
The response looks like:
```json theme={null}
{
"id": "f0903768-609c-4851-bc9a-c17ea245e120",
"send_status": "complete",
"from_name": "John",
"message": "Thank you!",
"orders_count": 1,
"orders_preview": [
{
"id": "a74adf4b-1837-43f5-8e51-f74803cd8832",
"status": "created",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"individual_gift_link": "https://gifts.ongoody.com/gift/gHBMKuXkiVgAFDyXx00h4XGs",
"card_id": "ff957080-192d-4032-b4c5-fbb057141c4b",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "f0903768-609c-4851-bc9a-c17ea245e120",
"cart": {
"id": "fad70b58-896e-4e11-b80b-d807f57e5e3d",
"items": [
{
"id": "0bc34fa6-d036-4300-a743-dec8eda7f2bd",
"quantity": 1,
"product": {
"id": "9abf2d67-e4f3-4d43-9142-4a1f0d10aaa0",
"name": "Cookies",
"brand": {
"id": "d8782dff-10b2-49ca-87ed-ed6c9d34e4bd",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15557426864@test.ongoody.com"
},
"workspace_id": "b99bf758-104f-4570-a3a9-bc59e64646b1",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "5NRQ9IKCVECOHFCUOZWJHTWW"
}
],
"recipients_count": 1,
"recipients_preview": [
{
"first_name": "Alena",
"last_name": "Kenter",
"email": "alena@ongoody.com"
}
],
"cart": {
"id": "fad70b58-896e-4e11-b80b-d807f57e5e3d",
"items": [
{
"id": "0bc34fa6-d036-4300-a743-dec8eda7f2bd",
"quantity": 1,
"product": {
"id": "9abf2d67-e4f3-4d43-9142-4a1f0d10aaa0",
"name": "Cookies",
"brand": {
"id": "d8782dff-10b2-49ca-87ed-ed6c9d34e4bd",
"name": "Cookie Company"
}
}
}
]
},
"is_scheduled_send": false,
"scheduled_send_on": null,
"expires_at": null,
"send_method": "link_multiple_custom_list",
"batch_name": "Alena Kenter",
"card_id": "ff957080-192d-4032-b4c5-fbb057141c4b",
"sender": {
"first_name": "Commerce",
"last_name": "User",
"email": "15557426864@ongoody.com"
},
"workspace_id": "b99bf758-104f-4570-a3a9-bc59e64646b1",
"workspace_name": "Test Team",
"reference_id": "XNYLJMW5JIFOFRM0PQIPNA56"
}
```
* **If you send an order batch with 10 or fewer recipients**, orders are processed right away, and you'll see that that `send_status` is `complete` and you'll receive the list of orders back in the `orders_preview` object.
* **If you send an order batch with more than 10 recipients**, creating orders happens asynchronously in the background, and you'll see that `send_status` is `pending`. You can hit the [`/order_batches/:id`](/api-reference/order-batches/retrieve-an-order-batch) endpoint to check the `send_status` for `complete`, or listen for the `order_batch.completed` webhook.
* The `orders_preview` endpoint only contains the first 10 orders. If you have more orders, you can paginate through all the orders using the [`/order_batches/:id/orders`](/api-reference/order-batches/retrieve-orders-for-an-order-batch) endpoint.
* **If you schedule an order batch for the future** using the `scheduled_send_on` parameter, the `send_status` will be `pending`, and `orders_preview` will be empty, until the scheduled send time, at which point the orders are created. Similarly to above, you can listen for the `order_batch.completed` webhook.
You can check the `send_status` field to determine if your order batch is being asynchronously processed or is scheduled for the future (`send_status == pending`) or orders are ready (`send_status == complete`).
### The `orders_preview` field
The most important thing in the response is the order object. The `orders_preview` field displays the first 10 orders in your order batch. To determine the number of orders in the order batch, you can use the `orders_count` field.
```json theme={null}
"orders_count": 1,
"orders_preview": [
{
"id": "a74adf4b-1837-43f5-8e51-f74803cd8832",
"status": "created",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"individual_order_link": "https://gifts.ongoody.com/gift/gHBMKuXkiVgAFDyXx00h4XGs",
"card_id": "ff957080-192d-4032-b4c5-fbb057141c4b",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "f0903768-609c-4851-bc9a-c17ea245e120",
"cart": { ... },
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15557426864@test.ongoody.com"
},
"workspace_id": "b99bf758-104f-4570-a3a9-bc59e64646b1",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "5NRQ9IKCVECOHFCUOZWJHTWW"
},
]
```
If you always send single orders or fewer than 10 orders at once, great! You can use this array without having to make another request. But if you send more than 10 orders at once, you can also hit the [`/order_batches/:id/orders`](../../goody-api-openapi.json/paths/~1v1~1order_batches~1\{id}~1orders) endpoint to paginate through the rest of your orders.
In the order object, there are a few fields to point out:
* `individual_gift_link` — This is the individual gift link for that recipient, which when opened goes directly to their gift. You can send this in an email or somewhere else so they can access their gift.
* `status` — This status is for the individual order itself. The list of order statuses can be viewed on the [order lifecycle guide](/introduction/order-lifecycle). You can set up webhooks to get notified on changes to the status.
* `amounts` — Contains the costs for this order, in cents.
Congratulations – you've sent a gift!
For more information on the order batch send endpoint, [visit the doc](/api-reference/~1v1~1order_batches).
## Next steps
Now that you've sent your gift, you can now open the gift link and accept the gift to see what the experience looks like.
# Embedded Payment Form
Source: https://developer.ongoody.com/commerce-api/embedded-payment-form
Embed Goody’s credit card form into your application to sell products without processing payment.
You can embed Goody's credit card form into your app to allow users to enter their credit card details directly into Goody's payment form. You can control virtually all of the styling of the payment form.
## How it works
1. Embed Goody's payment form using our pre-built code sample, or build your own UI. Goody's payment form uses tokenization from [Very Good Security](https://www.verygoodsecurity.com/), the leader in PCI-compliant card tokenization, so your servers never touch any sensitive credit card details.
2. After your user enters their payment information and billing address, the payment form will tokenize the card data, save the data to Goody's server, and return an `interim_card_key`. This is a key that identifies a temporary record of the card information that can be used to create a payment method.
3. Call Goody's [POST /commerce\_user\_payment\_methods](/api-reference/commerce-user-payment-methods/create-a-commerce-user-payment-method) endpoint with the `interim_card_key`, cardholder name and billing address, and the `commerce_end_user_id`, the user ID of your app's user to associate this payment method with. You'll receive an `id` of a payment method back.
4. [Create an order batch](/api-reference/order-batches/create-an-order-batch) by passing the `payment_method_id` and the `commerce_end_user_id` that the payment method belongs to.
5. When the order batch is paid for, the payment will be processed to the end user's credit card.
## Code samples
We're here to help you integrate the embedded payment form. Contact us by clicking the "Apply now" button on the [Goody API](https://www.ongoody.com/business/gift-api) homepage or contact us at [support@ongoody.com](mailto:support@ongoody.com).
See the source code for our example app with a Next.js frontend and a Python FastAPI backend.
See our example app in action.
## Variables
| | Sandbox | Production |
| --------------------------- | ------------------------- | ---------------------------- |
| **GOODY\_VGS\_VAULT\_ID** | `tntfizwd8io` | `tnt4fsnx8xx` |
| **GOODY\_VGS\_ENVIRONMENT** | `sandbox` | `live` |
| **GOODY\_VGS\_CNAME** | `vgs-sandbox.ongoody.com` | `vgs-production.ongoody.com` |
# Goody Commerce API
Source: https://developer.ongoody.com/commerce-api/overview
Sell physical products in your app without handling inventory, vendor partnerships, or logistics, and earn a revenue share on orders.
* **Access our product catalog** — We've built partnerships and revenue share agreements to carry brands like Brooklinen, Apple, MALIN+GOETZ, Levain Bakery, Bose, and more, so you don't have to. Access our product catalog with full product imagery and descriptions.
* **Sell physical products in your app** — Display our full catalog or curate your own selection. Programmatically create orders through the Commerce API.
* **Send gifts without an address** — Use our gifting flow to create a gift without an address. Generate a gift link that a recipient can use to accept their gift, swap for another gift, select personalized options like color or size, and more.
* **Ship orders directly to an address** — If you know the address, we support that too. Just submit an API request – we handle the logistics and notify you when it's delivered.
(Revenue share requires an agreement. Please contact our business development team before you go live.)
## Payments
The Commerce API is flexible on how to collect payments from end customers and how we pay the revenue share:
| Method | Description |
| ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Partner app collects payment** | If you want to capture payment information or already have customer cards on file, you can process payments yourself. We set up a prefunded payment account for you on Goody. Once an order is placed with Goody, the transaction is paid for (with revshare credited) through the prefunded account. |
| **Partner app passes credit card information** | If you want to capture payment information or already have customer cards on file, but you want us to process the payment, you can send customer credit card details to our secure payment environment in Stripe. We will process the payment, and record revenue share and pay the revshare via bank transfer. |
| **Goody captures credit card information** | If you don't want to capture payment information, we can provide a secure Stripe payment form for end customers. We will process the payment, and record revenue share and pay the revshare via bank transfer. |
## Getting started
In this guide, we'll walk through how to:
1. Set up an account on our sandbox environment
2. Obtain an API key
3. Send a gift
4. Set up webhooks for order events.
Let's start with setting up an account and authentication.
# Commerce API: Payment
Source: https://developer.ongoody.com/commerce-api/payment
The Commerce API supports several payment modes:
* [Stored Value](#stored-value)
* [Embedded Payment Form](#embedded-payment-form)
* [Tokenized Payment](#tokenized-payment)
## Stored Value
The Stored Value payment mode is typically used when you capture payment on your own platform from your customer.
It relies on a stored value balance deposited with Goody. Revenue share is credited back to the same account, so no additional revenue share reconciliation is required.
1. Create an order batch with `payment_method_id` set to `COMMERCE_STORED_VALUE`.
2. Capture payment from your customer on your own platform.
3. Once the order is accepted, the cost of the order will be deducted from your stored value account.
4. Then, the revenue share will be paid into the stored value account as a separate transaction, so it can be easily separated out in your reports.
Stored Value in the sandbox is test money and can be used freely. If you want to set up stored value in the sandbox, contact your partnerships manager or [support@ongoody.com](mailto:support@ongoody.com) and we'll add some money into your account.
To deposit stored value in production, contact your partnerships manager or [support@ongoody.com](mailto:support@ongoody.com).
## Embedded Payment Form
You can embed Goody's credit card form into your app to allow users to enter their credit card details directly into Goody's payment form. This allows you to sell products without processing payment; all payments are processed by Goody.
You can control virtually all of the styling of the payment form. For more information, see [Embedded Payment Form](/commerce-api/embedded-payment-form).
## Tokenized Payment
Tokenized payment is available for approved partners. It will allow you to pass credit card details directly from your own platform to Goody's payment processor. Please contact us directly if you have a use case for this.
## Other payment types
If you have a unique use case, contact us at [support@ongoody.com](mailto:support@ongoody.com).
# Commerce API: Retrieve order status
Source: https://developer.ongoody.com/commerce-api/retrieve-order-status
## Get order
In most cases, you'll want to get information about an individual order. You can retrieve an order by calling the [GET /orders/:id](/api-reference/orders/retrieve-an-order) endpoint.
This will return all information about the order, in particular its status, such as `notified`, `opened`, `shipped`, `delivered`, etc. For more information on all of the available order statuses, visit the [Order Lifecycle](/introduction/order-lifecycle) documentation page.
For more information about the other fields in the Order object, refer to the [Order schema](/api-reference/schemas/order).
## Cancel order
To cancel an order in `created`, `notified`, or `opened` status, call the [POST /orders/:id/cancel](/api-reference/orders/cancel-an-order) endpoint. For gifts that are in the `accepted` state or later, they are already processing; please contact Goody Support for these orders.
## Get order batch
You can retrieve an order batch by calling the [GET /order\_batches/:id](/api-reference/orders/retrieve-an-order) endpoint, or retrieve orders inside the order batch using the [GET /orders/:id/orders](/api-reference/order-batches/retrieve-orders-for-an-order-batch) endpoint.
For more information about the other fields in the OrderBatch object, refer to the [OrderBatch schema](/api-reference/schemas/orderbatch).
# Commerce API: Webhooks
Source: https://developer.ongoody.com/commerce-api/webhooks
Webhooks allow you to be notified when events happen on Goody orders and order batches. You can subscribe to all webhooks, or a subset of them. Webhooks are sent by the Svix platform.
## Set up webhooks
To set up webhooks, go to **Organization** on the top right, then **Commerce API** in the sub-menu, or click the link for your environment:
| Environment | Webhooks link |
| -------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Production** | [https://www.ongoody.com/plus/organization/api/commerce](https://www.ongoody.com/plus/organization/api/commerce) |
| **Sandbox** | [https://sandbox.ongoody.com/plus/organization/api/commerce](https://sandbox.ongoody.com/plus/organization/api/commerce) |
Then, click the commerce app you have set up.
## Available webhooks
| Webhook | Description |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **[order\_batch.created](/webhooks/events/order_batch.created)** | When an order batch is newly created. The order batch could still be in process of sending, or scheduled for the future. |
| **[order\_batch.completed](/webhooks/events/order_batch.completed)** | When an order batch is fully processed and all orders have been created. |
| **[order.created](/webhooks/events/order.created)** | When an order is created and is ready to be opened. |
| **[order.gift\_opened](/webhooks/events/order.gift_opened)** | When a gift is opened by the recipient. |
| **[order.gift\_accepted](/webhooks/events/order.gift_accepted)** | When a gift has been accepted by the recipient. |
| **[order.thank\_you\_note\_added](/webhooks/events/order.thank_you_note_added)** | When a recipient adds a thank you note to a order after accepting it. |
| **[order.shipped](/webhooks/events/order.shipped)** | When an order starts shipping. If there are multiple shipments, this is called for the first. |
| **[order.delivered](/webhooks/events/order.delivered)** | When an order is fully delivered. If there are multiple shipments, this is called when all shipments are delivered. |
| **[order.canceled](/webhooks/events/order.canceled)** | When an order has been canceled. |
| **[order.refunded](/webhooks/events/order.refunded)** | When an order has been refunded. |
## Setting up a new webhook
Enter a URL to recieve webhooks in the **Endpoint URL** section.
You can leave **Message Filtering** blank to receive all events, or select specific events to receive.
## Webhook security
To ensure the integrity of the webhooks you receive, we recommend verifying the signatures of the webhooks you receive. Svix provides packages for multiple languages that make verifying signatures easy.
To see how, go to the [Webhook Security](/webhooks/webhook-security) page.
## Logs
You can view the logs for webhook delivery for each endpoint, and re-send any failed webhooks if needed.
# Developer mode
Source: https://developer.ongoody.com/introduction/developer-mode
Enable Developer Mode on the Goody website to get product IDs and card IDs.
You can use Developer Mode on the Goody website to:
* Find product IDs to add to a create order batch payload
* Find the ID of digital greeting cards to add to a create order batch payload
* Obtain a cart payload from the contents of your Goody cart
## Enable Developer Mode
1. Go to your Account menu by clicking the user icon on the top-left of the Goody website, and then click **My Account**.
2. Click the **API Keys** menu item on the account sub-menu.
3. Under **Developer Mode**, click **Enable developer mode**.
## Find product IDs
When clicking into a product page with Developer Mode enabled, the Product ID is displayed below the product name.
Some products don't have dedicated product pages. For those products, the product ID is located at the bottom of the brand window.
## Find card IDs
Go to the **Send** page and click the **Select card** button, which might be **Edit card** if you've already selected a card.
Card IDs are displayed below the card image.
## Get cart payload
Once you've added products to your cart, you can click the bag icon at the top right to open your cart. The JSON cart payload for the items you've selected is displayed at the bottom of the cart.
# Order lifecycle
Source: https://developer.ongoody.com/introduction/order-lifecycle
## Orders
The status for an order can be found on the `status` field.
| Status | Meaning |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `created` | The gift has been created. |
| `notified` | Notifications (e.g. email or text) have been sent for this order, if requested. If no notifications are requested, orders will still move to this state without sending notifications. |
| `opened` | For gift orders: the recipient has opened a gift. |
| `accepted` | For gift orders: the recipient has accepted the gift. For other orders: the order has been accepted for processing. |
| `pending_payment` | The order is awaiting payment. If a payment method has been specified, it will be processed at this stage. |
| `paid` | The order has been paid for and is being prepared for shipment. |
| `shipped` | The order has shipped. If the order has multiple shipments, it will enter this state when the first shipment starts moving. |
| `delivered` | The order has been delivered. If the order has multiple shipments, it will enter this state when all shipments have been delivered. |
| `failed` | The order has been canceled. This status will show up if you cancel an order using the cancel order endpoint. |
## Order batches
Order batches are collections of orders. The order batch's `send_status` displays the status of the order batch.
| Status | Meaning |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `pending` | For non-scheduled order batches, the order batch is being processed to create orders for each recipient. For scheduled order batches, the order batch is waiting for the scheduled time to send. |
| `complete` | The order batch has been created and all orders have been created for all recipients. |
## Testing shipped and delivered statuses, and refunds
In the sandbox only, we provide some *magic words* for testing `shipped` and `delivered` orders. When you enter a specific from name, the order will be moved to shipped or delivered after it's accepted. Here's how to use it:
1. Create the order batch with `from_name` set to `[shipped]` or `[delivered]`.
2. Open the gift link and accept the gift.
3. Shortly after the gift is accepted, the order will move to Shipped or Delivered, depending on the magic word you use.
To test the refund webhook, you can also use the magic word `[refunded]` by creating an order batch with that `from_name`. This will cause the order to be refunded after it's accepted.
# Goody for developers
Source: https://developer.ongoody.com/introduction/overview
Send physical products and gifts programmatically with the Goody API, or gift directly from Claude and other AI assistants with the Goody MCP server.
Goody lets you send gifts and physical products programmatically — no mailing address required.
* **Send gifts without an address**. Generate a gift link where the recipient can view the gift, swap it for something else, and enter their own address.
* **Ship physical products to an address**. If you already have an address, Goody ships the product and handles all the logistics.
There are two ways to build on Goody:
## The API
Programmatic gifting and commerce over a REST API.
Sell physical products in your app without handling inventory, partnerships, or logistics. Access our catalog, gift without an address, and earn a revenue share.
Automate your own gifting and sending. Create custom integrations to send one or hundreds of gifts programmatically — or use our Zapier app for no-code workflows.
## The MCP server
Send and manage gifts directly from Claude and other AI assistants. Discover a gift, write the card, confirm the price, and send — all in one conversation, with spending always gated behind your confirmation.
Connect Goody to Claude in a couple of clicks and gift in natural language. See the MCP Reference for connection, permissions, and the full tool surface.
## Production and sandbox environments
Goody's API has two environments:
* **Production**: [https://api.ongoody.com](https://api.ongoody.com)
* **Sandbox**: [https://api.sandbox.ongoody.com](https://api.sandbox.ongoody.com)
## Start using the API
To start using the API, sign up for a Goody for Business account at [https://www.ongoody.com/business](https://www.ongoody.com/business). It's free to sign up.
To obtain an API key for the Automation API, go to your Account page and click [API Keys](https://www.ongoody.com/plus/account/api-keys). To send gifts in production, you'll need to add a payment method, which you can do on that page. To obtain an API key for the Commerce API, refer to the [getting started guide](/commerce-api/overview).
## Using the Sandbox environment
You can use the Sandbox environment to send test gifts without being charged for them. Your sandbox account is entirely separate account from production, so you can do your testing without affecting your main account.
Visit [https://sandbox.ongoody.com/business](https://sandbox.ongoody.com/business) to sign up for a sandbox account, and to obtain an API key for the Automation API, go to your Account page and click [API Keys](https://sandbox.ongoody.com/plus/account/api-keys). To obtain an API key for the Commerce API, refer to the [getting started guide](/commerce-api/overview).
## OpenAPI file
Goody provides an OpenAPI (Swagger) file that you can import to various tools like Postman and Insomnia.
[Download OpenAPI file](https://assets.ongoody.com/static/web/goody-api-openapi.json)
# Send methods
Source: https://developer.ongoody.com/introduction/send-methods
When creating an order batch, there are several send methods that define the behavior of orders.
The send method (`email_and_link`, `link_multiple_custom_list`, or `direct_send`) is passed as the `send_method` field on the [create order batch payload](/api-reference/order-batches/create-an-order-batch).
**Available send methods**
## Gift – Email Notification
Send method: `email_and_link`
Orders will be created as gifts. An email notification (and text message, if phone is specified) will be sent to the recipient of the gift. You will also be able to retrieve the gift link from the `individual_gift_link` field on the `Order` object (hence "email and link"). An email must be specified for every recipient.
Gift recipients can view their gift, swap for another gift (if swap is not disabled), and accept the gift by entering their address.
## Gift – Links Only
Send method: `link_multiple_custom_list`
Orders will be created as gifts. No email notification will be sent to the gift recipient. On the `Order` object, there will be an `individual_gift_link` field which contains the link to the gift, which you can send to the recipient.
Gift recipients can view their gift, swap for another gift (if swap is not disabled), and accept the gift by entering their address.
## Direct Send
Send method: `direct_send`
Ship products directly to the given address. For more info, see the [documentation page for direct send](/introduction/send-to-address). The address must be specified in the `mailing_address` field of the recipient payload, like the example below:
```json theme={null}
"recipients": [
{
"first_name": "Alena",
"last_name": "Kenter",
"email": "alena@ongoody.com",
"mailing_address": {
"first_name": "Alena",
"last_name": "Kenter",
"address_1": "1 Main St",
"address_2": "Apt 123",
"city": "New York",
"state": "NY",
"postal_code": "10022",
"country": "US"
}
}
]
```
# Ship to address
Source: https://developer.ongoody.com/introduction/send-to-address
Ship products directly to an address with the Direct Send send method.
When you already know the address you want to send an order to, you can use Goody to ship directly to that address using the Direct Send send method (`direct_send`).
There are two things to be aware of when using direct send:
1. You'll enter the address of the recipient in the `mailing_address` field of the recipient object.
2. If a product in your cart has variants, you must specify the variants to send.
## Specifying the mailing address
To specify the mailing address, you'll need to add a `mailing_address` object to the recipient object. Here's an example:
```json theme={null}
"recipients": [
{
"first_name": "Alena",
"last_name": "Kenter",
"email": "alena@ongoody.com",
"mailing_address": {
"first_name": "Alena",
"last_name": "Kenter",
"address_1": "1 Main St",
"address_2": "Apt 123",
"city": "New York",
"state": "NY",
"postal_code": "10022",
"country": "US"
}
}
]
```
## Specifying variants
When sending a gift with Goody, you don't need to specify the variants since the recipient can select the variants on their own. However, when sending with Direct Send, we need to know which variant to send to the recipient, so you'll need to specify the variant.
If a product has no variants (`variants_num_selectable` is null or zero), you don't need to specify any variants.
### Variants data
When [retrieving products from the product catalog](/api-reference/products/list-all-active-products), you'll see the following information in the product object:
```json theme={null}
{
"variants_label": "Flavor",
"variants_num_selectable": 1,
"variants": [
{
"id": "4da4dfd2-a094-4f9b-80dc-11d9067ff41b",
"name": "Chocolate Chip",
"subtitle": "Classic chocolate chip.",
"image_large": null
},
{
"id": "4d2581b7-b127-4e4b-8fac-7c7835022e3d",
"name": "Oatmeal",
"subtitle": "Delicious oatmeal.",
"image_large": null
},
{
"id": "087da4f9-8f8b-4d36-96b2-498a5b906409",
"name": "Sugar",
"subtitle": "Tasty sugar.",
"image_large": null
}
}
```
`variants_label` tells you the name of the variant. This can be something like Size, Flavor, Color, etc.
`variants_num_selectable` tells you how many variants can be selected. This is the expected length of the `variants` array that you pass into the cart item. Typically, this is 1, but some products let you select more than one variant, such as a 3-pack of cookies. If this is null or `0`, then you don't need to specify any variants.
`variants` shows you the data for each variant. You'll use the `name` field of the variant when passing variants in the cart item.
### Adding variants to the cart item
Let's say that the product has `variants_num_selectable` equal to `1`, so we must specify one variant in the cart item. Our cart item now looks like this:
```json theme={null}
"cart": {
"items": [
{
"product_id": "0b7b7cb3-a8c5-456f-af88-ae73f25092a5",
"quantity": 1,
"variants": ["Chocolate Chip"]
}
]
}
```
Now, if we had a product with `variants_num_selectable` equal to `3`, then we must specify three variants in the cart item. Our cart item now looks like this:
```json theme={null}
"cart": {
"items": [
{
"product_id": "0b7b7cb3-a8c5-456f-af88-ae73f25092a5",
"quantity": 1,
"variants": ["Chocolate Chip", "Sugar", "Sugar"]
}
]
}
```
You can specify the same variant more than once.
## Example direct send payload
This payload will send a direct send gift to the specified recipient. This product is a pack of cookies with a single variant selection (`variants_num_selectable` is `1`).
```json theme={null}
{
"from_name": "Michael",
"send_method": "direct_send",
"recipients": [
{
"first_name": "Alena",
"last_name": "Kenter",
"email": "alena@ongoody.com",
"mailing_address": {
"first_name": "Alena",
"last_name": "Kenter",
"mailing_address": {
"address_1": "1 Main St",
"address_2": "Apt 123",
"city": "New York",
"state": "NY",
"postal_code": "10022",
"country": "US"
}
}
}
],
"cart": {
"items": [
{
"product_id": "5ab8967a-0add-426f-a50c-8032b8bae643",
"quantity": 1,
"variants": ["Bestsellers Mix"]
}
]
}
}
```
# Capabilities & roadmap
Source: https://developer.ongoody.com/mcp-reference/capabilities
What the Goody MCP server can do today, what it can't do yet, and what's on the roadmap.
A candid map of the Goody MCP server's surface — what works today, the current limits, and where it's headed. For the exact tools, see the [tool reference](/mcp-reference/tools).
## What you can do today
* Search the catalog by intent, budget, and occasion — up to 5 curated matches per search.
* Retrieve full detail for a single product (description, shipping, alcohol status, US state restrictions).
* Browse curated **collections** and send one (each published collection carries a `product_id` you send like any product).
* Offer a **Gift of Choice** the recipient picks themselves, optionally framed to a budget.
* List Goody greeting cards and filter them by occasion.
* Draft card-message options for an occasion.
* **Preview a gift before sending** — get a shareable link to the assembled gift (card, message, products) plus the full price, without charging or sending.
* Price a gift in full (subtotal, shipping, estimated tax) — free and repeatable.
* Send a gift three ways: a **gift link** you share yourself, an **email** with the gift link, or **direct shipping** to a mailing address — after explicit price confirmation.
* **Schedule a send** for a future date (up to 3 months out).
* Send to a saved contact or an ad-hoc recipient (name + email).
* **International delivery** when the recipient is abroad (US is the default).
* Send **gift cards** and other catalog products; recipients can swap their gift unless you disable it.
* Pay with a saved card, your **Goody Balance**, or a **Corporate Account**.
* Review past gift batches and individual orders, and **cancel** an order the recipient hasn't accepted yet.
* Search, retrieve, create, and update workspace contacts.
* Create and list contact lists for group sends and automations.
* Create a recurring **autogift** two ways: clone a gift you've already sent, or build one from scratch (cart + card + message + payment).
* Triggers: birthday, work anniversary, and employee onboarding.
* **Preview** a rule's gift and per-send cost before activating it.
* List, activate, and pause autogift rules. Rules are always created paused.
* Identify the connected account and the server's current time.
* List the workspaces you can gift from and your saved payment methods (display names only — never card numbers).
* Send feedback about Goody straight to the Goody team.
## Can it do…?
A quick reference for the questions that come up most. "Not yet" means it's on the roadmap; "No" means it's out of scope for the Goody MCP server.
| Question | Today | Notes |
| ----------------------------------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Send a gift without an address | ✅ Yes | Gift link or email; the recipient enters their own address. |
| **Ship directly to a known address** | ✅ Yes | `direct_send` ships the physical product to a mailing address you provide. US addresses today. |
| **Preview the exact gift before sending** | ✅ Yes | Returns a shareable link to the assembled, not-yet-sent gift plus its full price — nothing is charged. |
| **Schedule a gift for a future date** | ✅ Yes | Up to 3 months out. |
| Gift of Choice (recipient picks) | ✅ Yes | Optionally budget-framed. |
| Send a **gift card** | ✅ Yes | Gift-card products live in the catalog — search for them like any product. (Distinct from greeting cards.) |
| Browse **& send collections** | ✅ Yes | List curated collections and send one via its `product_id` — the recipient picks from it, like a Gift of Choice. |
| **Create** a gift collection | ⏳ Not via MCP | Build collections in Goody for Business; the MCP server lists and sends them, but doesn't create them. |
| **Autogifts** (recurring) | ✅ Yes | Birthday / work anniversary / onboarding; clone a past send or build from scratch; created paused. |
| **Global shipping** | ✅ Yes | US is the default — say the recipient is international and it enables global delivery. |
| **Pay from Goody Balance or Corporate Account** | ✅ Yes | Alongside saved cards. (Balance-paid gifts require an expiration date.) |
| **Cancel a sent gift** | ✅ Yes | Per order, while the recipient hasn't accepted it yet — releases the hold and refunds any applied credit. |
| **Use from a script, Zapier, or cron job** | ✅ Yes | Mint a personal MCP token (no browser OAuth needed) and connect headlessly. |
| **Run fully autonomously** (no human at send) | ✅ Yes | Via a token scoped to Send gifts; bounded by your daily spend limit. See [the gifting flow](/mcp/gifting-flow#automatic--agentic-sends). |
| Manage contacts & lists | ✅ Yes | Search, create, update; build lists. |
| Apply **promo / referral / signup credit** | ⏳ Not yet | Automatic account credit isn't applied to gifts sent through the Goody MCP server yet. (Paying from your Goody **Balance** or **Corporate Account** is supported — see above.) |
| **Calendly** / meeting-request gifts | ⏳ Not yet | Can't attach a meeting requirement to a gift through the Goody MCP server yet. |
| Custom / **branded** cards | ⏳ Not yet | Only Goody's standard greeting cards are listed today. |
| Visual card preview inside the chat | ⏳ Not yet | Greeting cards are presented as named, clickable links today; an inline card picker is coming. |
| **Smart Links** (reusable, multi-claim links) | ⏳ Not via MCP | Smart Links are a Goody feature — they're just not exposed as an MCP tool yet. Sends here target specific recipients (link, email, or direct ship). |
| **Swag** / branded merch on demand | ❌ No | Not available through the Goody MCP server. |
| Send from **Gmail** | ❌ No | Goody's Gmail integration is a separate product; the Goody MCP server is independent of it. |
| Gift from **another user's** Goody account | ❌ No | The Goody MCP server acts only as the signed-in user, within workspaces they belong to. |
## Coming soon
Roadmap items are directional — not commitments or timelines — and reflect what
we're actively exploring. They may change.
* A visual card preview and picker inside the conversation.
* Smarter card discovery, so natural occasion language ("onboarding", "new parent") finds the right card.
* Access to your workspace's custom and branded cards.
* Richer, recipient-aware gift suggestions.
* Meeting-request (Calendly-style) settings on gifts.
* Applying account credit (promo / referral / signup) to gifts sent through the Goody MCP server.
* One-click connect via the Claude Connectors Directory — rolling out; for now, add Goody as a [custom connector](/mcp/connect).
# Example prompts
Source: https://developer.ongoody.com/mcp-reference/example-prompts
Real flows the Goody MCP server supports today, with illustrative responses.
These are real flows the Goody MCP server supports today. Responses are illustrative — your products, prices, and contacts will differ — but the shape matches how the Goody MCP server actually behaves.
A few defaults to know: gift searches return up to **5 curated matches** (ask
for changes to refine), **US shipping** is the default (say so for
international recipients), **alcohol** is excluded unless you ask for it, and
**you always see a preview and price before anything is sent**.
## Find a gift under a budget
> "Find a thank-you gift under \$50 for a client who loves coffee."
The assistant searches the catalog with your intent and budget, and typically also offers a **Gift of Choice** — Goody's "let them pick" option where the recipient chooses from a curated collection and you fund the amount.
```text Example response theme={null}
Here are five great options under $50:
1. Single-Origin Coffee Trio — Driftaway Coffee, $36
2. Cold Brew Starter Kit — Grady's, $42
3. Ceramic Pour-Over Set — Yield Design, $48
4. Espresso Chocolate Collection — Compartés, $34
5. Coffee + Mug Gift Box — Bean Box, $45
There's also a Goody Gift of Choice at your $50 budget — they'd pick their own
gift and you only pay what you fund. Want me to preview one of these?
```
## Preview, confirm, and send to one recipient
> "Send the Cold Brew Starter Kit to Sarah Chen at [sarah@acme.com](mailto:sarah@acme.com) with a thank-you card. Email it to her."
The assistant assembles the send — greeting card, optional message, payment method — then **builds a preview link and prices it**, and asks you to confirm before sending:
```text Example response theme={null}
Here's a preview of the gift before I send anything:
🔗 Preview: https://ongoody.com/p/preview/2f9c… (this is what Sarah will see)
- Gift: Cold Brew Starter Kit — $42.00
- Recipient: Sarah Chen (sarah@acme.com) — she'll get an email with her gift link
- Card: "Thank You" with the message we drafted
- From: Alex Rivera
- Payment: Visa ending 4242
- Estimated total: $51.83 ($42.00 gift + $6.00 shipping + $3.83 estimated tax)
Shall I send it?
```
After you say yes, it sends and confirms whether the recipient was notified. Sarah enters her own shipping details when she accepts — and can swap the gift unless you disable swapping.
Prefer to ship straight to an address? Say "ship it directly to 123 Main St…"
and the assistant uses **direct send** — no email or link, the physical gift
goes to the address you give. Want to send later? "Schedule it for next
Monday" works too (up to 3 months out).
## Add contacts and build a list
> "Add these three new hires to my workspace and put them in an 'Onboarding' list: Maya Patel ([maya@northwind.com](mailto:maya@northwind.com), birthday March 12), James Okafor ([james@northwind.com](mailto:james@northwind.com)), and Lena Fischer ([lena@northwind.com](mailto:lena@northwind.com))."
```text Example response theme={null}
Done — I added all three contacts and created the list "Onboarding" with all 3
in it. You can use this list for a group send or a recurring autogift.
```
If a contact with the same email already exists, the assistant won't silently overwrite it — it tells you and offers to update the existing contact instead.
## Turn a gift into a recurring autogift
> "Set up a birthday autogift for my Clients list, using that gift I just sent to Sarah as the template."
You can clone a past send like this, or build a brand-new rule from scratch ("set up a \$50 birthday autogift for my Clients list with the Cold Brew Kit and a birthday card"). Either way the rule is created paused:
```text Example response theme={null}
Here's a preview of the autogift rule before I activate anything:
- Trigger: each client's birthday, every year
- Gift: Cold Brew Starter Kit, with a "Happy Birthday" card and message
- Payment: Visa ending 4242
- Expected cost per send: ~$51.83
⏸️ The rule is created paused — autogifts are always created paused so a recurring
charge is never set up by accident. Want me to activate it now?
```
Only after you explicitly say yes does the assistant activate the rule. You can ask it to list, pause, or re-activate your autogifts any time ("what autogifts do I have running?").
# Tool reference
Source: https://developer.ongoody.com/mcp-reference/tools
The 28 tools the Goody MCP server exposes, grouped by area, with the permission each one requires.
The server exposes 28 tools. Each is named `goody__` and requires one of three permissions — **Read**, **Write**, or **Send gifts** (see [Authentication](/mcp/authentication)). Select a tool for its parameters, returns, and a worked `prompt → tool call → result` example.
## Account & workspaces
| Tool | Permission | Description |
| --------------------------------------------------------------- | ---------- | ------------------------------------------------------------------ |
| [`goody_me_get`](/mcp-reference/tools/me-get) | Read | Get the connected account's profile and the server's current time. |
| [`goody_workspaces_list`](/mcp-reference/tools/workspaces-list) | Read | List the workspaces you can gift from. |
## Discover gifts & cards
| Tool | Permission | Description |
| ----------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------- |
| [`goody_products_search`](/mcp-reference/tools/products-search) | Read | Search the catalog by intent, budget, and filters (up to 5 matches). |
| [`goody_products_get`](/mcp-reference/tools/products-get) | Read | Retrieve full detail for a single product. |
| [`goody_collections_list`](/mcp-reference/tools/collections-list) | Read | List curated gift collections. |
| [`goody_gift_of_choice_list`](/mcp-reference/tools/gift-of-choice-list) | Read | List "let them pick" Gift of Choice options, optionally budget-framed. |
| [`goody_cards_list`](/mcp-reference/tools/cards-list) | Read | List greeting cards, filterable by occasion. |
## Contacts
| Tool | Permission | Description |
| ------------------------------------------------------------------------- | ---------- | ----------------------------------------------- |
| [`goody_contacts_search`](/mcp-reference/tools/contacts-search) | Read | Search workspace contacts by name or email. |
| [`goody_contacts_get`](/mcp-reference/tools/contacts-get) | Read | Retrieve a single contact, with event dates. |
| [`goody_contacts_create`](/mcp-reference/tools/contacts-create) | Write | Add a workspace contact. |
| [`goody_contacts_update`](/mcp-reference/tools/contacts-update) | Write | Update an existing contact. |
| [`goody_contact_lists_list`](/mcp-reference/tools/contact-lists-list) | Read | List contact lists. |
| [`goody_contact_lists_create`](/mcp-reference/tools/contact-lists-create) | Write | Create a contact list, optionally with members. |
## Messages
| Tool | Permission | Description |
| ------------------------------------------------------------------- | ---------- | ------------------------------------------------- |
| [`goody_messages_generate`](/mcp-reference/tools/messages-generate) | Read | Draft three card-message options for an occasion. |
## Payment methods
| Tool | Permission | Description |
| ------------------------------------------------------------------------- | ---------- | ----------------------------------------------------------------------------------------------------------- |
| [`goody_payment_methods_list`](/mcp-reference/tools/payment-methods-list) | Read | List saved payment methods, Goody Balance, and Corporate Account (display names only — never card numbers). |
## Send & track gifts
| Tool | Permission | Description |
| --------------------------------------------------------------------------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| [`goody_order_batches_preview`](/mcp-reference/tools/order-batches-preview) | Write | Build a shareable preview link and price a gift that hasn't been sent. The confirmation step. |
| [`goody_order_batches_price`](/mcp-reference/tools/order-batches-price) | Write | Estimate the full price of a gift. A quick estimate; needs Write because it builds a draft order (see [Authentication](/mcp/authentication)). |
| [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create) | Send gifts | Send a gift. Requires explicit confirmation of the price. |
| [`goody_order_batches_list`](/mcp-reference/tools/order-batches-list) | Read | List past gift batches. |
| [`goody_order_batches_get`](/mcp-reference/tools/order-batches-get) | Read | Retrieve a single gift batch. |
| [`goody_orders_list`](/mcp-reference/tools/orders-list) | Read | List individual orders, optionally within a batch. |
| [`goody_orders_cancel`](/mcp-reference/tools/orders-cancel) | Write | Cancel a single order the recipient hasn't accepted yet. |
## Autogifts
| Tool | Permission | Description |
| ------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------- |
| [`goody_autogift_rules_list`](/mcp-reference/tools/autogift-rules-list) | Read | List autogift rules. |
| [`goody_autogift_rules_create`](/mcp-reference/tools/autogift-rules-create) | Send gifts | Create a recurring autogift — clone a past send or build from scratch (always created paused). |
| [`goody_autogift_rules_preview`](/mcp-reference/tools/autogift-rules-preview) | Read | Preview a paused rule's gift and per-send cost before activating. |
| [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate) | Send gifts | Activate a paused autogift rule. |
| [`goody_autogift_rules_pause`](/mcp-reference/tools/autogift-rules-pause) | Write | Pause an active autogift rule. |
## Feedback
| Tool | Permission | Description |
| --------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------- |
| [`goody_feedback_create`](/mcp-reference/tools/feedback-create) | Write | Send the user's feedback about Goody to the Goody team. Never charges. |
# goody_autogift_rules_activate
Source: https://developer.ongoody.com/mcp-reference/tools/autogift-rules-activate
Activate a paused autogift rule so it begins scheduling future gifts.
**Permission:** `Send gifts` · **Workspace:** required (from `goody_workspaces_list`)
Activates a paused rule so it begins scheduling future gifts against its contact list.
Activation commits the recurring spend — preview the rule with [`goody_autogift_rules_preview`](/mcp-reference/tools/autogift-rules-preview) and get the user's confirmation first.
The rule is re-validated before activating and fails cleanly if the product was discontinued, the payment method was removed, or required fields are missing.
## Parameters
Workspace UUID — from `goody_workspaces_list`. The rule must belong to this workspace.
Rule UUID — from [`goody_autogift_rules_list`](/mcp-reference/tools/autogift-rules-list).
## Returns
The now-active rule.
Rule UUID.
Now `active`.
The occasion that triggers a send.
The contact list the rule watches.
Contact list UUID.
The list's visible name.
The greeting card chosen for the rule.
The "From" name recipients see.
The gift-card message template.
Lowest years of service the rule applies to.
Highest years of service the rule applies to.
When the rule was created.
## Example
```text 💬 Prompt theme={null}
"Activate it."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_autogift_rules_activate",
"arguments": { "workspace_id": "3f8a…", "autogift_rule_id": "6d2a…" }
}
```
```json ↩️ Result theme={null}
{
"autogift_rule": {
"id": "6d2a…",
"status": "active",
"event_type": "birthday",
"contact_list": { "id": "d052…", "name": "Clients" },
"card_id": "a7f9…",
"from_name": "Jordan at Acme",
"message": "Happy birthday, {{firstname}}!",
"tenure_min": null,
"tenure_max": null,
"created_at": "2026-05-02T14:11:00Z"
}
}
```
Preview before activating with [`goody_autogift_rules_preview`](/mcp-reference/tools/autogift-rules-preview); stop a running rule with [`goody_autogift_rules_pause`](/mcp-reference/tools/autogift-rules-pause).
# goody_autogift_rules_create
Source: https://developer.ongoody.com/mcp-reference/tools/autogift-rules-create
Create a paused autogift rule — clone a past gift or build one from scratch.
**Permission:** `Send gifts` · **Workspace:** required (from `goody_workspaces_list`)
Creates a **paused** autogift rule — a recurring gift that sends automatically when a recipient hits a birthday, work anniversary, or onboarding milestone.
There are two ways to supply the gift contents — pick exactly one:
* **(A) Clone** a recently-sent gift batch with `source_order_batch_id`. The cart, card, message, From name, payment method, and shipping are all pulled from that batch.
* **(B) Build from scratch** (no prior send) — a cart plus `card_id`, `message`, and `payment_method_id`.
The rule is created **paused**. Call [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate) once the user confirms — activation is what commits the recurring spend.
## Parameters
### Required
Workspace UUID — from `goody_workspaces_list`. The rule is created in this workspace.
The occasion that triggers a send — one of `birthday`, `work_anniversary`, or `onboarding`.
An existing contact list — from [`goody_contact_lists_list`](/mcp-reference/tools/contact-lists-list) or [`goody_contact_lists_create`](/mcp-reference/tools/contact-lists-create). Mutually exclusive with `contact_ids`; supply exactly one.
Contact UUIDs to gift. The tool creates an implicit list from them. Mutually exclusive with `contact_list_id`; supply exactly one.
The gift batch to clone, from [`goody_order_batches_list`](/mcp-reference/tools/order-batches-list). Mutually exclusive with a from-scratch cart; supply exactly one.
### From-scratch path
Supply these instead of `source_order_batch_id` to build the gift without a prior send.
A single product to gift, from [`goody_products_search`](/mcp-reference/tools/products-search). Use this or `cart`.
How many of the product to include.
Funded amount in cents, for a Gift of Choice.
Multiple products to gift. Use this or `product_id`.
Each item names a `product_id` and optional `quantity` / `variable_price`.
Greeting card UUID — from [`goody_cards_list`](/mcp-reference/tools/cards-list).
The gift-card message. Personalization tags (e.g. the recipient's first name) are filled per-recipient at send time.
The "From" name recipients see. Defaults to the authenticated user.
The autopay payment method the rule charges on activation — from [`goody_payment_methods_list`](/mcp-reference/tools/payment-methods-list). Recommended. Without it the rule is created but won't activate.
Shipping tier to apply for recipients outside the US.
Required `true` when the cart contains alcohol.
Rule settings.
Set `true` to include international gift cards.
### Optional (both paths)
Lowest years of service the rule applies to. Meaningful for `work_anniversary`.
Highest years of service the rule applies to. Meaningful for `work_anniversary`.
When to send relative to the occasion — `send_on_anchor_date`, `send_before_anchor_date`, or `send_after_anchor_date`.
How many days before or after the occasion to send. Required when the send option is before or after.
Which date the occasion anchors to — `start_date` or `added_to_hris_date`. Only for `onboarding`.
Clone path only. When the source card's occasion doesn't match the event type, the request is rejected; set `true` to override.
## Returns
The newly created, paused rule.
Rule UUID — pass to [`goody_autogift_rules_preview`](/mcp-reference/tools/autogift-rules-preview) or [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate).
Always `paused` on creation.
The occasion that triggers a send.
The contact list the rule watches.
The greeting card chosen for the rule.
The gift-card message template.
The "From" name recipients see.
## Example
```text 💬 Prompt theme={null}
"Set up a $50 birthday autogift for my Clients list with the Cold Brew Kit and a birthday card."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_autogift_rules_create",
"arguments": {
"workspace_id": "3f8a…",
"event_type": "birthday",
"contact_list_id": "d052…",
"product_id": "0f3c…",
"card_id": "a7f9…",
"message": "Happy birthday, {{firstname}}!",
"from_name": "Jordan at Acme",
"payment_method_id": "pm_4c19…"
}
}
```
```json ↩️ Result theme={null}
{
"autogift_rule": {
"id": "6d2a…",
"status": "paused",
"event_type": "birthday",
"contact_list_id": "d052…",
"card_id": "a7f9…",
"message": "Happy birthday, {{firstname}}!",
"from_name": "Jordan at Acme"
}
}
```
Confirm the gift first with [`goody_autogift_rules_preview`](/mcp-reference/tools/autogift-rules-preview), then turn it on with [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate). To group recipients into a reusable list, use [`goody_contact_lists_create`](/mcp-reference/tools/contact-lists-create).
# goody_autogift_rules_list
Source: https://developer.ongoody.com/mcp-reference/tools/autogift-rules-list
List the autogift (recurring gift) rules in a workspace.
**Permission:** `Read` · **Workspace:** required (from `goody_workspaces_list`)
Lists the autogift (recurring gift) rules in a workspace — the rules that send a gift automatically when a recipient hits a birthday, work anniversary, or onboarding milestone.
## Parameters
Workspace UUID — from `goody_workspaces_list`. Rules in this workspace are returned.
Filter by rule state — one of `active`, `paused`, or `inactive`. Omit to return rules in all states.
Page number, starting at 1.
Results per page. Maximum 100.
## Returns
The matching autogift rules.
Rule UUID — pass to [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate) or [`goody_autogift_rules_pause`](/mcp-reference/tools/autogift-rules-pause).
Rule state — `active`, `paused`, or `inactive`.
The occasion that triggers a send — e.g. `birthday`, `work_anniversary`, or `onboarding`.
The contact list the rule watches.
Contact list UUID.
The list's visible name.
The greeting card chosen for the rule.
The "From" name recipients see.
The gift-card message template.
Lowest years of service the rule applies to.
Highest years of service the rule applies to.
When the rule was created.
The current page number.
Results per page.
Total number of matching rules across all pages.
## Example
```text 💬 Prompt theme={null}
"What autogifts do I have running?"
```
```json 🔧 Tool call theme={null}
{
"name": "goody_autogift_rules_list",
"arguments": { "workspace_id": "3f8a…", "status": "active" }
}
```
```json ↩️ Result theme={null}
{
"autogift_rules": [
{
"id": "6d2a…",
"status": "active",
"event_type": "birthday",
"contact_list": { "id": "d052…", "name": "Clients" },
"card_id": "a7f9…",
"from_name": "Jordan at Acme",
"message": "Happy birthday, {{firstname}}!",
"tenure_min": null,
"tenure_max": null,
"created_at": "2026-05-02T14:11:00Z"
}
],
"page": 1,
"per_page": 25,
"total_count": 1
}
```
Use a returned `id` with [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate) to turn a rule on, or [`goody_autogift_rules_pause`](/mcp-reference/tools/autogift-rules-pause) to stop further sends.
To turn a listed rule on or off, use [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate) and [`goody_autogift_rules_pause`](/mcp-reference/tools/autogift-rules-pause).
# goody_autogift_rules_pause
Source: https://developer.ongoody.com/mcp-reference/tools/autogift-rules-pause
Pause an active autogift rule so no further gifts are scheduled.
**Permission:** `Write` · **Workspace:** required (from `goody_workspaces_list`)
Pauses an active rule so no further gifts are scheduled against its contact list. Reversible via [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate).
## Parameters
Workspace UUID — from `goody_workspaces_list`. The rule must belong to this workspace.
Rule UUID — from [`goody_autogift_rules_list`](/mcp-reference/tools/autogift-rules-list).
## Returns
The now-paused rule.
Rule UUID.
Now `paused`.
The occasion that triggers a send.
The contact list the rule watches.
Contact list UUID.
The list's visible name.
The greeting card chosen for the rule.
The "From" name recipients see.
The gift-card message template.
Lowest years of service the rule applies to.
Highest years of service the rule applies to.
When the rule was created.
## Example
```text 💬 Prompt theme={null}
"Pause my Clients birthday autogift."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_autogift_rules_pause",
"arguments": { "workspace_id": "3f8a…", "autogift_rule_id": "6d2a…" }
}
```
```json ↩️ Result theme={null}
{
"autogift_rule": {
"id": "6d2a…",
"status": "paused",
"event_type": "birthday",
"contact_list": { "id": "d052…", "name": "Clients" },
"card_id": "a7f9…",
"from_name": "Jordan at Acme",
"message": "Happy birthday, {{firstname}}!",
"tenure_min": null,
"tenure_max": null,
"created_at": "2026-05-02T14:11:00Z"
}
}
```
Turn the rule back on with [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate), or browse all your rules with [`goody_autogift_rules_list`](/mcp-reference/tools/autogift-rules-list).
# goody_autogift_rules_preview
Source: https://developer.ongoody.com/mcp-reference/tools/autogift-rules-preview
Preview what a paused autogift rule will send — card, message, products, and cost — without sending.
**Permission:** `Read` · **Workspace:** required (from `goody_workspaces_list`)
Previews what a paused autogift rule will send — the greeting card, message, product(s), and expected per-send cost — without sending, charging, or activating anything. Call it before [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate) and relay the result for confirmation.
## Parameters
Workspace UUID — from `goody_workspaces_list`. The rule must belong to this workspace.
Rule UUID — from [`goody_autogift_rules_list`](/mcp-reference/tools/autogift-rules-list) or [`goody_autogift_rules_create`](/mcp-reference/tools/autogift-rules-create).
## Returns
The greeting card the rule will send.
Card UUID.
Card name.
Card image URL.
The gift-card message template.
The "From" name recipients see.
The product(s) the rule will send.
Product UUID.
Product name.
How many are included.
Funded amount in cents, for a Gift of Choice.
Estimated cost for a single recipient, in cents.
Low end of the estimate, in cents.
High end of the estimate, in cents.
## Example
```text 💬 Prompt theme={null}
"What will my Clients birthday autogift actually send?"
```
```json 🔧 Tool call theme={null}
{
"name": "goody_autogift_rules_preview",
"arguments": { "workspace_id": "3f8a…", "autogift_rule_id": "6d2a…" }
}
```
```json ↩️ Result theme={null}
{
"card": {
"id": "a7f9…",
"name": "Happy Birthday Confetti",
"image_url": "https://ongoody.com/cards/a7f9….png"
},
"message": "Happy birthday, {{firstname}}!",
"from_name": "Jordan at Acme",
"products": [
{
"product_id": "0f3c…",
"name": "Cold Brew Starter Kit",
"quantity": 1,
"flex_amount": null
}
],
"expected_spend_per_send": {
"est_group_total_low": 4200,
"est_group_total_high": 5000
}
}
```
The message is shown as its raw template — personalization tags (e.g. the recipient's first name) are filled per-recipient at send time, so no placeholder recipient is invented.
Once the preview looks right, turn the rule on with [`goody_autogift_rules_activate`](/mcp-reference/tools/autogift-rules-activate).
# goody_cards_list
Source: https://developer.ongoody.com/mcp-reference/tools/cards-list
Lists Goody's greeting cards — the card shown with a gift.
**Permission:** `Read` · **Workspace:** not required (global)
Lists Goody's greeting cards — the card shown with a gift (distinct from gift-card products). [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create) requires a `card_id`, so call this before composing a gift. Returns up to **25** cards.
## Parameters
Optional. Filters to cards tagged with a matching occasion name. The match is case-insensitive but **exact** — the full name, not a substring. Common values: `Birthday`, `Congratulations`, `Thank You`, `Work Anniversary`, `Welcome`, `Happy Holidays`, `Get Well`, `Thinking of You`, `Sympathy`, `Just Because`. The vocabulary is data-driven — inspect the `occasions` array on returned cards to find exact tags.
## Returns
Up to 25 matching cards.
Card UUID — pass as `card_id` when composing a gift.
Card name.
The card artwork.
Occasion tags for this card.
## Example
```text 💬 Prompt theme={null}
"Show me thank-you cards."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_cards_list",
"arguments": { "occasion": "Thank You" }
}
```
```json ↩️ Result theme={null}
{
"cards": [
{
"id": "0f3c…",
"name": "Heartfelt Thanks",
"image_url": "https://cards.goody.example/heartfelt-thanks.png",
"occasions": ["Thank You"]
},
{
"id": "9a17…",
"name": "Many Thanks",
"image_url": "https://cards.goody.example/many-thanks.png",
"occasions": ["Thank You", "Just Because"]
}
]
}
```
Pass a `card_id` from here to [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create) when composing a gift.
# goody_collections_list
Source: https://developer.ongoody.com/mcp-reference/tools/collections-list
List a workspace's curated gift collections — and get the product_id to send one.
**Permission:** `Read` · **Workspace:** required (from `goody_workspaces_list`)
Lists the curated gift collections in a workspace — each a pre-built, themed gift the recipient picks from. Returns up to **25**. Each published collection includes a **`product_id`** you can send like any other product: the recipient chooses from the collection before accepting, the same way a Gift of Choice works.
Collections are **read-only** through the MCP server — there's no tool to **create** one (build collections in Goody for Business). You can, however, **send** a published collection: use its `product_id` (not the collection `id`).
## Parameters
Workspace UUID, from [`goody_workspaces_list`](/mcp-reference/tools/workspaces-list).
When true, returns only published collections, skipping drafts. Set true when the user is ready to send — only published collections have a `product_id`.
## Returns
Up to 25 collections in the workspace.
Collection UUID. Identifies the collection itself — **not** what you send. To send, use `product_id`.
UUID of the owning workspace.
Collection name.
True when the collection has a published version.
Published price in cents; `null` when there's no published version.
The product to **send** this collection through — pass it as `product_id` to [`goody_order_batches_preview`](/mcp-reference/tools/order-batches-preview) / [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create). `null` for unpublished collections (nothing to send yet).
## Example
```text 💬 Prompt theme={null}
"Send our Welcome Aboard collection to the new hire, jordan@acme.com."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_collections_list",
"arguments": { "workspace_id": "0f3c…", "published_only": true }
}
```
```json ↩️ Result theme={null}
{
"collections": [
{
"id": "7b22…",
"workspace_id": "0f3c…",
"name": "Welcome Aboard Bundle",
"is_published": true,
"price_cents": 8500,
"product_id": "e91d…"
}
]
}
```
To send it, hand that `product_id` to the normal flow — preview, confirm, send:
```json 🔧 goody_order_batches_preview theme={null}
{
"name": "goody_order_batches_preview",
"arguments": {
"workspace_id": "0f3c…",
"card_id": "a7f9…",
"product_id": "e91d…",
"recipients": [{ "name": "Jordan Lee", "email": "jordan@acme.com" }]
}
}
```
The collection's price is in `price_cents`; for the full breakdown, run [`goody_order_batches_preview`](/mcp-reference/tools/order-batches-preview) with the `product_id`. (Collection products aren't in the searchable catalog, so [`goody_products_get`](/mcp-reference/tools/products-get) won't find them.) For an open-ended "let them pick" gift that isn't a saved collection, use [`goody_gift_of_choice_list`](/mcp-reference/tools/gift-of-choice-list).
# goody_contact_lists_create
Source: https://developer.ongoody.com/mcp-reference/tools/contact-lists-create
Create a new contact list, optionally with an initial set of members.
**Permission:** `Write` · **Workspace:** required (from `goody_workspaces_list`)
Creates a new active contact list in the workspace, optionally seeded with members. Use the returned id with [`goody_autogift_rules_create`](/mcp-reference/tools/autogift-rules-create).
## Parameters
Workspace UUID — from `goody_workspaces_list`. The list is created in this workspace.
The visible list name (e.g. "Q3 onboarding cohort").
Optional initial members — contact UUIDs from [`goody_contacts_search`](/mcp-reference/tools/contacts-search) or [`goody_contacts_get`](/mcp-reference/tools/contacts-get). Contacts that aren't in this workspace are silently skipped.
## Returns
The created list.
Contact list UUID — pass as `contact_list_id` to [`goody_autogift_rules_create`](/mcp-reference/tools/autogift-rules-create).
The visible list name.
Number of contacts added to the list.
## Example
```text 💬 Prompt theme={null}
"Make an 'Onboarding' list with these three contacts."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_contact_lists_create",
"arguments": {
"workspace_id": "3f8a…",
"name": "Onboarding",
"contact_ids": ["7b21…", "9c44…", "a1d7…"]
}
}
```
```json ↩️ Result theme={null}
{
"contact_list": {
"id": "d052…",
"name": "Onboarding",
"contact_count": 3
}
}
```
Find members first with [`goody_contacts_search`](/mcp-reference/tools/contacts-search), then point an
[`goody_autogift_rules_create`](/mcp-reference/tools/autogift-rules-create) rule at the new list.
# goody_contact_lists_list
Source: https://developer.ongoody.com/mcp-reference/tools/contact-lists-list
List a workspace's active contact lists, newest first.
**Permission:** `Read` · **Workspace:** required (from `goody_workspaces_list`)
Lists the active contact lists in a workspace, newest first. Use it before [`goody_autogift_rules_create`](/mcp-reference/tools/autogift-rules-create) so the user can pick a recipient list.
## Parameters
Workspace UUID — from `goody_workspaces_list`. Lists are scoped to this workspace.
Page number, 1-indexed.
Lists per page. Maximum 100.
## Returns
The active contact lists, newest first.
Contact list UUID — pass as `contact_list_id` to [`goody_autogift_rules_create`](/mcp-reference/tools/autogift-rules-create).
The visible list name.
`User-added` (a list the user built) or `HRIS-synced` (mirrored from an HR integration).
Number of contacts in the list.
The page returned.
Lists per page.
Total active lists in the workspace.
## Example
```text 💬 Prompt theme={null}
"What contact lists do I have?"
```
```json 🔧 Tool call theme={null}
{
"name": "goody_contact_lists_list",
"arguments": { "workspace_id": "3f8a…" }
}
```
```json ↩️ Result theme={null}
{
"contact_lists": [
{ "id": "c1e9…", "name": "Q3 onboarding cohort", "kind": "User-added", "contact_count": 12 },
{ "id": "b730…", "name": "Engineering", "kind": "HRIS-synced", "contact_count": 48 }
],
"page": 1,
"per_page": 25,
"total_count": 2
}
```
No list yet? Build one with [`goody_contact_lists_create`](/mcp-reference/tools/contact-lists-create), then point an
[`goody_autogift_rules_create`](/mcp-reference/tools/autogift-rules-create) rule at it.
# goody_contacts_create
Source: https://developer.ongoody.com/mcp-reference/tools/contacts-create
Add a new contact to a workspace and return the saved record.
**Permission:** `Write` · **Workspace:** required (from `goody_workspaces_list`)
Creates a contact in the workspace. Only `first_name` is required; everything else is optional. Returns the saved contact.
## Parameters
Workspace UUID — from `goody_workspaces_list`. The contact is created in this workspace.
The contact's given name.
Family name.
Email address.
Phone number in any format — it's normalized automatically.
Company name.
Job title.
Date as `YYYY-MM-DD`. Use year `1900` if only the month and day are known.
Date as `YYYY-MM-DD`. Use year `1900` if only the month and day are known.
If a contact with the same email or phone already exists in this workspace, the request is rejected rather than overwriting the existing contact. Call [`goody_contacts_update`](/mcp-reference/tools/contacts-update) to modify that contact instead.
## Returns
The saved contact.
Contact UUID.
Given name.
Family name.
Email address.
Phone number.
Company name.
Job title.
Date as `YYYY-MM-DD`; year `1900` means month and day only.
Date as `YYYY-MM-DD`.
## Example
```text 💬 Prompt theme={null}
"Add James Okafor (james@northwind.com) to my workspace."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_contacts_create",
"arguments": {
"workspace_id": "3f8a…",
"first_name": "James",
"last_name": "Okafor",
"email": "james@northwind.com"
}
}
```
```json ↩️ Result theme={null}
{
"contact": {
"id": "a1d7…",
"first_name": "James",
"last_name": "Okafor",
"email": "james@northwind.com",
"phone": null,
"company": null,
"title": null,
"birthday": null,
"work_anniversary": null
}
}
```
To edit a contact you already have, use [`goody_contacts_update`](/mcp-reference/tools/contacts-update). To find one first, use
[`goody_contacts_search`](/mcp-reference/tools/contacts-search).
# goody_contacts_get
Source: https://developer.ongoody.com/mcp-reference/tools/contacts-get
Fetch one contact's full detail, including birthday and work anniversary.
**Permission:** `Read` · **Workspace:** required (from `goody_workspaces_list`)
Fetches the full detail for a single contact, including the event dates the search response omits. Use it before composing a birthday or anniversary gift, or to confirm a recipient's details before sending.
## Parameters
Workspace UUID — from `goody_workspaces_list`. The contact must belong to this workspace.
Contact UUID — from a [`goody_contacts_search`](/mcp-reference/tools/contacts-search) result.
## Returns
Contact UUID.
Given name.
Family name.
Email address.
Phone number.
Company name.
Job title.
Date as `YYYY-MM-DD`. A year of `1900` means only the month and day are known.
Date as `YYYY-MM-DD`.
Returns not-found if the id is unknown or belongs to another workspace.
## Example
```text 💬 Prompt theme={null}
"When is Maya Patel's birthday?"
```
```json 🔧 Tool call theme={null}
{
"name": "goody_contacts_get",
"arguments": { "workspace_id": "3f8a…", "contact_id": "9c44…" }
}
```
```json ↩️ Result theme={null}
{
"id": "9c44…",
"first_name": "Maya",
"last_name": "Patel",
"email": "maya@northwind.com",
"phone": "+14155550199",
"company": "Northwind",
"title": "Design Lead",
"birthday": "1991-04-12",
"work_anniversary": "2020-09-01"
}
```
Find the contact first with [`goody_contacts_search`](/mcp-reference/tools/contacts-search), then edit it with
[`goody_contacts_update`](/mcp-reference/tools/contacts-update).
# goody_contacts_search
Source: https://developer.ongoody.com/mcp-reference/tools/contacts-search
Find a workspace contact by name, email, or phone — returns up to 25 matches.
**Permission:** `Read` · **Workspace:** required (from `goody_workspaces_list`)
Searches the contacts in a workspace and returns up to `limit` matches. Use it to find a recipient before pricing or sending a gift. Match a free-text `query` across name, email, and phone — or omit it to list everyone alphabetically.
## Parameters
Workspace UUID — from `goody_workspaces_list`. Search is always scoped to this workspace.
Free-text search matched across first name, last name, email, and phone. Name matches outrank email matches, which outrank phone matches. Omit to list contacts alphabetically.
Maximum contacts to return. Range 1–25; higher values are clamped to 25. There's no pagination — narrow `query` instead of raising the limit.
## Returns
Up to `limit` matching contacts.
Contact UUID — pass as `contact_id` to [`goody_contacts_get`](/mcp-reference/tools/contacts-get) or [`goody_contacts_update`](/mcp-reference/tools/contacts-update).
Given name.
Family name.
Email address.
Phone number.
Company name.
Job title.
The search response omits event dates. To get a contact's birthday or work anniversary, call [`goody_contacts_get`](/mcp-reference/tools/contacts-get).
## Example
```text 💬 Prompt theme={null}
"Find my contact Sarah at Acme."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_contacts_search",
"arguments": { "workspace_id": "3f8a…", "query": "Sarah Acme" }
}
```
```json ↩️ Result theme={null}
{
"contacts": [
{
"id": "7b21…",
"first_name": "Sarah",
"last_name": "Chen",
"email": "sarah@acme.com",
"phone": "+14155550148",
"company": "Acme",
"title": "Head of People"
}
]
}
```
Once you have a match, call [`goody_contacts_get`](/mcp-reference/tools/contacts-get) for the full detail (including birthday and work anniversary), or
[`goody_contacts_update`](/mcp-reference/tools/contacts-update) to edit it.
# goody_contacts_update
Source: https://developer.ongoody.com/mcp-reference/tools/contacts-update
Update an existing contact — only the fields you supply are changed.
**Permission:** `Write` · **Workspace:** required (from `goody_workspaces_list`)
Updates an existing contact. Only the fields you supply are written; omitted fields stay untouched. Returns the saved contact.
## Parameters
Workspace UUID — from `goody_workspaces_list`. The contact must belong to this workspace.
Contact UUID — from [`goody_contacts_search`](/mcp-reference/tools/contacts-search) or [`goody_contacts_get`](/mcp-reference/tools/contacts-get).
Given name.
Family name.
Email address.
Phone number in any format — it's normalized automatically.
Company name.
Job title.
Date as `YYYY-MM-DD`; use year `1900` if only the month and day are known. Pass an empty string to clear it; omit it entirely to leave it unchanged.
Date as `YYYY-MM-DD`. Pass an empty string to clear it; omit it entirely to leave it unchanged.
If the new email or phone already belongs to a different contact in this workspace, the request is rejected. Re-saving the contact's own current email or phone is fine.
## Returns
The saved contact.
Contact UUID.
Given name.
Family name.
Email address.
Phone number.
Company name.
Job title.
Date as `YYYY-MM-DD`; year `1900` means month and day only.
Date as `YYYY-MM-DD`.
## Example
```text 💬 Prompt theme={null}
"Update Maya's email to maya@northwind.io."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_contacts_update",
"arguments": {
"workspace_id": "3f8a…",
"contact_id": "9c44…",
"email": "maya@northwind.io"
}
}
```
```json ↩️ Result theme={null}
{
"contact": {
"id": "9c44…",
"first_name": "Maya",
"last_name": "Patel",
"email": "maya@northwind.io",
"phone": "+14155550199",
"company": "Northwind",
"title": "Design Lead",
"birthday": "1991-04-12",
"work_anniversary": "2020-09-01"
}
}
```
Find the contact first with [`goody_contacts_search`](/mcp-reference/tools/contacts-search), or read its current detail with
[`goody_contacts_get`](/mcp-reference/tools/contacts-get).
# goody_feedback_create
Source: https://developer.ongoody.com/mcp-reference/tools/feedback-create
Send the user's feedback about Goody to the Goody team.
**Permission:** `Write` · **Workspace:** optional
Sends the user's feedback about Goody to the Goody team — a comment, suggestion, bug report, or reaction. This tool never sends a gift or charges anything. It's a good thing to offer after a successful send ("Want me to pass any feedback to the Goody team?").
## Parameters
The feedback, in the user's own words.
How the user feels — one of `positive`, `neutral`, or `negative`.
Optional. Associates the feedback with a workspace — from `goody_workspaces_list`.
Optional. Ties the feedback to a specific gift batch the user is reacting to — from [`goody_order_batches_list`](/mcp-reference/tools/order-batches-list).
## Returns
The recorded feedback.
Feedback UUID.
The feedback message as recorded.
The sentiment, if one was given.
When the feedback was recorded.
A short confirmation message to relay to the user.
## Example
```text 💬 Prompt theme={null}
"Tell the Goody team the preview link was super helpful."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_feedback_create",
"arguments": {
"message": "The preview link was super helpful.",
"sentiment": "positive"
}
}
```
```json ↩️ Result theme={null}
{
"feedback": {
"id": "f10c…",
"message": "The preview link was super helpful.",
"sentiment": "positive",
"created_at": "2026-06-23T16:40:00Z"
},
"confirmation": "Thanks — your feedback has been sent to the Goody team."
}
```
After a successful send with [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create), pass along the `order_batch_id` here to tie a reaction to that specific gift.
# goody_gift_of_choice_list
Source: https://developer.ongoody.com/mcp-reference/tools/gift-of-choice-list
Lists Goody's Gifts of Choice — flex gifts where the recipient picks and the sender funds an amount.
**Permission:** `Read` · **Workspace:** not required (global)
Lists Goody's Gifts of Choice — variable-amount flex gifts where the recipient picks from a curated set and the sender funds an amount. Use when the user wants to "let the recipient choose" or is unsure what to send.
## Parameters
Optional. The catalog is global — pass a workspace UUID only to scope or validate against a workspace.
Optional, in cents (e.g. `7500` for \$75); must be positive. When set, each result's `suggested_variable_price` echoes the fundable amount — your budget clamped to the gift's range.
## Returns
Matching Gifts of Choice.
Gift UUID — pass as `product_id` to send.
Gift name.
`default` or `seasonal`.
Lowest fundable amount, in cents.
Highest fundable amount; `null` means unlimited.
Your budget clamped to `[price_min, price_max]`; `null` if the budget is below `price_min` or no budget was given.
Occasion tags for this gift.
To send one, pass its `id` as `product_id` plus `variable_price` (cents, within the range) to [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create).
## Example
```text 💬 Prompt theme={null}
"I don't know their taste — give me a $75 let-them-pick option."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_gift_of_choice_list",
"arguments": { "budget_cents": 7500 }
}
```
```json ↩️ Result theme={null}
{
"gifts_of_choice": [
{
"id": "0f3c…",
"name": "Gift of Choice",
"kind": "default",
"price_min": 2000,
"price_max": null,
"suggested_variable_price": 7500,
"occasions": ["Thank You", "Congratulations"]
},
{
"id": "9a17…",
"name": "Holiday Gift of Choice",
"kind": "seasonal",
"price_min": 5000,
"price_max": 25000,
"suggested_variable_price": 7500,
"occasions": ["Happy Holidays"]
}
]
}
```
Browse fixed-price gifts with [`goody_products_search`](/mcp-reference/tools/products-search), then send the chosen gift with [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create).
# goody_me_get
Source: https://developer.ongoody.com/mcp-reference/tools/me-get
Returns the connected Goody account's identity plus the server's current time.
**Permission:** `Read` · **Workspace:** not required (global)
Returns the authenticated Goody user's identity plus the server's current time. The first tool to call in a session to confirm which account is connected, and the anchor for any relative dates.
## Parameters
This tool takes no arguments.
## Returns
The Goody user's UUID.
The account's email address.
Given name, if set.
Family name, if set.
The server's authoritative "now", as an ISO 8601 UTC timestamp.
Scheduled-send dates are anchored to `server_time` — not the assistant's own clock. A scheduled date must be in the future and at most 3 months out.
## Example
```text 💬 Prompt theme={null}
"Which Goody account am I connected to?"
```
```json 🔧 Tool call theme={null}
{
"name": "goody_me_get",
"arguments": {}
}
```
```json ↩️ Result theme={null}
{
"id": "0f3c…",
"email": "jordan@northwind.example",
"first_name": "Jordan",
"last_name": "Rivera",
"server_time": "2026-06-23T14:05:00Z"
}
```
Call [`goody_workspaces_list`](/mcp-reference/tools/workspaces-list) next to discover the workspaces this account can gift from.
# goody_messages_generate
Source: https://developer.ongoody.com/mcp-reference/tools/messages-generate
Draft three candidate gift-card messages for the user to pick from or refine.
**Permission:** `Read` · **Workspace:** not required (global)
Generates three candidate gift-card messages for the user to pick from or refine. It works two ways — **autopilot** (`category` + `sub_category`) and **collaborative** (`user_prompt`) — and you can combine them: a category plus free-text instructions.
Built-in categories include thank you, congratulations, birthday, work anniversary, welcome/onboarding, apology, sympathy, farewell, and holidays.
## Parameters
A message category for autopilot mode — pair with `sub_category` (e.g. `category` `"birthday"`). One of: thank you, congratulations, birthday, work anniversary, welcome/onboarding, apology, sympathy, farewell, or holidays.
A narrower variant within the chosen `category`. Use alongside `category` in autopilot mode.
Free text describing the message you want — e.g. "thank a client for sticking with us through a delay". Required for collaborative mode; optional in autopilot mode as extra instructions on top of the category.
Free-text tone hints, e.g. `["warm", "professional"]`. Defaults to empty.
How formal the message should read, from `1` (very casual) to `5` (formal). Defaults to `3`.
## Returns
Exactly three candidate messages. Show them to the user and let them pick or refine.
Generated messages may contain the placeholder tokens `{{firstname}}` and `{{fullname}}` — Goody fills in each recipient's real name at send time. Pass the chosen message through to [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create) with the tokens unchanged. When you **show** a message to the user, render the token with the recipient's actual name for a clean preview.
## Example
```text 💬 Prompt theme={null}
"Draft a warm thank-you message for a client."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_messages_generate",
"arguments": {
"category": "thank you",
"user_prompt": "thank a client for sticking with us through a delay",
"tones": ["warm", "professional"],
"formality_level": 3
}
}
```
```json ↩️ Result theme={null}
{
"messages": [
"Thank you for your patience through the delay, {{firstname}} — your trust means everything to us, and we're grateful to keep working together.",
"{{firstname}}, we know the wait wasn't easy. Thank you for sticking with us — here's to a smoother road ahead.",
"A small thank-you, {{firstname}}, for your understanding and continued partnership. We don't take it for granted."
]
}
```
Once the user picks a message, carry the tokens through unchanged to [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create) — Goody personalizes each recipient's name at send time.
# goody_order_batches_create
Source: https://developer.ongoody.com/mcp-reference/tools/order-batches-create
Send a gift batch — charges the payment method and generates the gift links.
**Permission:** `Send gifts` · **Workspace:** required (from `goody_workspaces_list`)
Sends a gift batch — charges the payment method and generates the gift links.
This spends real money and cannot be undone from here. Preview or price first, relay the total, and only call this **after** the user confirms both the price and the recipients.
## Parameters
Workspace UUID — from `goody_workspaces_list`. Charges and sends from this workspace.
The funding source — from [`goody_payment_methods_list`](/mcp-reference/tools/payment-methods-list). A saved-card UUID, or the literal `BALANCE`, `WORKSPACE_BALANCE`, or `CORPORATE_ACCOUNT` sentinel.
Card UUID — from [`goody_cards_list`](/mcp-reference/tools/cards-list). The card the recipient sees with the gift.
Must be the literal `true` — the tool rejects anything else. Pass `true` only after the user has approved the price and recipients.
How each recipient receives the gift. **No default — you must choose one:**
* `link_single` — the recipient is **not** auto-notified; you share the link yourself.
* `email_and_link` — Goody emails each recipient their gift link.
* `direct_send` — Goody ships the physical product to each recipient's `mailing_address`, with no email. The `contact_id` shorthand can't be combined with `direct_send`.
A single product UUID — from [`goody_products_search`](/mcp-reference/tools/products-search). Use this **or** `cart`, never both.
Quantity for `product_id`. Defaults to `1`.
Amount to fund, in cents, for a variable-amount Gift of Choice or variable gift card. Must fall within the gift's `[price_min, price_max]`. Only applies to `product_id`.
A multi-item cart — an object with an `items` array (not a bare array). Use this **or** `product_id`, never both.
One entry per product in the gift.
Product UUID.
Quantity of this product.
Amount in cents for a variable-amount gift, within its `[price_min, price_max]`.
Selected variant option IDs (e.g. size, color) for products that offer them.
A single saved-contact UUID — from [`goody_contacts_search`](/mcp-reference/tools/contacts-search). Use this **or** `recipients`. Cannot be combined with `direct_send`.
The people to send to. Use this **or** `contact_id`.
Full name — split on the **first** space (first token → first name, the rest → last name). Use this or `first_name` + `last_name`.
First name. Pair with `last_name`.
Last name.
Recipient email.
Recipient phone, when sending by text.
Link this recipient to an existing saved contact.
Required on every recipient when `send_method` is `direct_send`.
Recipient first name for the shipping label.
Recipient last name for the shipping label.
Street address.
Apartment, suite, etc.
City.
State or province.
ZIP or postal code.
Country.
The note shown on the gift card. Use [`goody_messages_generate`](/mcp-reference/tools/messages-generate) to draft one.
The "From" name the recipient sees. Defaults to the authenticated user.
Whether the recipient may swap the gift. One of `single` (swap once), `multiple` (swap freely), or `disabled` (no swapping).
ISO 8601 datetime to delay sending. Must be in the future and at most 3 months out — anchor "now" to [`goody_me_get`](/mcp-reference/tools/me-get)'s `server_time`.
ISO 8601 datetime the gift expires if the recipient hasn't accepted it. **Required when paying from `BALANCE`.** The standard default is about 10 weeks. Mutually exclusive with `expires_on`.
Date alias `YYYY-MM-DD`, coerced to end of day. Mutually exclusive with `expires_at`.
Must be `true` when the cart contains alcohol.
How far the gift can ship. One of `disabled` (default; US & Canada only), `standard`, or `full` (global, 140+ countries; up to about \$55/order in taxes, tariffs, and freight).
Lets recipients outside supported regions swap their gift for a gift card.
Attach an existing custom form's recipient questions to the gift.
**Alcohol gifts** require the account to be alcohol-enabled, cannot be paid from `BALANCE`, and require `alcohol_age_verification_attested: true`.
## Returns
The created batch.
Batch UUID — pass as `order_batch_id` to [`goody_order_batches_get`](/mcp-reference/tools/order-batches-get) or [`goody_orders_list`](/mcp-reference/tools/orders-list).
The batch's public identifier.
Where the batch is in its lifecycle.
A shareable URL that renders the sent gift. **Lead your reply with this.**
Per-recipient sender-view links.
The funding source that was charged.
The payment-method UUID, or the `BALANCE` / `WORKSPACE_BALANCE` / `CORPORATE_ACCOUNT` sentinel.
Display name, e.g. "Visa 1234".
Whether and how recipients were notified. State this to the user.
Follow-on actions you can offer the user.
## Example
```text 💬 Prompt theme={null}
"Yes, send it."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_order_batches_create",
"arguments": {
"workspace_id": "3f8a…",
"confirmed": true,
"card_id": "7c20…",
"payment_method_id": "c41d…",
"product_id": "0f3c…",
"contact_id": "5b6e…",
"send_method": "email_and_link",
"message": "Thanks for everything this quarter, Sarah!",
"from_name": "Jordan at Acme"
}
}
```
```json ↩️ Result theme={null}
{
"order_batch": {
"id": "b92e…",
"public_id": "gift_2f9c…",
"status": "sent"
},
"preview_url": "https://www.ongoody.com/preview/2f9c…",
"sender_preview_urls": ["https://www.ongoody.com/s/8d41…"],
"payment_method": { "id": "c41d…", "name": "Visa 1234" },
"notification_summary": "Goody emailed Sarah Chen a link to claim her gift.",
"suggested_next_steps": [
"Track whether Sarah opens her gift with goody_orders_list.",
"Set this up to recur for future occasions with goody_autogift_rules_create."
]
}
```
Build the confirmation step with [`goody_order_batches_preview`](/mcp-reference/tools/order-batches-preview) before calling this. To make a one-off gift recurring, offer [`goody_autogift_rules_create`](/mcp-reference/tools/autogift-rules-create).
# goody_order_batches_get
Source: https://developer.ongoody.com/mcp-reference/tools/order-batches-get
Fetch full detail for a single gift batch — cart, recipients, and send timing.
**Permission:** `Read` · **Workspace:** required (from `goody_workspaces_list`)
Fetches full detail for a single gift batch — read back the cart, see who received it, or check scheduled-send timing.
## Parameters
Workspace UUID — from `goody_workspaces_list`. The batch must belong to this workspace.
Batch UUID — from [`goody_order_batches_list`](/mcp-reference/tools/order-batches-list).
## Returns
Batch UUID.
The batch's name.
Where the batch is in its lifecycle.
The "From" name recipients see.
The gift-card message.
Number of orders in the batch.
Up to 10 orders from the batch, for a quick look.
Number of recipients.
Up to 10 recipients, for a quick look.
The gift contents (products) for the batch.
Who sent the batch.
Sender's given name.
Sender's family name.
Sender's email.
True if the batch is set to send at a future time.
When the batch is scheduled to send.
When the gift expires. `null` means it does not expire on a fixed date.
How recipients are notified.
The gift card chosen for the batch.
The workspace the batch belongs to.
The workspace's name.
Caller-supplied reference, if one was set.
The sender's "see what you sent" link.
Per-recipient preview links for the sender.
## Example
```text 💬 Prompt theme={null}
"Show me the details of that batch."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_order_batches_get",
"arguments": { "workspace_id": "3f8a…", "order_batch_id": "b92e…" }
}
```
```json ↩️ Result theme={null}
{
"id": "b92e…",
"batch_name": "Q2 client thank-yous",
"send_status": "sent",
"from_name": "Jordan at Acme",
"message": "Thank you for a great quarter, {{firstname}}!",
"orders_count": 12,
"orders_preview": [
{ "id": "1c4d…", "recipient_first_name": "Sarah", "status": "accepted" }
],
"recipients_count": 12,
"recipients_preview": [
{ "first_name": "Sarah", "last_name": "Chen", "email": "sarah@acme.com" }
],
"cart": {
"items": [
{ "product_id": "0f3c…", "name": "Cold Brew Starter Kit" }
]
},
"sender": {
"first_name": "Jordan",
"last_name": "Lee",
"email": "jordan@acme.com"
},
"is_scheduled_send": false,
"scheduled_send_on": null,
"expires_at": null,
"send_method": "email",
"card_id": "a7f9…",
"workspace_id": "3f8a…",
"workspace_name": "Acme",
"reference_id": null,
"preview_url": "https://ongoody.com/g/b92e…",
"sender_preview_urls": [
"https://ongoody.com/g/b92e…/1c4d…"
]
}
```
You'll get a not-found error if the id is unknown or belongs to another workspace.
To browse other batches, use [`goody_order_batches_list`](/mcp-reference/tools/order-batches-list); to list every individual order inside this batch, use [`goody_orders_list`](/mcp-reference/tools/orders-list).
# goody_order_batches_list
Source: https://developer.ongoody.com/mcp-reference/tools/order-batches-list
List previously-sent gift batches in a workspace, most recent first.
**Permission:** `Read` · **Workspace:** required (from `goody_workspaces_list`)
Lists previously-sent gift batches in a workspace, most recent first. This is how you answer "what did I send recently?".
## Parameters
Workspace UUID — from `goody_workspaces_list`. Listing is always scoped to this workspace.
Page number, starting at `1`.
Batches per page. Defaults to `25`, max `100`.
## Returns
Batch summaries, most recent first. Each object also includes additional summary fields beyond those listed here.
Batch UUID — pass as `order_batch_id` to [`goody_order_batches_get`](/mcp-reference/tools/order-batches-get) or [`goody_orders_list`](/mcp-reference/tools/orders-list).
The batch's name.
Where the batch is in its lifecycle.
The "From" name recipients see.
The gift-card message.
Number of orders in the batch.
Number of recipients.
When the batch is scheduled to send, if scheduled.
Total number of batches across all pages.
## Example
```text 💬 Prompt theme={null}
"Show me my last few gifts."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_order_batches_list",
"arguments": { "workspace_id": "3f8a…", "per_page": 3 }
}
```
```json ↩️ Result theme={null}
{
"order_batches": [
{
"id": "b92e…",
"batch_name": "Q2 client thank-yous",
"send_status": "sent",
"from_name": "Jordan at Acme",
"message": "Thank you for a great quarter, {{firstname}}!",
"orders_count": 12,
"recipients_count": 12,
"scheduled_send_on": null
},
{
"id": "4a07…",
"batch_name": "Welcome — new hires",
"send_status": "scheduled",
"from_name": "The Acme Team",
"message": "Welcome aboard, {{firstname}}!",
"orders_count": 3,
"recipients_count": 3,
"scheduled_send_on": "2026-07-01T09:00:00Z"
}
],
"total_count": 47
}
```
For the full detail of one batch use [`goody_order_batches_get`](/mcp-reference/tools/order-batches-get); to list the individual orders inside a batch use [`goody_orders_list`](/mcp-reference/tools/orders-list).
# goody_order_batches_preview
Source: https://developer.ongoody.com/mcp-reference/tools/order-batches-preview
Build a shareable preview link and price a gift before sending — nothing is charged.
**Permission:** `Write` · **Workspace:** required (from `goody_workspaces_list`)
Builds a shareable preview link **and** prices a gift that has **not** been sent — nothing is charged, nothing is sent. This is the step that lets the user *see* the assembled gift (card, message, products) at a real URL and review the total before sending.
Lead your reply with the `preview_url`, relay the `total_price`, and only after the user confirms call [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create) with the same inputs.
There is no `payment_method_id` here — previewing neither charges nor needs a funding source.
## Parameters
Workspace UUID — from `goody_workspaces_list`. Scopes the preview to this workspace.
Card UUID — from [`goody_cards_list`](/mcp-reference/tools/cards-list). Picking a real card means the preview shows the actual card the recipient will see.
A single product UUID — from [`goody_products_search`](/mcp-reference/tools/products-search). Use this **or** `cart`, never both.
Quantity for `product_id`. Defaults to `1`.
Amount to fund, in cents, for a variable-amount Gift of Choice or variable gift card. Must fall within the gift's `[price_min, price_max]`. Only applies to `product_id`.
A multi-item cart — an object with an `items` array (not a bare array). Use this **or** `product_id`, never both.
One entry per product in the gift.
Product UUID.
Quantity of this product.
Amount in cents for a variable-amount gift, within its `[price_min, price_max]`.
Selected variant option IDs (e.g. size, color) for products that offer them.
A single saved-contact UUID — from [`goody_contacts_search`](/mcp-reference/tools/contacts-search). Use this **or** `recipients`. Optional: omit recipients entirely to preview a half-composed gift with a placeholder recipient.
The people to send to. Use this **or** `contact_id`. Optional here — omit to preview before recipients are known.
Full name — split on the **first** space (first token → first name, the rest → last name). Use this or `first_name` + `last_name`.
First name. Pair with `last_name`.
Last name.
Recipient email.
Recipient phone, when sending by text.
Link this recipient to an existing saved contact.
Required on every recipient when `send_method` is `direct_send`.
Recipient first name for the shipping label.
Recipient last name for the shipping label.
Street address.
Apartment, suite, etc.
City.
State or province.
ZIP or postal code.
Country.
The note shown on the gift card. Use [`goody_messages_generate`](/mcp-reference/tools/messages-generate) to draft one.
The "From" name the recipient sees. Defaults to the authenticated user.
How the recipient receives the gift. One of `link_single` (you share the link yourself), `email_and_link` (Goody emails each recipient their link), or `direct_send` (ships a physical product to each recipient — requires a `mailing_address` on every recipient).
## Returns
A shareable URL that renders the assembled gift — card, message, and products. **Lead your reply with this** so the user can see exactly what they're sending.
UUID of the draft batch the preview was built from.
The cart subtotal before tax and shipping.
The full total — subtotal, tax, and shipping. Relay this to the user before sending.
## Example
```text 💬 Prompt theme={null}
"Show me a preview of the Cold Brew Kit for Sarah before sending."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_order_batches_preview",
"arguments": {
"workspace_id": "3f8a…",
"card_id": "7c20…",
"product_id": "0f3c…",
"recipients": [
{ "name": "Sarah Chen", "email": "sarah@acme.com" }
],
"message": "Thanks for everything this quarter, Sarah!",
"from_name": "Jordan at Acme"
}
}
```
```json ↩️ Result theme={null}
{
"preview_url": "https://www.ongoody.com/preview/2f9c…",
"draft_batch_id": "a18d…",
"cart_price": { "subtotal": 4200, "currency": "USD" },
"total_price": { "subtotal": 4200, "tax": 357, "shipping": 0, "total": 4557, "currency": "USD" }
}
```
When the user confirms, send it with [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create) using the same inputs. For just a number without the link, use [`goody_order_batches_price`](/mcp-reference/tools/order-batches-price); to draft the card message, use [`goody_messages_generate`](/mcp-reference/tools/messages-generate).
# goody_order_batches_price
Source: https://developer.ongoody.com/mcp-reference/tools/order-batches-price
Quick price estimate — cart subtotal, tax, shipping, and total — before sending.
**Permission:** `Write` · **Workspace:** required (from `goody_workspaces_list`)
A quick price estimate — cart subtotal, tax, shipping, and total — before sending. Use it when the user just wants a number; use [`goody_order_batches_preview`](/mcp-reference/tools/order-batches-preview) for the richer confirm-against-it step that returns a shareable link. Nothing is charged.
Relay the total, the `from_name`, and the `notification_preview` before calling [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create).
## Parameters
Workspace UUID — from `goody_workspaces_list`. Scopes the estimate to this workspace.
A single product UUID — from [`goody_products_search`](/mcp-reference/tools/products-search). Use this **or** `cart`, never both.
Quantity for `product_id`. Defaults to `1`.
Amount to fund, in cents, for a variable-amount Gift of Choice or variable gift card. Must fall within the gift's `[price_min, price_max]`. Only applies to `product_id`.
A multi-item cart — an object with an `items` array (not a bare array). Use this **or** `product_id`, never both.
One entry per product in the gift.
Product UUID.
Quantity of this product.
Amount in cents for a variable-amount gift, within its `[price_min, price_max]`.
Selected variant option IDs (e.g. size, color) for products that offer them.
A single saved-contact UUID — from [`goody_contacts_search`](/mcp-reference/tools/contacts-search). Use this **or** `recipients`.
The people to send to. Use this **or** `contact_id`.
Full name — split on the **first** space (first token → first name, the rest → last name). Use this or `first_name` + `last_name`.
First name. Pair with `last_name`.
Last name.
Recipient email.
Recipient phone, when sending by text.
Link this recipient to an existing saved contact.
Required on every recipient when `send_method` is `direct_send`.
Recipient first name for the shipping label.
Recipient last name for the shipping label.
Street address.
Apartment, suite, etc.
City.
State or province.
ZIP or postal code.
Country.
How the recipient receives the gift. One of `link_single`, `email_and_link`, or `direct_send` (ships a physical product — requires a `mailing_address` on every recipient). Affects shipping in the estimate.
Whether the recipient may swap the gift. One of `single` (swap once), `multiple` (swap freely), or `disabled` (no swapping).
The "From" name the recipient sees. When the user states a From name, pass it. Defaults to the authenticated user.
Optional. A funding source — from [`goody_payment_methods_list`](/mcp-reference/tools/payment-methods-list). When supplied, the result echoes the resolved `payment_method` so the user can confirm where the charge would land.
## Returns
The cart subtotal before tax and shipping.
The full total — subtotal, tax, and shipping. Relay this to the user.
The resolved sender name. Show it to the user so they can confirm who the gift is from.
How recipients are reached for the chosen `send_method` (e.g. emailed a link, or shipped directly). State this before sending.
The resolved funding source — present only when a `payment_method_id` was supplied.
The payment-method UUID, or the `BALANCE` / `WORKSPACE_BALANCE` / `CORPORATE_ACCOUNT` sentinel.
Display name, e.g. "Visa 1234".
## Example
```text 💬 Prompt theme={null}
"How much to send the Brightland olive oil set to Jane Doe (jane@acme.com)?"
```
```json 🔧 Tool call theme={null}
{
"name": "goody_order_batches_price",
"arguments": {
"workspace_id": "3f8a…",
"product_id": "9a17…",
"recipients": [
{ "name": "Jane Doe", "email": "jane@acme.com" }
]
}
}
```
```json ↩️ Result theme={null}
{
"cart_price": { "subtotal": 5200, "currency": "USD" },
"total_price": { "subtotal": 5200, "tax": 442, "shipping": 0, "total": 5642, "currency": "USD" },
"from_name": "Jordan at Acme",
"notification_preview": "Goody will email Jane Doe a link to claim the gift.",
"payment_method": null
}
```
For a shareable preview link the user can review before sending, use [`goody_order_batches_preview`](/mcp-reference/tools/order-batches-preview). When the user confirms, send it with [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create).
# goody_orders_cancel
Source: https://developer.ongoody.com/mcp-reference/tools/orders-cancel
Cancel a single order (one recipient's gift) before the recipient accepts it.
**Permission:** `Write` · **Workspace:** required (from `goody_workspaces_list`)
Cancels a single order — one recipient's gift.
This is irreversible — it releases the recipient's payment hold and refunds any applied credit. Only orders the recipient has **not** yet accepted can be canceled.
To cancel a whole batch, call this once per order id from [`goody_orders_list`](/mcp-reference/tools/orders-list).
## Parameters
Workspace UUID — from `goody_workspaces_list`. Scopes the cancellation to this workspace.
The order to cancel — an order id from a [`goody_orders_list`](/mcp-reference/tools/orders-list) result.
## Returns
The order id that was canceled.
The order status after cancellation.
A person can also self-serve cancellations on the Goody Track page.
## Example
```text 💬 Prompt theme={null}
"Cancel the gift I sent to that wrong address."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_orders_cancel",
"arguments": {
"workspace_id": "3f8a…",
"order_id": "d72b…"
}
}
```
```json ↩️ Result theme={null}
{
"id": "d72b…",
"status": "canceled"
}
```
Find the order id with [`goody_orders_list`](/mcp-reference/tools/orders-list); for the full detail of the batch it belongs to, use [`goody_order_batches_get`](/mcp-reference/tools/order-batches-get).
# goody_orders_list
Source: https://developer.ongoody.com/mcp-reference/tools/orders-list
List individual orders (one per recipient), across a workspace or within one batch.
**Permission:** `Read` · **Workspace:** required (from `goody_workspaces_list`)
Lists individual orders — one per recipient. Without `order_batch_id`, it lists all orders in the workspace, newest first. With it, it lists the orders in that batch, oldest first.
## Parameters
Workspace UUID — from `goody_workspaces_list`. Listing is always scoped to this workspace.
Optional filter to one batch — from [`goody_order_batches_list`](/mcp-reference/tools/order-batches-list). Omit to list all orders in the workspace.
Page number, starting at `1`.
Orders per page. Defaults to `25`, max `100`.
## Returns
The matching orders, one per recipient.
Order UUID — pass as `order_id` to [`goody_orders_cancel`](/mcp-reference/tools/orders-cancel).
Where the order is in its lifecycle.
Recipient's given name.
Recipient's family name.
Recipient's email.
The gift card chosen for this order.
The gift-card message.
The gift contents (products).
The order's monetary breakdown.
Shipment records for the order, if any.
Who sent the order.
The workspace the order belongs to.
The batch this order belongs to.
Caller-supplied reference, if one was set.
Total number of orders across all pages.
## Example
```text 💬 Prompt theme={null}
"Who received the gifts in that batch?"
```
```json 🔧 Tool call theme={null}
{
"name": "goody_orders_list",
"arguments": { "workspace_id": "3f8a…", "order_batch_id": "b92e…" }
}
```
```json ↩️ Result theme={null}
{
"orders": [
{
"id": "1c4d…",
"status": "accepted",
"recipient_first_name": "Sarah",
"recipient_last_name": "Chen",
"recipient_email": "sarah@acme.com",
"card_id": "a7f9…",
"message": "Thank you for a great quarter, Sarah!",
"cart": { "items": [{ "product_id": "0f3c…", "name": "Cold Brew Starter Kit" }] },
"amounts": { "subtotal": 4200, "total": 4620 },
"shipments": [],
"sender": { "first_name": "Jordan", "last_name": "Lee", "email": "jordan@acme.com" },
"workspace_id": "3f8a…",
"order_batch_id": "b92e…",
"reference_id": null
}
],
"total_count": 12
}
```
You'll get a not-found error if `order_batch_id` references a batch outside the resolved workspace.
For the batch as a whole — cart, "From" name, send timing — use [`goody_order_batches_get`](/mcp-reference/tools/order-batches-get); to cancel an order that hasn't been accepted yet, use [`goody_orders_cancel`](/mcp-reference/tools/orders-cancel).
# goody_payment_methods_list
Source: https://developer.ongoody.com/mcp-reference/tools/payment-methods-list
List the payment methods the user can charge for a gift in a workspace.
**Permission:** `Read` · **Workspace:** required (from `goody_workspaces_list`)
Lists the payment methods the user can charge for a gift in the given workspace. Call this before sending so the user can confirm the funding source.
## Parameters
Workspace UUID — from `goody_workspaces_list`. Gates access to the user's payment methods.
## Returns
The payment methods available in this workspace.
A payment-method UUID, or the literal `BALANCE` or `CORPORATE_ACCOUNT`. Pass as `payment_method_id` to [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create).
Display name, e.g. "Visa 1234", "Balance", or "Corporate Account".
Name on the card, when applicable.
Cents available to spend. Present only for `BALANCE` and `CORPORATE_ACCOUNT`.
## Example
```text 💬 Prompt theme={null}
"What can I pay with?"
```
```json 🔧 Tool call theme={null}
{
"name": "goody_payment_methods_list",
"arguments": { "workspace_id": "3f8a…" }
}
```
```json ↩️ Result theme={null}
{
"items": [
{
"id": "c41d…",
"name": "Visa 1234",
"cardholder_name": "Jordan Lee",
"balance": null
},
{
"id": "BALANCE",
"name": "Balance",
"cardholder_name": null,
"balance": 25000
},
{
"id": "CORPORATE_ACCOUNT",
"name": "Corporate Account",
"cardholder_name": null,
"balance": 480000
}
]
}
```
Confirm the funding source with the user, then pass the chosen `id` as `payment_method_id` to [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create).
# goody_products_get
Source: https://developer.ongoody.com/mcp-reference/tools/products-get
Fetches full detail for a single product, richer than a search result.
**Permission:** `Read` · **Workspace:** not required (global)
Fetches full detail for a single product — richer than a search result. Use it when the user is close to committing and you need the description, shipping tier, alcohol status, or US state restrictions.
## Parameters
Product UUID, from a [`goody_products_search`](/mcp-reference/tools/products-search) result.
## Returns
Product UUID.
Product name.
Brand name.
Opaque image key for the product photo.
Price in cents for fixed-price products.
Full product description.
Extra image keys beyond the primary photo.
`domestic_us`, `international`, or `any`.
True if the product contains alcohol (extra requirements apply to send).
US state codes where this product can't ship.
`fixed`, `variable`, or `tiers`.
True for a Gift of Choice (recipient picks; sender funds an amount).
Lowest amount (cents) the sender may fund, for a Gift of Choice.
Highest fundable amount; `null` means unlimited.
Returns a not-found error if the product id is unknown, private, or inactive.
## Example
```text 💬 Prompt theme={null}
"Tell me more about the Cold Brew Starter Kit."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_products_get",
"arguments": { "product_id": "0f3c…" }
}
```
```json ↩️ Result theme={null}
{
"id": "0f3c…",
"name": "Cold Brew Starter Kit",
"brand": "Grady's",
"image_key": "products/cold-brew-starter-kit.png",
"price_cents": 4200,
"description": "Everything to brew smooth cold brew at home: a glass carafe, a reusable filter, and two pouches of coarse-ground beans.",
"additional_images": [
"products/cold-brew-starter-kit-2.png",
"products/cold-brew-starter-kit-3.png"
],
"shipping_tier": "domestic_us",
"alcohol": false,
"restrictions": [],
"price_type": "fixed",
"is_flex_gift": false,
"price_min": null,
"price_max": null
}
```
Pair with [`goody_products_search`](/mcp-reference/tools/products-search) to discover products, or [`goody_gift_of_choice_list`](/mcp-reference/tools/gift-of-choice-list) when the recipient's taste is unknown.
# goody_products_search
Source: https://developer.ongoody.com/mcp-reference/tools/products-search
Search Goody's catalog by intent, budget, and filters — returns up to 5 curated matches.
**Permission:** `Read` · **Workspace:** not required (global catalog)
Searches Goody's product catalog and returns up to **5** candidate products. There's no pagination — to refine, call again with tighter filters. This is the discovery half of the gifting flow.
Most results are fixed-price SKUs. Some are a **Gift of Choice** (`price_type` `variable`, `is_flex_gift` true): the recipient picks from a curated set and the sender funds any amount within `[price_min, price_max]`. To list Gifts of Choice directly, use [`goody_gift_of_choice_list`](/mcp-reference/tools/gift-of-choice-list).
## Parameters
Free-text intent — recipient interests, vibe, or occasion (e.g. "tea lover", "Vermont maple syrup"). Matched across product name, description, and brand.
Minimum price, in cents (e.g. `2500` for \$25). Strings are accepted and coerced.
Maximum price, in cents.
Defaults to true. Set false only if the user explicitly asked for alcohol gifts.
One of `domestic_us` (default), `international` (recipient outside the US), or `any`.
UUID of a Goody category. Advanced — usually omitted.
## Returns
Up to 5 matching products.
Product UUID — pass as `product_id` to [`goody_products_get`](/mcp-reference/tools/products-get), [`goody_order_batches_preview`](/mcp-reference/tools/order-batches-preview), or [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create).
Product name.
Brand name.
Opaque image key for the product photo.
Price in cents for fixed-price products.
`fixed`, `variable`, or `tiers`.
True for a Gift of Choice (recipient picks; sender funds an amount).
Lowest amount (cents) the sender may fund, for a Gift of Choice.
Highest fundable amount; `null` means unlimited.
True if the product contains alcohol (extra requirements apply to send).
## Example
```text 💬 Prompt theme={null}
"Find a thank-you gift under $50 for a client who loves coffee."
```
```json 🔧 Tool call theme={null}
{
"name": "goody_products_search",
"arguments": { "query": "coffee gift for a client", "price_max": 5000 }
}
```
```json ↩️ Result theme={null}
{
"products": [
{
"id": "0f3c…",
"name": "Cold Brew Starter Kit",
"brand": "Grady's",
"image_key": "products/cold-brew-starter-kit.png",
"price_cents": 4200,
"price_type": "fixed",
"is_flex_gift": false,
"price_min": null,
"price_max": null,
"alcohol": false
},
{
"id": "9a17…",
"name": "Single-Origin Coffee Trio",
"brand": "Driftaway Coffee",
"image_key": "products/coffee-trio.png",
"price_cents": 3600,
"price_type": "fixed",
"is_flex_gift": false,
"price_min": null,
"price_max": null,
"alcohol": false
}
]
}
```
Pair with [`goody_products_get`](/mcp-reference/tools/products-get) for richer detail before committing, or
[`goody_gift_of_choice_list`](/mcp-reference/tools/gift-of-choice-list) when the recipient's taste is unknown — let them pick.
# goody_workspaces_list
Source: https://developer.ongoody.com/mcp-reference/tools/workspaces-list
Lists the Goody workspaces the connected user can gift from.
**Permission:** `Read` · **Workspace:** not required (global)
Lists the Goody workspaces the connected user belongs to. Call before any tool that creates, updates, or sends gifts — they all require an explicit `workspace_id`, and this is the only way to discover valid ones.
## Parameters
This tool takes no arguments.
## Returns
The workspaces the connected user belongs to.
Workspace UUID — pass as `workspace_id` to any tool that requires one.
Workspace name.
## Example
```text 💬 Prompt theme={null}
"What workspaces can I send gifts from?"
```
```json 🔧 Tool call theme={null}
{
"name": "goody_workspaces_list",
"arguments": {}
}
```
```json ↩️ Result theme={null}
{
"workspaces": [
{ "id": "0f3c…", "name": "Northwind Trading" },
{ "id": "9a17…", "name": "Northwind Labs" }
]
}
```
Start a session with [`goody_me_get`](/mcp-reference/tools/me-get) to confirm the account, then pass a `workspace_id` from here to tools like [`goody_collections_list`](/mcp-reference/tools/collections-list) or [`goody_order_batches_create`](/mcp-reference/tools/order-batches-create).
# Authentication & permissions
Source: https://developer.ongoody.com/mcp/authentication
How the Goody MCP server authenticates — OAuth for interactive clients, personal tokens for scripts and automations — and what the Read, Write, and Send gifts permissions allow.
The Goody MCP server supports two ways to authenticate, both built on the same permissions and safeguards. Interactive AI clients use **OAuth**; scripts and automations use a **personal MCP token**. Either way, what a connection can do is governed by the three permissions below — and **Send gifts** is the only one that can spend money.
## Two ways to connect
Claude (web, desktop, mobile), Cursor, ChatGPT's MCP support, and other interactive AI clients connect through **OAuth** — authorization code flow with PKCE, refresh tokens, and Dynamic Client Registration. You add Goody as a connector, sign in once in the browser, and approve the permissions; the client then stores and silently refreshes short-lived tokens. There's nothing to paste into a config file.
This is the [Connect](/mcp/connect) path — use it for any client a person drives in a chat. Manage these connections in **Goody for Business → account settings → Connect AI tools**.
For scripts, n8n / Zapier / Make workflows, cron jobs, or headless agent frameworks — anywhere a browser sign-in isn't an option — mint a **personal MCP token** in **Goody for Business → account settings → Personal MCP token**, and paste it together with the [server URL](/mcp/connect) into your client's config.
When you create a token you choose:
* a **name** (e.g. "Zapier — Marketing") so you can identify and revoke it later,
* its **scopes** — any of `mcp.read`, `mcp.write`, `mcp.gifts` (see [Permissions](#permissions)), and
* an **expiry** — 30 days, 90 days (recommended), 1 year, or no expiry.
The full token is shown **once**, at creation — store it somewhere safe. You can hold several active tokens and revoke any of them at any time.
It's the same server, the same scopes, and the same enforcement either way — the only difference is how the credential is obtained.
## Permissions
Whether granted via OAuth consent or selected as a token's scopes, a connection carries one or more of three permissions:
| Permission | Scope | What it allows |
| -------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Read** | `mcp.read` | See your account basics — profile, workspaces, contacts, contact lists, past gifts and orders, and saved payment methods (display names only, never card numbers) — and browse Goody's gift catalog and greeting cards. |
| **Write** | `mcp.write` | Create and edit things that don't cost money: add or update contacts, create contact lists, cancel an unaccepted order, and price or preview a gift before sending. Preview/price need Write because they build a draft order to estimate the total — a create-style preview, not a charge. |
| **Send gifts** | `mcp.gifts` | Send gifts and activate recurring autogifts using your payment methods. **This is the only permission that can spend money.** With an interactive client a person still confirms each send; with an unattended token, this is the permission that lets an automation spend on your behalf — see [Automatic & agentic sends](/mcp/gifting-flow#automatic--agentic-sends). |
Pricing and previewing a gift never charge anything — they're free. Only the **Send
gifts** permission moves money. Grant it only to connections or tokens you intend to let spend.
## Spending limits
Beyond per-gift confirmation, gifts sent through AI connectors are held under a **rolling daily spend limit** for your account. You can review and adjust it — including raising it, lowering it, or setting it to zero to block AI-initiated spend entirely — in **Goody for Business → account settings → [Connect AI tools](#disconnecting)**. The limit applies across every AI tool and token you connect, not per connection — so it backstops unattended automations as well as interactive sessions.
## Disconnecting
You're in control of every connection from either side:
* **From Goody:** open **Goody for Business → account settings**. **Connect AI tools** lists every OAuth-connected AI tool — when it connected and its permissions — with **Disconnect** to revoke it instantly. **Personal MCP token** lists your active tokens, each with **Revoke**.
* **From the client:** remove or disable the Goody connector in the client's settings (in Claude: **Settings → Connectors**), or delete the token from your script's config.
A disconnected tool or revoked token must be re-authorized — or a new token minted — before it can access your account again.
# Connect Goody to Claude
Source: https://developer.ongoody.com/mcp/connect
Add Goody to Claude as a custom connector using the server URL. (Directory listing is rolling out.)
You can connect Goody to Claude — or any MCP-compatible client — by adding it as a custom connector with the server URL.
The Claude Connectors Directory listing is rolling out — for now, add Goody as a
custom connector below.
## Add Goody as a custom connector
Any MCP client that supports remote OAuth servers can add Goody by URL — Claude (web, desktop, and mobile) and others. Point the client at the server URL and complete OAuth sign-in. In Claude specifically, use the steps below; in another client, add a custom/remote MCP server with the same URL.
In claude.ai, go to **Settings → Connectors → Add custom connector**. In another MCP client, open its custom or remote MCP server settings.
```text theme={null}
https://api.ongoody.com/mcp/v1
```
You'll be redirected to Goody to sign in — or to create a Goody for Business account if you don't have one.
Review the permissions Goody requests and click **Authorize**. Goody now appears as a connected tool — start a new chat and try an [example prompt](/mcp-reference/example-prompts).
The Goody MCP server publishes the standard OAuth authorization-server and
protected-resource metadata, so any compliant client discovers the
authorization, token, and registration endpoints from the URL alone — there's
nothing to configure by hand.
A Goody for Business account is required. The Goody MCP server acts only within
the Goody workspaces you're a member of, and gifts you send appear in your Goody
dashboard exactly like gifts sent from the website.
## Connect a script or automation
For scripts, n8n / Zapier / Make workflows, cron jobs, or headless agent frameworks — anywhere a browser-based OAuth sign-in isn't an option — connect with a **personal MCP token** instead.
In Goody for Business, go to **account settings → Personal MCP token**. Give it a name, choose its [scopes](/mcp/authentication#permissions) (Read / Write / Send gifts), and pick an expiry. The token is shown **once** — copy it now.
Point your MCP client at the server URL and pass the token in an `Authorization: Bearer` header. Both are required.
```json Streamable HTTP client theme={null}
{
"mcpServers": {
"goody": {
"url": "https://api.ongoody.com/mcp/v1",
"headers": {
"Authorization": "Bearer YOUR_PERSONAL_MCP_TOKEN"
}
}
}
}
```
```json Via mcp-remote (stdio-only clients) theme={null}
{
"mcpServers": {
"goody": {
"command": "npx",
"args": [
"-y", "mcp-remote",
"https://api.ongoody.com/mcp/v1",
"--header", "Authorization: Bearer YOUR_PERSONAL_MCP_TOKEN"
]
}
}
}
```
Use the direct Streamable HTTP form when your client supports remote MCP servers with custom headers. Use the [`mcp-remote`](https://www.npmjs.com/package/mcp-remote) bridge for clients that only speak stdio.
A personal MCP token is a credential — anyone with it can act with the scopes you granted, including spending money if you selected **Send gifts**. Store it like a password, scope it to only what the automation needs, and revoke it from the same page if it's exposed.
See [Authentication & permissions](/mcp/authentication) for how the two methods compare and what each permission allows.
## Supported clients
Any MCP client that supports remote servers works. **Interactive clients** (Claude on web, desktop, and mobile; Cursor; ChatGPT's MCP support) connect over OAuth with no setup beyond the server URL. **Scripts and automations** connect with a personal MCP token. The server uses the standard Streamable HTTP transport, so no local proxy or command-line setup is required.
# Data handling & support
Source: https://developer.ongoody.com/mcp/data-handling
What Goody records about MCP usage, what it never stores, and how to reach support.
The Goody MCP server is deliberately thin on what it keeps. It records enough to operate the service and understand usage — and nothing about the content of your conversation.
## What Goody records
For each tool call, Goody stores a single usage record containing:
* the **tool name** (e.g. `goody_products_search`),
* the **permission** it ran under (Read / Write / Send gifts),
* the **outcome** — success or error, and the error type if it failed,
* how **long** it took, and
* for money-spending tools, a few **non-identifying numbers** — such as an estimated amount and the resulting gift-batch reference — used to track spend.
This is operational telemetry: it powers metrics, debugging, and the spend safeguards.
## What Goody never stores
* Your **conversation** or prompts.
* The **arguments** you pass to tools — recipient names, emails, phone numbers, mailing addresses, or card-message text.
* Any **free-text** content. The usage record is restricted to small, non-identifying values by design, so personal data can't leak into it.
Gifts you actually send are, of course, recorded in your Goody account — the same way a gift sent from the website is — so they appear in your dashboard, receipts, and order history. That's your account data, not MCP telemetry.
For full details on how Goody handles personal data, see the [Goody Privacy Policy](https://www.ongoody.com/legal/privacy-policy).
## Support
Questions, issues, or feedback about the Goody MCP server? Email [support@ongoody.com](mailto:support@ongoody.com). You can also send feedback to the Goody team directly from a conversation — just ask the assistant to pass it along.
# The gifting flow
Source: https://developer.ongoody.com/mcp/gifting-flow
How a gift goes from idea to sent through the Goody MCP server, and how the spend-confirmation safeguards work.
A send moves through a few clear steps. The assistant orchestrates them for you — this is what's happening under the hood.
The assistant searches the catalog by your intent, budget, and occasion (returning up to **5 strong matches**), and can also offer a **Gift of Choice** the recipient picks themselves.
Pick a greeting card and an optional card message (the assistant can draft a few), choose the recipient, and select a payment method.
The assistant builds a **preview link** — a real page showing the assembled gift (card, message, products) — and prices it in full: subtotal, shipping, and estimated tax. Nothing is charged. This is the step you confirm against: you see exactly what the recipient will get, and the total, before anything happens.
Only after you say yes does the assistant send the gift. It returns the same preview link plus a one-line summary of whether and how the recipient was notified.
Need just a number? The assistant can run a quick **price estimate** at any time without building a preview. The preview is the richer, confirm-against-it step — it returns the link, the price, the From name, the payment method, and how recipients are notified, all in one.
## How recipients receive a gift
You choose one of three send methods, and the assistant tells you which it's using — because each reaches the recipient differently:
* **Gift link you share** — the recipient is *not* automatically notified; you get a link to send them yourself.
* **Email** — Goody emails each recipient a notification with their gift link.
* **Direct shipping** — Goody ships the physical product straight to a mailing address you provide (no email). US addresses today.
For the link and email methods, recipients don't need to share an address up front: they enter their own shipping details when they accept, and can swap the gift for something else — unless you disable swapping.
## How spending is protected
Nothing is charged without you seeing the price and confirming. This is enforced in a few layers:
* **In the Goody MCP server.** The send action cannot run until a price has been presented and you've confirmed it. Recurring autogifts are always created **paused** — they can't spend anything until you explicitly activate them.
* **In the client.** The money-spending actions are flagged as sensitive, so Claude asks your permission before running them rather than acting silently.
* **A daily spend cap.** Gifts sent through AI connectors are held under a rolling daily spend limit, which you can review and adjust (including turning it off, or down to zero) in **Goody for Business → account settings → Connect AI tools**.
Other defaults worth knowing:
* **US shipping is the default.** If your recipient is outside the US, say so — the assistant searches international-friendly gifts and enables global delivery.
* **Alcohol is excluded by default** unless you explicitly ask for it (alcohol gifts require age attestation and a card payment, and can't be paid from Balance).
* **Sending doesn't auto-save recipients** as contacts — the assistant offers to, and only saves if you agree.
## Scheduling, expiration, and payment
* **Schedule for later.** Ask to send on a future date and the assistant schedules it — any time in the next 3 months.
* **Expiration.** A gift link can expire if the recipient hasn't accepted it. The assistant asks rather than guessing; Goody's standard window is about 10 weeks. (An expiration date is required when you pay from your Goody Balance.)
* **Payment source.** Pay with a saved card, your **Goody Balance**, or a **Corporate Account**. The assistant shows you which funding source it will charge before you confirm.
## Recurring gifts (autogifts)
An autogift is a rule: "every year on this person's birthday or work anniversary, send this gift." You can create one two ways:
* **Clone a past send** — reuse a gift you've already sent (same gift, card, message, and payment method).
* **Build from scratch** — no prior send required: pick a product, card, message, and payment method, and the assistant assembles the rule directly.
Autogifts are always **created paused**. Before activating, ask the assistant to **preview** the rule — it shows the card, message, product, and the expected per-send cost. Activating one re-checks that the gift is still available and the payment method still works. Supported triggers today: **birthday**, **work anniversary**, and **employee onboarding**.
## Automatic & agentic sends
Not every send has a human watching. A gift might go out from a scheduled send, a recurring autogift, or a Claude routine running on its own. Confirmation can't happen at the moment of sending then — so approval moves earlier, and the spending limit backstops it.
There are two modes:
* **Human in the loop** — the everyday case. The assistant previews the gift, you confirm the price, and only then does it send. You approve *each* send.
* **Unattended** — a scheduled send, an autogift, or an autonomous agent or routine (see [how clients authenticate](/mcp/authentication#two-ways-to-connect)). You approve *once, up front*; the gift sends later with no one watching.
For an unattended send, your confirmation is the consent you give before it ever runs, in three layers:
1. **The permission you granted.** The connection must carry the **Send gifts** permission — granted when you authorize an interactive client over OAuth, or selected as a scope when you mint a [personal MCP token](/mcp/authentication#two-ways-to-connect) for a script, cron job, or headless agent. Without it, the agent can preview and price, but never send.
2. **The automation you set up.** Activating an autogift, scheduling a send, or writing a routine's standing instructions *is* your advance approval of what gets sent and when. For autogifts, **activation** — not creation — is the commit point: rules are created paused and preview their cost first.
3. **The spending limit.** The rolling daily cap (set in **Connect AI tools**) bounds total spend however a send is triggered, so an automation that misbehaves can't run away.
**Worked example.** You ask Claude to run a daily routine: *"Every morning, check my calendar; if it's a direct report's birthday, send them a \$50 gift of choice with a warm note."* When it fires next Tuesday you aren't there, so there's no per-gift "send it?" prompt. Your confirmation already happened — you granted **Send gifts** when you connected, you wrote the routine's rule, and your daily spend cap limits the exposure if something goes wrong. The agent assembles and sends each gift on its own, within those bounds.
A calendar- or routine-driven send like that is the **agent** acting autonomously — distinct from a Goody **autogift**, which only triggers on a birthday, work anniversary, or onboarding date and is fired by Goody itself. Reach for an autogift when the occasion is one of those three; use a routine or your own agent for anything else.
# Goody MCP Server
Source: https://developer.ongoody.com/mcp/overview
Send and manage business gifts directly from Claude and other MCP clients — discover a gift, write the card, see the price, and send, all in one conversation.
The **Goody MCP server** brings Goody's business gifting platform into Claude and any other [Model Context Protocol](https://modelcontextprotocol.io) client. Once connected, you can ask the assistant to find the right gift for a budget and occasion, draft the card message, show you the exact price, and send the gift — without ever needing the recipient's mailing address.
It's not just one-off sends. The assistant can also manage the work around a send — look up and save contacts, organize them into lists, review past gifts and orders, and set up recurring "autogifts." Anything that spends money always works the same way: **you see the full price first, and nothing is charged until you say yes.**
## Endpoint
```text Production theme={null}
https://api.ongoody.com/mcp/v1
```
```text Sandbox theme={null}
https://api.sandbox.ongoody.com/mcp/v1
```
The server speaks the standard MCP **Streamable HTTP** transport. Interactive clients (Claude, Cursor, …) authenticate with OAuth — they need only the URL above and walk you through sign-in. Scripts and automations connect with a personal token instead. See [Authentication](/mcp/authentication).
## Sandbox vs production
The two endpoints are independent environments backed by separate Goody for Business accounts. Sign in to production to send real gifts; sign in to sandbox to test sends without being charged. Point your MCP client at the environment you want and authorize with that environment's account — sign-in is per-environment, and credentials and data do not carry over between the two.
## What you can do
Search the catalog by intent, budget, and occasion; browse curated collections and greeting cards; or offer a Gift of Choice the recipient picks themselves.
Preview the assembled gift, review the total, and send by link, email, or direct shipping — only after you confirm.
Find, create, and update workspace contacts and organize them into lists.
Turn a past send into a birthday, work-anniversary, or onboarding autogift — always created paused until you activate it.
## Get started
Add Goody in Claude from the connectors directory or as a custom connector.
How OAuth sign-in works and what the Read / Write / Send gifts permissions mean.
How a gift goes from idea to sent — and how the spend-confirmation safeguards work.
Real prompts that work today, with illustrative responses.
## Tools
The server exposes **28 tools** across discovery, contacts, sending, and automation. See the [tool reference](/mcp-reference/tools) for the full list and the permission each one requires.
## Data & support
The Goody MCP server records only non-identifying usage telemetry — never your conversation or tool arguments. See [Data handling](/mcp/data-handling) for specifics and how to reach support.
# Changelog
Source: https://developer.ongoody.com/resources/changelog
Updates to the Goody API and MCP server
### June 25, 2026
* **Goody MCP server (beta).** Connect Goody to Claude and other MCP clients to send and manage gifts in conversation — discover gifts, draft a card message, preview and price a gift, and send with your confirmation, plus contacts and recurring autogifts. See the [MCP overview](/mcp/overview).
### June 3, 2026
* Add [customer\_reference\_id](https://developer.ongoody.com/api-reference/order-batches/create-an-order-batch#body-customer-reference-id-one-of-0) to OrderBatch, a unique/idempotent ID where you can store an ID reference to your own system.
### November 5, 2025
* Add endpoints for [fetching all collections (/v1/collections)](/api-reference/collections/list-all-collections) and [retrieving a single collection (/v1/collections/:id)](/api-reference/collections/retrieve-a-collection).
### May 21, 2025
* Add the [Embedded Payment Form](/commerce-api/embedded-payment-form) payment type for the Commerce API.
* Add [Create a commerce user payment method (/v1/commerce\_user\_payment\_methods)](/api-reference/commerce-user-payment-methods/create-a-commerce-user-payment-method).
### September 10, 2024
* Add `custom_catalog_show_inactive` parameter to the [List all active products (/v1/products)](https://developer.ongoody.com/api-reference/products/list-all-active-products) endpoint (Commerce API custom catalogs only).
* Add `updated_at` and `status` (Commerce API custom catalogs only) fields to the [Product schema](https://developer.ongoody.com/api-reference/schemas/product). `status` is only for custom catalogs; by default, all products returned are active, unless when using the `custom_catalog_show_inactive` parameter.
### August 28, 2024
* Add `variant_groups` field to the Product schema.
### August 8, 2024
* Add `international_shipping_tier` and `international_gift_cards_enabled` fields to Order Batch Create payload.
# Event: order.canceled
Source: https://developer.ongoody.com/webhooks/events/order.canceled
Emitted when an order has been canceled.
## Example
```json theme={null}
{
"event_type": "order.canceled",
"id": "ad097c47-bf12-45c9-8feb-0536a0012c09",
"data": {
"id": "8999f804-d731-440d-a67d-35444c12c493",
"status": "failed",
"individual_gift_link": "https://gifts.ongoody.com/gift/IsDyQQWtqrOyGPgZ9bVm6ptz",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"card_id": "7e79fd96-212b-4468-9989-57b896ca22f4",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "d158184c-6b31-4a72-b39f-8f8ca04ecbdd",
"expires_at": null,
"cart": {
"id": "3ff7dab1-ae03-4b20-a2c8-82a3f3326b83",
"items": [
{
"id": "284dc74f-a2c4-4b62-bfe5-94c464d56ea7",
"quantity": 1,
"product": {
"id": "10227d72-c355-4881-8007-aad34f501055",
"name": "Cookies",
"brand": {
"id": "fe370ec6-1208-4d23-b936-de857ceeae6d",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15551494889@test.ongoody.com"
},
"workspace_id": "dfe0d5cb-2c98-4800-a950-b40cca509250",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "2MUPN0YMGIDT7TJNPPFPB7WE"
}
}
```
## Schema
The type of event that occurred
The unique ID for this event
An individual order contains the gift link to be sent to the recipient (if applicable) and other information about the order.
Allowed values: `created` `notified` `opened` `accepted`
`pending_payment` `paid` `ordered` `shipped` `delivered` `failed`
`canceled`
This gift link can be sent to the recipient or shared with the sender.
For privacy reasons, this gift link does not display tracking
information. A separate link, the recipient link, is sent directly to
the recipient after they accept their gift, which does contain
tracking information.
The cart currently on this order. If the order is a gift that was
swapped, `cart` displays the most recent products selected (i.e.
post-swap).
The brand that this product is from.
A list of the shipments for the order.
Allowed values: `pending` `tracking` `shipped` `delivered` `delivered_override` `failed` `failed_unset_tracking` `failed_with_reship`
The name of the brand that this shipment is from
The carrier for this shipment, e.g. UPS.
Only for approved distribution partners.
ISO 8601
ISO 8601
The estimated delivery time of this shipment.
Organizations are sub-divided into workspaces. Orders are contained in workspaces, identified by this ID.
For gifts, the date and time the gift is set to expire.
The digital greeting card on this gift.
The message in this gift, provided by the sender.
A thank you note sent by the recipient.
The number of times the recipient viewed the gift.
If this gift was swapped by the recipient. Swapping allows a recipient to select another product or products, which replaces the `cart`. The original products are saved to `original_cart`.
On Goody for Business, all orders are attached to a order batch, which is a collection of one or more orders.
Costs in USD cents (i.e. \$1.00 = 100). If the order was swapped, `amounts` displays the most recent amounts (i.e. post-swap).
Total cost of the products in this order.
Total cost of shipping for this order.
Total cost of processing fees for this order.
Total amount of credit applied to this order.
Total cost of the products, shipping, and processing fees in this order.
Total tax for this order.
Total cost of the products, shipping, processing fees, tax, and global shipping costs in this order.
Total cost of global shipping for this order through the Global Relay service.
Only provided when calling the /orders/:id endpoint.
ISO 8601
When the recipient was notified of the order.
For gifts, when the recipient opened the order.
For gifts, when the recipient accepted the order.
When the order entered pending payment status.
When the order was paid for.
When the order was first shipped. If there are multiple shipments, this is when the first shipment shipped.
When the order was delivered. If there are multiple shipments, this is when all shipments were delivered.
If this order is a gift that was swapped, this displays the original cart that was sent to the recipient.
The brand that this product is from.
If this order is a gift that was swapped, this displays the original amounts of the cart that was sent to the recipient.
The Goody user who sent this order.
The reference ID displayed on receipts and other locations as the ID for this order.
# Event: order.created
Source: https://developer.ongoody.com/webhooks/events/order.created
Emitted when an order has been created and is ready to be opened and accepted (if it's a gift). An individual gift link is available (`individual_gift_link`).
## Example
```json theme={null}
{
"event_type": "order.created",
"id": "ad097c47-bf12-45c9-8feb-0536a0012c09",
"data": {
"id": "10c588dd-d566-45bf-86e9-c23bd1f1587b",
"status": "created",
"individual_gift_link": "https://gifts.ongoody.com/gift/vWtUe8lQRJuoyYzKlYeHMkbV",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"card_id": "ae4cb4ce-75fc-4782-a9ab-2f30d9b7b41d",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "4133078a-c35f-441e-8e92-57645342b299",
"expires_at": null,
"cart": {
"id": "39b04e91-6a40-468d-8ed4-f59e9059afae",
"items": [
{
"id": "d59dead0-a44c-44df-885f-030612038a48",
"quantity": 1,
"product": {
"id": "c399bafb-3fbc-40c5-bef3-9158b7a19abc",
"name": "Cookies",
"brand": {
"id": "db631527-c59c-409c-823f-42a24c972283",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15556038009@test.ongoody.com"
},
"workspace_id": "8779bb01-ca47-4e9e-a845-d05f509c4be3",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "PCI7GLZ3KFIEN8MWWSD5LDCF"
}
}
```
## Schema
The type of event that occurred
The unique ID for this event
An individual order contains the gift link to be sent to the recipient (if applicable) and other information about the order.
Allowed values: `created` `notified` `opened` `accepted`
`pending_payment` `paid` `ordered` `shipped` `delivered` `failed`
`canceled`
This gift link can be sent to the recipient or shared with the sender.
For privacy reasons, this gift link does not display tracking
information. A separate link, the recipient link, is sent directly to
the recipient after they accept their gift, which does contain
tracking information.
The cart currently on this order. If the order is a gift that was
swapped, `cart` displays the most recent products selected (i.e.
post-swap).
The brand that this product is from.
A list of the shipments for the order.
Allowed values: `pending` `tracking` `shipped` `delivered` `delivered_override` `failed` `failed_unset_tracking` `failed_with_reship`
The name of the brand that this shipment is from
The carrier for this shipment, e.g. UPS.
Only for approved distribution partners.
ISO 8601
ISO 8601
The estimated delivery time of this shipment.
Organizations are sub-divided into workspaces. Orders are contained in workspaces, identified by this ID.
For gifts, the date and time the gift is set to expire.
The digital greeting card on this gift.
The message in this gift, provided by the sender.
A thank you note sent by the recipient.
The number of times the recipient viewed the gift.
If this gift was swapped by the recipient. Swapping allows a recipient to select another product or products, which replaces the `cart`. The original products are saved to `original_cart`.
On Goody for Business, all orders are attached to a order batch, which is a collection of one or more orders.
Costs in USD cents (i.e. \$1.00 = 100). If the order was swapped, `amounts` displays the most recent amounts (i.e. post-swap).
Total cost of the products in this order.
Total cost of shipping for this order.
Total cost of processing fees for this order.
Total amount of credit applied to this order.
Total cost of the products, shipping, and processing fees in this order.
Total tax for this order.
Total cost of the products, shipping, processing fees, tax, and global shipping costs in this order.
Total cost of global shipping for this order through the Global Relay service.
Only provided when calling the /orders/:id endpoint.
ISO 8601
When the recipient was notified of the order.
For gifts, when the recipient opened the order.
For gifts, when the recipient accepted the order.
When the order entered pending payment status.
When the order was paid for.
When the order was first shipped. If there are multiple shipments, this is when the first shipment shipped.
When the order was delivered. If there are multiple shipments, this is when all shipments were delivered.
If this order is a gift that was swapped, this displays the original cart that was sent to the recipient.
The brand that this product is from.
If this order is a gift that was swapped, this displays the original amounts of the cart that was sent to the recipient.
The Goody user who sent this order.
The reference ID displayed on receipts and other locations as the ID for this order.
# Event: order.delivered
Source: https://developer.ongoody.com/webhooks/events/order.delivered
Emitted when an order has been delivered. If the order has multiple shipments, this is emitted when all shipments have been delivered.
## Example
```json theme={null}
{
"event_type": "order.delivered",
"id": "ad097c47-bf12-45c9-8feb-0536a0012c09",
"data": {
"id": "10c588dd-d566-45bf-86e9-c23bd1f1587b",
"status": "shipped",
"individual_gift_link": "https://gifts.ongoody.com/gift/vWtUe8lQRJuoyYzKlYeHMkbV",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"card_id": "ae4cb4ce-75fc-4782-a9ab-2f30d9b7b41d",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "4133078a-c35f-441e-8e92-57645342b299",
"expires_at": null,
"cart": {
"id": "39b04e91-6a40-468d-8ed4-f59e9059afae",
"items": [
{
"id": "d59dead0-a44c-44df-885f-030612038a48",
"quantity": 1,
"product": {
"id": "c399bafb-3fbc-40c5-bef3-9158b7a19abc",
"name": "Cookies",
"brand": {
"id": "db631527-c59c-409c-823f-42a24c972283",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [
{
"id": "9a1a2003-bb03-4409-b7fd-243b2e600e46",
"status": "delivered",
"brand_name": "Cookie Company",
"tracking_carrier": "UPS",
"shipped_at": "2023-01-23T00:00:00Z",
"delivered_at": "2023-01-26T00:00:00Z",
"delivery_eta": "2023-01-26T00:00:00Z"
}
],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": 150,
"amount_total": 2250,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15556038009@test.ongoody.com"
},
"workspace_id": "8779bb01-ca47-4e9e-a845-d05f509c4be3",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "PCI7GLZ3KFIEN8MWWSD5LDCF"
}
}
```
## Schema
The type of event that occurred
The unique ID for this event
An individual order contains the gift link to be sent to the recipient (if applicable) and other information about the order.
Allowed values: `created` `notified` `opened` `accepted`
`pending_payment` `paid` `ordered` `shipped` `delivered` `failed`
`canceled`
This gift link can be sent to the recipient or shared with the sender.
For privacy reasons, this gift link does not display tracking
information. A separate link, the recipient link, is sent directly to
the recipient after they accept their gift, which does contain
tracking information.
The cart currently on this order. If the order is a gift that was
swapped, `cart` displays the most recent products selected (i.e.
post-swap).
The brand that this product is from.
A list of the shipments for the order.
Allowed values: `pending` `tracking` `shipped` `delivered` `delivered_override` `failed` `failed_unset_tracking` `failed_with_reship`
The name of the brand that this shipment is from
The carrier for this shipment, e.g. UPS.
Only for approved distribution partners.
ISO 8601
ISO 8601
The estimated delivery time of this shipment.
Organizations are sub-divided into workspaces. Orders are contained in workspaces, identified by this ID.
For gifts, the date and time the gift is set to expire.
The digital greeting card on this gift.
The message in this gift, provided by the sender.
A thank you note sent by the recipient.
The number of times the recipient viewed the gift.
If this gift was swapped by the recipient. Swapping allows a recipient to select another product or products, which replaces the `cart`. The original products are saved to `original_cart`.
On Goody for Business, all orders are attached to a order batch, which is a collection of one or more orders.
Costs in USD cents (i.e. \$1.00 = 100). If the order was swapped, `amounts` displays the most recent amounts (i.e. post-swap).
Total cost of the products in this order.
Total cost of shipping for this order.
Total cost of processing fees for this order.
Total amount of credit applied to this order.
Total cost of the products, shipping, and processing fees in this order.
Total tax for this order.
Total cost of the products, shipping, processing fees, tax, and global shipping costs in this order.
Total cost of global shipping for this order through the Global Relay service.
Only provided when calling the /orders/:id endpoint.
ISO 8601
When the recipient was notified of the order.
For gifts, when the recipient opened the order.
For gifts, when the recipient accepted the order.
When the order entered pending payment status.
When the order was paid for.
When the order was first shipped. If there are multiple shipments, this is when the first shipment shipped.
When the order was delivered. If there are multiple shipments, this is when all shipments were delivered.
If this order is a gift that was swapped, this displays the original cart that was sent to the recipient.
The brand that this product is from.
If this order is a gift that was swapped, this displays the original amounts of the cart that was sent to the recipient.
The Goody user who sent this order.
The reference ID displayed on receipts and other locations as the ID for this order.
# Event: order.gift_accepted
Source: https://developer.ongoody.com/webhooks/events/order.gift_accepted
Emitted when a gift has been accepted by a recipient, and the final costs of the order have been calculated. You can also view whether they swapped the gift (`is_swapped`) and what they swapped to (`cart`).
## Example
```json theme={null}
{
"event_type": "order.gift_accepted",
"id": "ad097c47-bf12-45c9-8feb-0536a0012c09",
"data": {
"id": "10c588dd-d566-45bf-86e9-c23bd1f1587b",
"status": "accepted",
"individual_gift_link": "https://gifts.ongoody.com/gift/vWtUe8lQRJuoyYzKlYeHMkbV",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"card_id": "ae4cb4ce-75fc-4782-a9ab-2f30d9b7b41d",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "4133078a-c35f-441e-8e92-57645342b299",
"expires_at": null,
"cart": {
"id": "39b04e91-6a40-468d-8ed4-f59e9059afae",
"items": [
{
"id": "d59dead0-a44c-44df-885f-030612038a48",
"quantity": 1,
"product": {
"id": "c399bafb-3fbc-40c5-bef3-9158b7a19abc",
"name": "Cookies",
"brand": {
"id": "db631527-c59c-409c-823f-42a24c972283",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": 150,
"amount_total": 2250,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15556038009@test.ongoody.com"
},
"workspace_id": "8779bb01-ca47-4e9e-a845-d05f509c4be3",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"payment_link": "https://checkout.ongoody.com/checkout?key=1on1dhtA3LekJgvxNZu83XqN",
"reference_id": "PCI7GLZ3KFIEN8MWWSD5LDCF"
}
}
```
## Schema
The type of event that occurred
The unique ID for this event
An individual order contains the gift link to be sent to the recipient (if applicable) and other information about the order.
Allowed values: `created` `notified` `opened` `accepted`
`pending_payment` `paid` `ordered` `shipped` `delivered` `failed`
`canceled`
This gift link can be sent to the recipient or shared with the sender.
For privacy reasons, this gift link does not display tracking
information. A separate link, the recipient link, is sent directly to
the recipient after they accept their gift, which does contain
tracking information.
The cart currently on this order. If the order is a gift that was
swapped, `cart` displays the most recent products selected (i.e.
post-swap).
The brand that this product is from.
A list of the shipments for the order.
Allowed values: `pending` `tracking` `shipped` `delivered` `delivered_override` `failed` `failed_unset_tracking` `failed_with_reship`
The name of the brand that this shipment is from
The carrier for this shipment, e.g. UPS.
Only for approved distribution partners.
ISO 8601
ISO 8601
The estimated delivery time of this shipment.
Organizations are sub-divided into workspaces. Orders are contained in workspaces, identified by this ID.
For gifts, the date and time the gift is set to expire.
The digital greeting card on this gift.
The message in this gift, provided by the sender.
A thank you note sent by the recipient.
The number of times the recipient viewed the gift.
If this gift was swapped by the recipient. Swapping allows a recipient to select another product or products, which replaces the `cart`. The original products are saved to `original_cart`.
On Goody for Business, all orders are attached to a order batch, which is a collection of one or more orders.
Costs in USD cents (i.e. \$1.00 = 100). If the order was swapped, `amounts` displays the most recent amounts (i.e. post-swap).
Total cost of the products in this order.
Total cost of shipping for this order.
Total cost of processing fees for this order.
Total amount of credit applied to this order.
Total cost of the products, shipping, and processing fees in this order.
Total tax for this order.
Total cost of the products, shipping, processing fees, tax, and global shipping costs in this order.
Total cost of global shipping for this order through the Global Relay service.
Only provided when calling the /orders/:id endpoint.
ISO 8601
When the recipient was notified of the order.
For gifts, when the recipient opened the order.
For gifts, when the recipient accepted the order.
When the order entered pending payment status.
When the order was paid for.
When the order was first shipped. If there are multiple shipments, this is when the first shipment shipped.
When the order was delivered. If there are multiple shipments, this is when all shipments were delivered.
If this order is a gift that was swapped, this displays the original cart that was sent to the recipient.
The brand that this product is from.
If this order is a gift that was swapped, this displays the original amounts of the cart that was sent to the recipient.
The Goody user who sent this order.
For commerce apps using Hosted Payment, the payment link for the gift with the credit card entry form. Available when the gift is in `pending_payment` status (after it has been accepted).
The reference ID displayed on receipts and other locations as the ID for this order.
# Event: order.gift_opened
Source: https://developer.ongoody.com/webhooks/events/order.gift_opened
Emitted when a gift is first opened. Note that if you open the gift link yourself, you might trigger this event.
## Example
```json theme={null}
{
"event_type": "order.gift_opened",
"id": "ad097c47-bf12-45c9-8feb-0536a0012c09",
"data": {
"id": "10c588dd-d566-45bf-86e9-c23bd1f1587b",
"status": "opened",
"individual_gift_link": "https://gifts.ongoody.com/gift/vWtUe8lQRJuoyYzKlYeHMkbV",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"card_id": "ae4cb4ce-75fc-4782-a9ab-2f30d9b7b41d",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "4133078a-c35f-441e-8e92-57645342b299",
"expires_at": null,
"cart": {
"id": "39b04e91-6a40-468d-8ed4-f59e9059afae",
"items": [
{
"id": "d59dead0-a44c-44df-885f-030612038a48",
"quantity": 1,
"product": {
"id": "c399bafb-3fbc-40c5-bef3-9158b7a19abc",
"name": "Cookies",
"brand": {
"id": "db631527-c59c-409c-823f-42a24c972283",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15556038009@test.ongoody.com"
},
"workspace_id": "8779bb01-ca47-4e9e-a845-d05f509c4be3",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "PCI7GLZ3KFIEN8MWWSD5LDCF"
}
}
```
## Schema
The type of event that occurred
The unique ID for this event
An individual order contains the gift link to be sent to the recipient (if applicable) and other information about the order.
Allowed values: `created` `notified` `opened` `accepted`
`pending_payment` `paid` `ordered` `shipped` `delivered` `failed`
`canceled`
This gift link can be sent to the recipient or shared with the sender.
For privacy reasons, this gift link does not display tracking
information. A separate link, the recipient link, is sent directly to
the recipient after they accept their gift, which does contain
tracking information.
The cart currently on this order. If the order is a gift that was
swapped, `cart` displays the most recent products selected (i.e.
post-swap).
The brand that this product is from.
A list of the shipments for the order.
Allowed values: `pending` `tracking` `shipped` `delivered` `delivered_override` `failed` `failed_unset_tracking` `failed_with_reship`
The name of the brand that this shipment is from
The carrier for this shipment, e.g. UPS.
Only for approved distribution partners.
ISO 8601
ISO 8601
The estimated delivery time of this shipment.
Organizations are sub-divided into workspaces. Orders are contained in workspaces, identified by this ID.
For gifts, the date and time the gift is set to expire.
The digital greeting card on this gift.
The message in this gift, provided by the sender.
A thank you note sent by the recipient.
The number of times the recipient viewed the gift.
If this gift was swapped by the recipient. Swapping allows a recipient to select another product or products, which replaces the `cart`. The original products are saved to `original_cart`.
On Goody for Business, all orders are attached to a order batch, which is a collection of one or more orders.
Costs in USD cents (i.e. \$1.00 = 100). If the order was swapped, `amounts` displays the most recent amounts (i.e. post-swap).
Total cost of the products in this order.
Total cost of shipping for this order.
Total cost of processing fees for this order.
Total amount of credit applied to this order.
Total cost of the products, shipping, and processing fees in this order.
Total tax for this order.
Total cost of the products, shipping, processing fees, tax, and global shipping costs in this order.
Total cost of global shipping for this order through the Global Relay service.
Only provided when calling the /orders/:id endpoint.
ISO 8601
When the recipient was notified of the order.
For gifts, when the recipient opened the order.
For gifts, when the recipient accepted the order.
When the order entered pending payment status.
When the order was paid for.
When the order was first shipped. If there are multiple shipments, this is when the first shipment shipped.
When the order was delivered. If there are multiple shipments, this is when all shipments were delivered.
If this order is a gift that was swapped, this displays the original cart that was sent to the recipient.
The brand that this product is from.
If this order is a gift that was swapped, this displays the original amounts of the cart that was sent to the recipient.
The Goody user who sent this order.
The reference ID displayed on receipts and other locations as the ID for this order.
# Event: order.refunded
Source: https://developer.ongoody.com/webhooks/events/order.refunded
Emitted when an order has been refunded.
## Example
```json theme={null}
{
"event_type": "order.refunded",
"id": "ad097c47-bf12-45c9-8feb-0536a0012c09",
"data": {
"id": "8999f804-d731-440d-a67d-35444c12c493",
"status": "shipped",
"individual_gift_link": "https://gifts.ongoody.com/gift/IsDyQQWtqrOyGPgZ9bVm6ptz",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"card_id": "7e79fd96-212b-4468-9989-57b896ca22f4",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "d158184c-6b31-4a72-b39f-8f8ca04ecbdd",
"expires_at": null,
"cart": {
"id": "3ff7dab1-ae03-4b20-a2c8-82a3f3326b83",
"items": [
{
"id": "284dc74f-a2c4-4b62-bfe5-94c464d56ea7",
"quantity": 1,
"product": {
"id": "10227d72-c355-4881-8007-aad34f501055",
"name": "Cookies",
"brand": {
"id": "fe370ec6-1208-4d23-b936-de857ceeae6d",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": 150,
"amount_total": 2250,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15551494889@test.ongoody.com"
},
"workspace_id": "dfe0d5cb-2c98-4800-a950-b40cca509250",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "2MUPN0YMGIDT7TJNPPFPB7WE"
}
}
```
## Schema
The type of event that occurred
The unique ID for this event
An individual order contains the gift link to be sent to the recipient (if applicable) and other information about the order.
Allowed values: `created` `notified` `opened` `accepted`
`pending_payment` `paid` `ordered` `shipped` `delivered` `failed`
`canceled`
This gift link can be sent to the recipient or shared with the sender.
For privacy reasons, this gift link does not display tracking
information. A separate link, the recipient link, is sent directly to
the recipient after they accept their gift, which does contain
tracking information.
The cart currently on this order. If the order is a gift that was
swapped, `cart` displays the most recent products selected (i.e.
post-swap).
The brand that this product is from.
A list of the shipments for the order.
Allowed values: `pending` `tracking` `shipped` `delivered` `delivered_override` `failed` `failed_unset_tracking` `failed_with_reship`
The name of the brand that this shipment is from
The carrier for this shipment, e.g. UPS.
Only for approved distribution partners.
ISO 8601
ISO 8601
The estimated delivery time of this shipment.
Organizations are sub-divided into workspaces. Orders are contained in workspaces, identified by this ID.
For gifts, the date and time the gift is set to expire.
The digital greeting card on this gift.
The message in this gift, provided by the sender.
A thank you note sent by the recipient.
The number of times the recipient viewed the gift.
If this gift was swapped by the recipient. Swapping allows a recipient to select another product or products, which replaces the `cart`. The original products are saved to `original_cart`.
On Goody for Business, all orders are attached to a order batch, which is a collection of one or more orders.
Costs in USD cents (i.e. \$1.00 = 100). If the order was swapped, `amounts` displays the most recent amounts (i.e. post-swap).
Total cost of the products in this order.
Total cost of shipping for this order.
Total cost of processing fees for this order.
Total amount of credit applied to this order.
Total cost of the products, shipping, and processing fees in this order.
Total tax for this order.
Total cost of the products, shipping, processing fees, tax, and global shipping costs in this order.
Total cost of global shipping for this order through the Global Relay service.
Only provided when calling the /orders/:id endpoint.
ISO 8601
When the recipient was notified of the order.
For gifts, when the recipient opened the order.
For gifts, when the recipient accepted the order.
When the order entered pending payment status.
When the order was paid for.
When the order was first shipped. If there are multiple shipments, this is when the first shipment shipped.
When the order was delivered. If there are multiple shipments, this is when all shipments were delivered.
If this order is a gift that was swapped, this displays the original cart that was sent to the recipient.
The brand that this product is from.
If this order is a gift that was swapped, this displays the original amounts of the cart that was sent to the recipient.
The Goody user who sent this order.
The reference ID displayed on receipts and other locations as the ID for this order.
# Event: order.shipped
Source: https://developer.ongoody.com/webhooks/events/order.shipped
Emitted when the order is shipped. If there are multiple shipments, this is emitted when the first shipment for this order is in transit.
You can access the list of shipments under the `shipments` field. Note that for multi-shipment orders, when this order first enters the shipped state, the list of shipments might be incomplete since more shipments might be shipped later.
## Example
```json theme={null}
{
"event_type": "order.shipped",
"id": "ad097c47-bf12-45c9-8feb-0536a0012c09",
"data": {
"id": "10c588dd-d566-45bf-86e9-c23bd1f1587b",
"status": "shipped",
"individual_gift_link": "https://gifts.ongoody.com/gift/vWtUe8lQRJuoyYzKlYeHMkbV",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"card_id": "ae4cb4ce-75fc-4782-a9ab-2f30d9b7b41d",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "4133078a-c35f-441e-8e92-57645342b299",
"expires_at": null,
"cart": {
"id": "39b04e91-6a40-468d-8ed4-f59e9059afae",
"items": [
{
"id": "d59dead0-a44c-44df-885f-030612038a48",
"quantity": 1,
"product": {
"id": "c399bafb-3fbc-40c5-bef3-9158b7a19abc",
"name": "Cookies",
"brand": {
"id": "db631527-c59c-409c-823f-42a24c972283",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [
{
"id": "9a1a2003-bb03-4409-b7fd-243b2e600e46",
"status": "shipped",
"brand_name": "Cookie Company",
"tracking_carrier": "UPS",
"shipped_at": "2023-01-23T00:00:00Z",
"delivered_at": null,
"delivery_eta": "2023-01-26T00:00:00Z"
}
],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": 150,
"amount_total": 2250,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15556038009@test.ongoody.com"
},
"workspace_id": "8779bb01-ca47-4e9e-a845-d05f509c4be3",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "PCI7GLZ3KFIEN8MWWSD5LDCF"
}
}
```
## Schema
The type of event that occurred
The unique ID for this event
An individual order contains the gift link to be sent to the recipient (if applicable) and other information about the order.
Allowed values: `created` `notified` `opened` `accepted`
`pending_payment` `paid` `ordered` `shipped` `delivered` `failed`
`canceled`
This gift link can be sent to the recipient or shared with the sender.
For privacy reasons, this gift link does not display tracking
information. A separate link, the recipient link, is sent directly to
the recipient after they accept their gift, which does contain
tracking information.
The cart currently on this order. If the order is a gift that was
swapped, `cart` displays the most recent products selected (i.e.
post-swap).
The brand that this product is from.
A list of the shipments for the order.
Allowed values: `pending` `tracking` `shipped` `delivered` `delivered_override` `failed` `failed_unset_tracking` `failed_with_reship`
The name of the brand that this shipment is from
The carrier for this shipment, e.g. UPS.
Only for approved distribution partners.
ISO 8601
ISO 8601
The estimated delivery time of this shipment.
Organizations are sub-divided into workspaces. Orders are contained in workspaces, identified by this ID.
For gifts, the date and time the gift is set to expire.
The digital greeting card on this gift.
The message in this gift, provided by the sender.
A thank you note sent by the recipient.
The number of times the recipient viewed the gift.
If this gift was swapped by the recipient. Swapping allows a recipient to select another product or products, which replaces the `cart`. The original products are saved to `original_cart`.
On Goody for Business, all orders are attached to a order batch, which is a collection of one or more orders.
Costs in USD cents (i.e. \$1.00 = 100). If the order was swapped, `amounts` displays the most recent amounts (i.e. post-swap).
Total cost of the products in this order.
Total cost of shipping for this order.
Total cost of processing fees for this order.
Total amount of credit applied to this order.
Total cost of the products, shipping, and processing fees in this order.
Total tax for this order.
Total cost of the products, shipping, processing fees, tax, and global shipping costs in this order.
Total cost of global shipping for this order through the Global Relay service.
Only provided when calling the /orders/:id endpoint.
ISO 8601
When the recipient was notified of the order.
For gifts, when the recipient opened the order.
For gifts, when the recipient accepted the order.
When the order entered pending payment status.
When the order was paid for.
When the order was first shipped. If there are multiple shipments, this is when the first shipment shipped.
When the order was delivered. If there are multiple shipments, this is when all shipments were delivered.
If this order is a gift that was swapped, this displays the original cart that was sent to the recipient.
The brand that this product is from.
If this order is a gift that was swapped, this displays the original amounts of the cart that was sent to the recipient.
The Goody user who sent this order.
The reference ID displayed on receipts and other locations as the ID for this order.
# Event: order.thank_you_note_added
Source: https://developer.ongoody.com/webhooks/events/order.thank_you_note_added
Emitted when the recipient adds a thank you note to a gift. This typically happens shortly after the gift has been accepted, but can happen anytime after acceptance. You can access the thank you note on the `thank_you_note` property of the order.
## Example
```json theme={null}
{
"event_type": "order.thank_you_note_added",
"id": "ad097c47-bf12-45c9-8feb-0536a0012c09",
"data": {
"id": "10c588dd-d566-45bf-86e9-c23bd1f1587b",
"status": "accepted",
"individual_gift_link": "https://gifts.ongoody.com/gift/vWtUe8lQRJuoyYzKlYeHMkbV",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"card_id": "ae4cb4ce-75fc-4782-a9ab-2f30d9b7b41d",
"message": "Thank you!",
"thank_you_note": "Thanks for the gift!",
"view_count_recipient": 0,
"is_swapped": false,
"order_batch_id": "4133078a-c35f-441e-8e92-57645342b299",
"expires_at": null,
"cart": {
"id": "39b04e91-6a40-468d-8ed4-f59e9059afae",
"items": [
{
"id": "d59dead0-a44c-44df-885f-030612038a48",
"quantity": 1,
"product": {
"id": "c399bafb-3fbc-40c5-bef3-9158b7a19abc",
"name": "Cookies",
"brand": {
"id": "db631527-c59c-409c-823f-42a24c972283",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": 150,
"amount_total": 2250,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15556038009@test.ongoody.com"
},
"workspace_id": "8779bb01-ca47-4e9e-a845-d05f509c4be3",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "PCI7GLZ3KFIEN8MWWSD5LDCF"
}
}
```
## Schema
The type of event that occurred
The unique ID for this event
An individual order contains the gift link to be sent to the recipient (if applicable) and other information about the order.
Allowed values: `created` `notified` `opened` `accepted`
`pending_payment` `paid` `ordered` `shipped` `delivered` `failed`
`canceled`
This gift link can be sent to the recipient or shared with the sender.
For privacy reasons, this gift link does not display tracking
information. A separate link, the recipient link, is sent directly to
the recipient after they accept their gift, which does contain
tracking information.
The cart currently on this order. If the order is a gift that was
swapped, `cart` displays the most recent products selected (i.e.
post-swap).
The brand that this product is from.
A list of the shipments for the order.
Allowed values: `pending` `tracking` `shipped` `delivered` `delivered_override` `failed` `failed_unset_tracking` `failed_with_reship`
The name of the brand that this shipment is from
The carrier for this shipment, e.g. UPS.
Only for approved distribution partners.
ISO 8601
ISO 8601
The estimated delivery time of this shipment.
Organizations are sub-divided into workspaces. Orders are contained in workspaces, identified by this ID.
For gifts, the date and time the gift is set to expire.
The digital greeting card on this gift.
The message in this gift, provided by the sender.
A thank you note sent by the recipient.
The number of times the recipient viewed the gift.
If this gift was swapped by the recipient. Swapping allows a recipient to select another product or products, which replaces the `cart`. The original products are saved to `original_cart`.
On Goody for Business, all orders are attached to a order batch, which is a collection of one or more orders.
Costs in USD cents (i.e. \$1.00 = 100). If the order was swapped, `amounts` displays the most recent amounts (i.e. post-swap).
Total cost of the products in this order.
Total cost of shipping for this order.
Total cost of processing fees for this order.
Total amount of credit applied to this order.
Total cost of the products, shipping, and processing fees in this order.
Total tax for this order.
Total cost of the products, shipping, processing fees, tax, and global shipping costs in this order.
Total cost of global shipping for this order through the Global Relay service.
Only provided when calling the /orders/:id endpoint.
ISO 8601
When the recipient was notified of the order.
For gifts, when the recipient opened the order.
For gifts, when the recipient accepted the order.
When the order entered pending payment status.
When the order was paid for.
When the order was first shipped. If there are multiple shipments, this is when the first shipment shipped.
When the order was delivered. If there are multiple shipments, this is when all shipments were delivered.
If this order is a gift that was swapped, this displays the original cart that was sent to the recipient.
The brand that this product is from.
If this order is a gift that was swapped, this displays the original amounts of the cart that was sent to the recipient.
The Goody user who sent this order.
The reference ID displayed on receipts and other locations as the ID for this order.
# Event: order_batch.completed
Source: https://developer.ongoody.com/webhooks/events/order_batch.completed
Emitted when an order batch is fully processed, which is when all orders are created for each recipient in the order batch.
**For non-scheduled order batches,** the `order_batch.completed` event is emitted immediately after the order batch is finished processing and all orders have been created. *(This is instantly after the `order_batch.created` webhook event for order batches with 10 or fewer recipients, and shortly after the `order_batch.created` event for order batches with more than 10 recipients.)*
**For scheduled order batches,** the `order_batch.completed` event is emitted when the order batch scheduled time is reached, and orders are created for the order batch.
## Example
```json theme={null}
{
"event_type": "gift_batch.completed",
"id": "ad097c47-bf12-45c9-8feb-0536a0012c09",
"data": {
"id": "bd1fd5b5-6339-4331-a404-66200143ff0f",
"send_status": "complete",
"from_name": "John",
"message": "Thank you!",
"gifts_count": 2,
"gifts_preview": [
{
"id": "1f6e253e-4d03-4a85-a349-0659384ac894",
"status": "created",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"individual_gift_link_shared": "https://gifts.ongoody.com/gift/Anc0HT0ZhyKAJguP75jt2Rar",
"card_id": "60c4a674-4f0e-4031-9eca-645d34bb6cec",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"gift_batch_id": "bd1fd5b5-6339-4331-a404-66200143ff0f",
"cart": {
"id": "e0597695-5e19-4bbc-9a99-0fd540a9e68f",
"items": [
{
"id": "5f4e70e9-5cc7-406e-8058-c513af667511",
"quantity": 1,
"product": {
"id": "e69ea31a-320f-48f5-8fd7-0692df22328e",
"name": "Cookies",
"brand": {
"id": "393d847d-874b-4338-b834-fe3e0cf27644",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15550197216@test.ongoody.com"
},
"workspace_id": "ae6e2795-8667-4d21-a1b0-fe7f642d7893",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "LLRMPDGSSD7GXISGMACUKUIS"
},
{
"id": "981c4abd-1f0c-4287-8c35-c7cea8f6f5da",
"status": "created",
"recipient_first_name": "Michael",
"recipient_last_name": "Franci",
"recipient_email": "michael@ongoody.com",
"individual_gift_link_shared": "https://gifts.ongoody.com/gift/6p5k63B9ym4ksusHG6hr6xtA",
"card_id": "60c4a674-4f0e-4031-9eca-645d34bb6cec",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"gift_batch_id": "bd1fd5b5-6339-4331-a404-66200143ff0f",
"cart": {
"id": "e0597695-5e19-4bbc-9a99-0fd540a9e68f",
"items": [
{
"id": "5f4e70e9-5cc7-406e-8058-c513af667511",
"quantity": 1,
"product": {
"id": "e69ea31a-320f-48f5-8fd7-0692df22328e",
"name": "Cookies",
"brand": {
"id": "393d847d-874b-4338-b834-fe3e0cf27644",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15550197216@test.ongoody.com"
},
"workspace_id": "ae6e2795-8667-4d21-a1b0-fe7f642d7893",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "U23DXZIHYSI4U9M8SBQ7XMVH"
}
],
"recipients_count": 2,
"recipients_preview": [
{
"first_name": "Alena",
"last_name": "Kenter",
"email": "alena@ongoody.com"
},
{
"first_name": "Michael",
"last_name": "Franci",
"email": "michael@ongoody.com"
}
],
"cart": {
"id": "e0597695-5e19-4bbc-9a99-0fd540a9e68f",
"items": [
{
"id": "5f4e70e9-5cc7-406e-8058-c513af667511",
"quantity": 1,
"product": {
"id": "e69ea31a-320f-48f5-8fd7-0692df22328e",
"name": "Cookies",
"brand": {
"id": "393d847d-874b-4338-b834-fe3e0cf27644",
"name": "Cookie Company"
}
}
}
]
},
"is_scheduled_send": false,
"scheduled_send_on": null,
"expires_at": null,
"send_method": "link_multiple_custom_list",
"batch_name": "Alena Kenter and Michael Franci",
"card_id": "60c4a674-4f0e-4031-9eca-645d34bb6cec",
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15550197216@test.ongoody.com"
},
"workspace_id": "ae6e2795-8667-4d21-a1b0-fe7f642d7893",
"workspace_name": "Test Team",
"reference_id": "61Q2FSAHYYISJRZDHQXGYTBU"
}
}
```
## Schema
The type of event that occurred
The unique ID for this event
An order batch is the primary resource created by the API. Order batches
contain an array of orders.
An order batch is the primary resource created by the API. Order batches
contain an array of orders.
The `pending` status indicates that an order batch is being prepared to be
sent out. If it is not scheduled, it is being sent asynchronously. If it
is scheduled, it will stay in `pending` state until the scheduled time is
reached, at which point it will be processed and moved to `complete`. When
it is in `pending` status, no orders are created yet. When the order
batch is in `complete` status, all orders are created and available.
Allowed values: `pending` `complete` `failed` `canceled`
The name of the sender. This is displayed on the order and notifications.
The message in this order batch, provided by the sender.
The total number of orders in this order batch. This might be blank if the
order batch is scheduled for the future, or it could be fewer than the
recipient count if the order batch is in the process of being sent.
A preview of the first 10 orders in this order batch. To paginate through
all of the orders, use the `/order_batches/:id/orders` endpoint with
`?page&per_page`. If your use case never sends more than 10 orders in a
single batch, you can use this field instead of calling
`/order_batches/:id/orders`. For order batches with more than 10
recipients, this array will be empty while the orders are asynchronously
created in the background.
Allowed values: `created` `notified` `opened` `accepted`
`pending_payment` `paid` `ordered` `shipped` `delivered` `failed`
`canceled`
This gift link can be sent to the recipient or shared with the sender.
For privacy reasons, this gift link does not display tracking
information. A separate link, the recipient link, is sent directly to
the recipient after they accept their gift, which does contain
tracking information.
The cart currently on this order. If the order is a gift that was
swapped, `cart` displays the most recent products selected (i.e.
post-swap).
The brand that this product is from.
A list of the shipments for the order.
Allowed values: `pending` `tracking` `shipped` `delivered` `delivered_override` `failed` `failed_unset_tracking` `failed_with_reship`
The name of the brand that this shipment is from
The carrier for this shipment, e.g. UPS.
Only for approved distribution partners.
ISO 8601
ISO 8601
The estimated delivery time of this shipment.
Organizations are sub-divided into workspaces. Orders are contained in workspaces, identified by this ID.
For gifts, the date and time the gift is set to expire.
The digital greeting card on this gift.
The message in this gift, provided by the sender.
A thank you note sent by the recipient.
The number of times the recipient viewed the gift.
If this gift was swapped by the recipient. Swapping allows a recipient to select another product or products, which replaces the `cart`. The original products are saved to `original_cart`.
On Goody for Business, all orders are attached to a order batch, which is a collection of one or more orders.
Costs in USD cents (i.e. \$1.00 = 100). If the order was swapped, `amounts` displays the most recent amounts (i.e. post-swap).
Total cost of the products in this order.
Total cost of shipping for this order.
Total cost of processing fees for this order.
Total amount of credit applied to this order.
Total cost of the products, shipping, and processing fees in this order.
Total tax for this order.
Total cost of the products, shipping, processing fees, tax, and global shipping costs in this order.
Total cost of global shipping for this order through the Global Relay service.
Only provided when calling the /orders/:id endpoint.
ISO 8601
When the recipient was notified of the order.
For gifts, when the recipient opened the order.
For gifts, when the recipient accepted the order.
When the order entered pending payment status.
When the order was paid for.
When the order was first shipped. If there are multiple shipments, this is when the first shipment shipped.
When the order was delivered. If there are multiple shipments, this is when all shipments were delivered.
If this order is a gift that was swapped, this displays the original cart that was sent to the recipient.
The brand that this product is from.
If this order is a gift that was swapped, this displays the original amounts of the cart that was sent to the recipient.
The Goody user who sent this order.
The reference ID displayed on receipts and other locations as the ID for this order.
The total number of recipients in this order batch.
A preview of the first 10 recipients in this order batch. To see all of the recipients, use `/order_batches/:id/recipients`. Recipients contain the original contact information provided for each recipient when the order batch was created.
The cart that was sent for this order batch. This is the original cart that was created for this order batch. If individual orders were swapped, this still remains the same, whereas orders' `cart` would change if they were swapped.
Whether this order batch was set up as a scheduled send. This stays as `true` after the scheduled send is complete. To determine if the order batch is scheduled to be sent for the future, check if `status` is `pending` and `scheduled_send_on` is in the future. When a order batch is scheduled, orders are only created on the scheduled send date.
The date and time the order batch is scheduled to be sent. This will be `null` if the order batch is not a scheduled send. This field remains after the scheduled send completes. ISO 8601, UTC.
The date and time the order batch is set to expire. ISO 8601, UTC.
The method for sending a order batch. Currently, the only supported send method is `link_multiple_custom_list` which specifies that a link should be created for each order, but no email should automatically be sent to the recipient. Allowed value: `link_multiple_custom_list`
An internal name for the order batch, falling back to an auto-generated batch name. Not displayed to recipients.
The digital greeting card on this order batch.
The sender of the order batch.
Organizations are sub-divided into workspaces. Order batches are contained in workspaces, identified by this ID.
The reference ID displayed on receipts and other locations as the ID for this order batch.
# Order batch.created
Source: https://developer.ongoody.com/webhooks/events/order_batch.created
Emitted when a order batch is created in the organization.
**For non-scheduled order batches,** for order batches with 10 or fewer recipients, the `order_batch.created` event will contain all of the orders for each recipient. For order batches with more than 10 recipients, order creation happens asynchronously, and the `order_batch.completed` event is emitted immediately after the orders are created.
**For scheduled order batches,** no order will be created when the order batch is created until the scheduled send time. The `order_batch.completed` event is emitted when the order batch scheduled time is reached, and orders are created for the order batch.
## Example
```json theme={null}
{
"event_type": "gift_batch.created",
"id": "ad097c47-bf12-45c9-8feb-0536a0012c09",
"data": {
"id": "bd1fd5b5-6339-4331-a404-66200143ff0f",
"send_status": "complete",
"from_name": "John",
"message": "Thank you!",
"gifts_count": 2,
"gifts_preview": [
{
"id": "1f6e253e-4d03-4a85-a349-0659384ac894",
"status": "created",
"recipient_first_name": "Alena",
"recipient_last_name": "Kenter",
"recipient_email": "alena@ongoody.com",
"individual_gift_link_shared": "https://gifts.ongoody.com/gift/Anc0HT0ZhyKAJguP75jt2Rar",
"card_id": "60c4a674-4f0e-4031-9eca-645d34bb6cec",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"gift_batch_id": "bd1fd5b5-6339-4331-a404-66200143ff0f",
"cart": {
"id": "e0597695-5e19-4bbc-9a99-0fd540a9e68f",
"items": [
{
"id": "5f4e70e9-5cc7-406e-8058-c513af667511",
"quantity": 1,
"product": {
"id": "e69ea31a-320f-48f5-8fd7-0692df22328e",
"name": "Cookies",
"brand": {
"id": "393d847d-874b-4338-b834-fe3e0cf27644",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15550197216@test.ongoody.com"
},
"workspace_id": "ae6e2795-8667-4d21-a1b0-fe7f642d7893",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "LLRMPDGSSD7GXISGMACUKUIS"
},
{
"id": "981c4abd-1f0c-4287-8c35-c7cea8f6f5da",
"status": "created",
"recipient_first_name": "Michael",
"recipient_last_name": "Franci",
"recipient_email": "michael@ongoody.com",
"individual_gift_link_shared": "https://gifts.ongoody.com/gift/6p5k63B9ym4ksusHG6hr6xtA",
"card_id": "60c4a674-4f0e-4031-9eca-645d34bb6cec",
"message": "Thank you!",
"thank_you_note": null,
"view_count_recipient": 0,
"is_swapped": false,
"gift_batch_id": "bd1fd5b5-6339-4331-a404-66200143ff0f",
"cart": {
"id": "e0597695-5e19-4bbc-9a99-0fd540a9e68f",
"items": [
{
"id": "5f4e70e9-5cc7-406e-8058-c513af667511",
"quantity": 1,
"product": {
"id": "e69ea31a-320f-48f5-8fd7-0692df22328e",
"name": "Cookies",
"brand": {
"id": "393d847d-874b-4338-b834-fe3e0cf27644",
"name": "Cookie Company"
}
}
}
]
},
"shipments": [],
"amounts": {
"amount_product": 1000,
"amount_shipping": 1000,
"amount_processing_fee": 100,
"amount_pre_tax_total": 2100,
"amount_tax": null,
"amount_total": null,
"amount_global_relay_cost": null
},
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15550197216@test.ongoody.com"
},
"workspace_id": "ae6e2795-8667-4d21-a1b0-fe7f642d7893",
"workspace_name": "Test Team",
"original_cart": null,
"original_amounts": null,
"reference_id": "U23DXZIHYSI4U9M8SBQ7XMVH"
}
],
"recipients_count": 2,
"recipients_preview": [
{
"first_name": "Alena",
"last_name": "Kenter",
"email": "alena@ongoody.com"
},
{
"first_name": "Michael",
"last_name": "Franci",
"email": "michael@ongoody.com"
}
],
"cart": {
"id": "e0597695-5e19-4bbc-9a99-0fd540a9e68f",
"items": [
{
"id": "5f4e70e9-5cc7-406e-8058-c513af667511",
"quantity": 1,
"product": {
"id": "e69ea31a-320f-48f5-8fd7-0692df22328e",
"name": "Cookies",
"brand": {
"id": "393d847d-874b-4338-b834-fe3e0cf27644",
"name": "Cookie Company"
}
}
}
]
},
"is_scheduled_send": false,
"scheduled_send_on": null,
"expires_at": null,
"send_method": "link_multiple_custom_list",
"batch_name": "Alena Kenter and Michael Franci",
"card_id": "60c4a674-4f0e-4031-9eca-645d34bb6cec",
"sender": {
"first_name": "Test",
"last_name": "User",
"email": "15550197216@test.ongoody.com"
},
"workspace_id": "ae6e2795-8667-4d21-a1b0-fe7f642d7893",
"workspace_name": "Test Team",
"reference_id": "61Q2FSAHYYISJRZDHQXGYTBU"
}
}
```
## Schema
The type of event that occurred
The unique ID for this event
An order batch is the primary resource created by the API. Order batches
contain an array of orders.
The `pending` status indicates that an order batch is being prepared to be
sent out. If it is not scheduled, it is being sent asynchronously. If it
is scheduled, it will stay in `pending` state until the scheduled time is
reached, at which point it will be processed and moved to `complete`. When
it is in `pending` status, no orders are created yet. When the order
batch is in `complete` status, all orders are created and available.
Allowed values: `pending` `complete` `failed` `canceled`
The name of the sender. This is displayed on the order and notifications.
The message in this order batch, provided by the sender.
The total number of orders in this order batch. This might be blank if the
order batch is scheduled for the future, or it could be fewer than the
recipient count if the order batch is in the process of being sent.
A preview of the first 10 orders in this order batch. To paginate through
all of the orders, use the `/order_batches/:id/orders` endpoint with
`?page&per_page`. If your use case never sends more than 10 orders in a
single batch, you can use this field instead of calling
`/order_batches/:id/orders`. For order batches with more than 10
recipients, this array will be empty while the orders are asynchronously
created in the background.
Allowed values: `created` `notified` `opened` `accepted`
`pending_payment` `paid` `ordered` `shipped` `delivered` `failed`
`canceled`
This gift link can be sent to the recipient or shared with the sender.
For privacy reasons, this gift link does not display tracking
information. A separate link, the recipient link, is sent directly to
the recipient after they accept their gift, which does contain
tracking information.
The cart currently on this order. If the order is a gift that was
swapped, `cart` displays the most recent products selected (i.e.
post-swap).
The brand that this product is from.
A list of the shipments for the order.
Allowed values: `pending` `tracking` `shipped` `delivered` `delivered_override` `failed` `failed_unset_tracking` `failed_with_reship`
The name of the brand that this shipment is from
The carrier for this shipment, e.g. UPS.
Only for approved distribution partners.
ISO 8601
ISO 8601
The estimated delivery time of this shipment.
Organizations are sub-divided into workspaces. Orders are contained in workspaces, identified by this ID.
For gifts, the date and time the gift is set to expire.
The digital greeting card on this gift.
The message in this gift, provided by the sender.
A thank you note sent by the recipient.
The number of times the recipient viewed the gift.
If this gift was swapped by the recipient. Swapping allows a recipient to select another product or products, which replaces the `cart`. The original products are saved to `original_cart`.
On Goody for Business, all orders are attached to a order batch, which is a collection of one or more orders.
Costs in USD cents (i.e. \$1.00 = 100). If the order was swapped, `amounts` displays the most recent amounts (i.e. post-swap).
Total cost of the products in this order.
Total cost of shipping for this order.
Total cost of processing fees for this order.
Total amount of credit applied to this order.
Total cost of the products, shipping, and processing fees in this order.
Total tax for this order.
Total cost of the products, shipping, processing fees, tax, and global shipping costs in this order.
Total cost of global shipping for this order through the Global Relay service.
Only provided when calling the /orders/:id endpoint.
ISO 8601
When the recipient was notified of the order.
For gifts, when the recipient opened the order.
For gifts, when the recipient accepted the order.
When the order entered pending payment status.
When the order was paid for.
When the order was first shipped. If there are multiple shipments, this is when the first shipment shipped.
When the order was delivered. If there are multiple shipments, this is when all shipments were delivered.
If this order is a gift that was swapped, this displays the original cart that was sent to the recipient.
The brand that this product is from.
If this order is a gift that was swapped, this displays the original amounts of the cart that was sent to the recipient.
The Goody user who sent this order.
The reference ID displayed on receipts and other locations as the ID for this order.
The total number of recipients in this order batch.
A preview of the first 10 recipients in this order batch. To see all of the recipients, use `/order_batches/:id/recipients`. Recipients contain the original contact information provided for each recipient when the order batch was created.
The cart that was sent for this order batch. This is the original cart that was created for this order batch. If individual orders were swapped, this still remains the same, whereas orders' `cart` would change if they were swapped.
Whether this order batch was set up as a scheduled send. This stays as `true` after the scheduled send is complete. To determine if the order batch is scheduled to be sent for the future, check if `status` is `pending` and `scheduled_send_on` is in the future. When a order batch is scheduled, orders are only created on the scheduled send date.
The date and time the order batch is scheduled to be sent. This will be `null` if the order batch is not a scheduled send. This field remains after the scheduled send completes. ISO 8601, UTC.
The date and time the order batch is set to expire. ISO 8601, UTC.
The method for sending a order batch. Currently, the only supported send method is `link_multiple_custom_list` which specifies that a link should be created for each order, but no email should automatically be sent to the recipient. Allowed value: `link_multiple_custom_list`
An internal name for the order batch, falling back to an auto-generated batch name. Not displayed to recipients.
The digital greeting card on this order batch.
The sender of the order batch.
Organizations are sub-divided into workspaces. Order batches are contained in workspaces, identified by this ID.
The reference ID displayed on receipts and other locations as the ID for this order batch.
# Webhooks
Source: https://developer.ongoody.com/webhooks/overview
Webhooks allow you to be notified when events happen on Goody orders and order batches. You can subscribe to all webhooks, or a subset of them. Webhooks are sent by the Svix platform.
For the complete guide to webhooks, visit the Webhooks page for the API you are using:
## Available webhooks
| Webhook | Description |
| -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **[order\_batch.created](/webhooks/events/order_batch.created)** | When an order batch is newly created. The order batch could still be in process of sending, or scheduled for the future. |
| **[order\_batch.completed](/webhooks/events/order_batch.completed)** | When an order batch is fully processed and all orders have been created. |
| **[order.created](/webhooks/events/order.created)** | When an order is created and is ready to be opened. |
| **[order.gift\_opened](/webhooks/events/order.gift_opened)** | When a gift is opened by the recipient. |
| **[order.gift\_accepted](/webhooks/events/order.gift_accepted)** | When a gift has been accepted by the recipient. |
| **[order.thank\_you\_note\_added](/webhooks/events/order.thank_you_note_added)** | When a recipient adds a thank you note to a order after accepting it. |
| **[order.shipped](/webhooks/events/order.shipped)** | When an order starts shipping. If there are multiple shipments, this is called for the first. |
| **[order.delivered](/webhooks/events/order.delivered)** | When an order is fully delivered. If there are multiple shipments, this is called when all shipments are delivered. |
| **[order.canceled](/webhooks/events/order.canceled)** | When an order has been canceled. |
| **[order.refunded](/webhooks/events/order.refunded)** | When an order has been refunded. |
## Setting up a new webhook
Enter a URL to recieve webhooks in the **Endpoint URL** section.
You can leave **Message Filtering** blank to receive all events, or select specific events to receive.
## Webhook security
To ensure the integrity of the webhooks you receive, we recommend verifying the signatures of the webhooks you receive. Svix provides packages for multiple languages that make verifying signatures easy.
To see how, go to the [Webhook Security](/webhooks/webhook-security) page.
## Logs
You can view the logs for webhook delivery for each endpoint, and re-send any failed webhooks if needed.
# Webhook security
Source: https://developer.ongoody.com/webhooks/webhook-security
To ensure the integrity of the webhooks you receive, we recommend verifying the signatures of the webhooks you receive. The webhook platform we use, Svix, provides packages for multiple languages that make verifying signatures easy.
```JavaScript JavaScript theme={null}
npm install svix
// Or
yarn add svix
```
```Python Python theme={null}
pip install svix
```
```Ruby Ruby theme={null}
gem install svix
```
```Rust Rust theme={null}
svix = "0"
```
```Go Go theme={null}
go get github.com/svix/svix-webhooks/go
```
```Java Java theme={null}
// Gradle
implementation "com.svix:svix:0.x.y"
// Maven
com.svix
svix
0.x.y
```
```Kotlin Kotlin theme={null}
// Gradle
implementation "com.svix.kotlin:svix-kotlin:0.x.y"
// Maven
com.svix.kotlin
svix-kotlin
0.x.y
```
```C# C# theme={null}
dotnet add package Svix
```
```PHP PHP theme={null}
composer require svix/svix
```
First, obtain your webhook secret on the configuration page for your webhook under the **Signing Secret**:
Then, to verify the webhook, pass your signing secret with the headers and raw payload body to the verify method.
**Make sure to use the raw request body for the payload**
If your framework
parses JSON, you'll want to use the raw request body instead of the parsed
JSON.
```JavaScript JavaScript theme={null}
import { Webhook } from "svix";
const secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw";
// These were all sent from the server
const headers = {
"svix-id": "msg_p5jXN8AQM9LWM0D4loKWxJek",
"svix-timestamp": "1614265330",
"svix-signature": "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=",
};
const payload = '{"test": 2432232314}';
const wh = new Webhook(secret);
// Throws on error, returns the verified content on success
const payload = wh.verify(payload, headers);
```
```Python Python theme={null}
from svix.webhooks import Webhook
secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
# These were all sent from the server
headers = {
"svix-id": "msg_p5jXN8AQM9LWM0D4loKWxJek",
"svix-timestamp": "1614265330",
"svix-signature": "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=",
}
payload = '{"test": 2432232314}'
wh = Webhook(secret)
# Throws on error, returns the verified content on success
payload = wh.verify(payload, headers)
```
```Ruby Ruby theme={null}
require 'svix'
secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
# These were all sent from the server
headers = {
"svix-id" => "msg_p5jXN8AQM9LWM0D4loKWxJek",
"svix-timestamp" => "1614265330",
"svix-signature" => "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="
}
payload = '{"test": 2432232314}'
wh = Svix::Webhook.new(secret)
# Raises on error, returns the verified content on success
json = wh.verify(payload, headers)
```
```Rust Rust theme={null}
use svix::webhooks::Webhook;
let secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw".to_string();
let mut headers = http::header::HeaderMap::new();
headers.insert("svix-id", "msg_p5jXN8AQM9LWM0D4loKWxJek");
headers.insert("svix-timestamp", "1614265330");
headers.insert("svix-signature", "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=");
let payload = b"{\"test\": 2432232314}";
let wh = Webhook::new(secret)?;
wh.verify(&payload, &headers)?;
// returns Ok on success, Err otherwise
```
```Go Go theme={null}
import (
svix "github.com/svix/svix-webhooks/go"
)
secret := "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw"
// These were all sent from the server
headers := http.Header{}
headers.Set("svix-id", "msg_p5jXN8AQM9LWM0D4loKWxJek")
headers.Set("svix-timestamp", "1614265330")
headers.Set("svix-signature", "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=")
payload := []byte(`{"test": 2432232314}`)
wh, err := svix.NewWebhook(secret)
err := wh.Verify(payload, headers)
// returns nil on success, error otherwise
```
```Java Java theme={null}
import com.svix.Webhook;
String secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw";
// These were all sent from the server
HashMap> headerMap = new HashMap>();
headerMap.put("svix-id", Arrays.asList("msg_p5jXN8AQM9LWM0D4loKWxJek"));
headerMap.put("svix-timestamp", Arrays.asList("1614265330"));
headerMap.put("svix-signature", Arrays.asList("v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE="));
HttpHeaders headers = HttpHeaders.of(headerMap, BiPredicate)
String payload = "{\"test\": 2432232314}";
Webhook webhook = new Webhook(secret);
webhook.verify(payload, headers)
// throws WebhookVerificationError exception on failure.
```
```Kotlin Kotlin theme={null}
import com.svix.kotlin.Webhook
val secret = "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw";
// These were all sent from the server
val headersMap = mapOf(
"svix-id" to listOf("msg_p5jXN8AQM9LWM0D4loKWxJek"),
"svix-timestamp" to listOf("1614265330"),
"svix-signature" to listOf("v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=")
)
val headers = HttpHeaders.of(headersMap) { _, _ -> true }
val payload = "{\"test\": 2432232314}";
val webhook = Webhook(secret);
webhook.verify(payload, headers)
// throws WebhookVerificationError exception on failure.
```
```C# C# theme={null}
using Svix;
using System.Net;
// These were all sent from the server
var headers = new WebHeaderCollection();
headers.Set("svix-id", "msg_p5jXN8AQM9LWM0D4loKWxJek");
headers.Set("svix-timestamp", "1614265330");
headers.Set("svix-signature", "v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=");
var payload = "{\"test\": 2432232314}";
var wh = new Webhook("whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw/Je4ZJEGP1QFb");
// Throws on error
wh.Verify(payload, headers);
```
```PHP PHP theme={null}
// import using composers autoload
require_once('vendor/autoload.php');
// or manually
require_once('/path/to/svix/php/init.php');
// These were all sent from the server
$payload = '{"test": 2432232314}';
$header = array(
'svix-id' => 'msg_p5jXN8AQM9LWM0D4loKWxJek',
'svix-timestamp' => '1614265330',
'svix-signature' => 'v1,g0hM9SsE+OTPJTGt/tmIKtSyZlE3uFJELVlNIOLJ1OE=',
);
// Throws on error, returns the verified content on success
$wh = new \Svix\Webhook('whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw');
$json = $wh->verify($payload, $header);
```
To view more information on how to verify signatures, and to see examples for popular frameworks, visit [Svix's documentation](https://docs.svix.com/receiving/verifying-payloads/how).
If you want to verify webhooks manually, [follow this guide](https://docs.svix.com/receiving/verifying-payloads/how-manual).