Goody
BUSINESS · COMMERCE & FINANCE
Gift collections, templates, brands, greeting cards, and orders in the account they connected.
Acts as the person, not as itself
Each user connects their own account. Every call carries both identities — the agent and the person it is acting for — so the agent can never reach past what that individual can already do.
Credentials never touch the agent
Tokens live in the vault and attach server-side at call time. The agent holds a session, not a secret, and revoking access does not mean rotating a key.
Every call on the record
Who asked, which agent acted, which action ran, and the verdict that let it through — one audit trail across every integration, not one per vendor.
What an agent can do
Each action is granted on its own. An agent allowed to read is not thereby allowed to write, and the scope beside each row is what the acting user must have connected for it to run at all.
goody_delete_v1_webhooks_by_idWRITEDelete one webhook endpoint by id, after which Goody stops calling it. There is no undo in this integration: restoring it means creating it again with Create a webhook endpoint. It destroys the subscription and not any order -- what stops is the delivery of events via DELETE /v1/webhooks/{id}
goody_get_v1_brandsREADPage through the brands in the gift catalogue, each with its logo, its shipping price and free-shipping threshold in cents, its brand values (USA Made, Social Impact Driven, Sustainable, Gluten Free, Vegan, Kosher Certified, Female Founded, AAPI Founded, BIPOC Founded, Black Founded, LGBTQ+ Founded, Hispanic Founded) and its brand sets -- the collections of products it sells. `country_code` narrows the catalogue to what ships to one country and defaults to US via GET /v1/brands
goody_get_v1_cardsREADPage through the digital greeting cards a gift can be wrapped in, each with its image, thumbnail and the occasions it suits. A card id is what `card_id` on Send a gift batch names, and a card is REQUIRED whenever a message is sent, because the message is shown after the card is opened via GET /v1/cards
goody_get_v1_categoriesREADList the storefront categories a product listing can be filtered by, each with its name, stable slug, SVG icon, whether it appears in the Categories navigation, in the Occasions navigation, or in neither, and which one is the store's default landing category via GET /v1/categories
goody_get_v1_collectionsREADPage through this account's gift collections -- curated groups of products a recipient chooses one of. Each row carries the collection's title, its owning workspace, whether it currently has a published version and that version's price in cents including shipping. `published=true` narrows the list to the published ones via GET /v1/collections
goody_get_v1_collections_by_idREADRead one gift collection by id: its title, owning workspace, published state, published price in cents including shipping, and the product that represents it in a cart. A collection is sent like any other product, so this is how to check what a recipient will be offered before sending it via GET /v1/collections/{id}
goody_get_v1_gift_templatesREADPage through this user's saved gift templates -- a reusable cart plus a greeting card. Each row carries the template's name, its products subtotal in USD cents before shipping, fees and tax, a comma-separated product summary, up to four product thumbnails, whether everything in it ships free, and its card via GET /v1/gift_templates
goody_get_v1_gift_templates_by_idREADRead one saved gift template by id: name, products subtotal in USD cents before shipping, fees and tax, product count and summary, thumbnails, free-shipping flag, greeting card and card image, and its created and updated timestamps via GET /v1/gift_templates/{id}
goody_get_v1_gifts_of_choiceREADList the Gift of Choice products -- the flagship one (`kind: default`) and any seasonal one -- each with the price range in cents a sender may fund it with (`price_max` null means unlimited) and the occasions it suits. A gift of choice is sent like any other product: put its id in the cart with a `variable_price` inside that range via GET /v1/gifts_of_choice
goody_get_v1_meREADReturn who this credential belongs to: the associated email address and the account's public app id. Goody's own documentation names this as the smoke test for a new API key, and it is the cheapest read on the surface -- no argument, no pagination and nothing a plan can gate via GET /v1/me
goody_get_v1_order_activitiesREADPage through order status-change events -- each one an order plus the status it moved to and when -- newest first. `after` and `before` take an activity id and page around it, and `statuses` filters to the transitions you care about, which is what makes this the polling alternative to webhooks for tracking whether gifts were opened, accepted or shipped via GET /v1/order_activities
goody_get_v1_order_batchesREADPage through this account's order batches -- one batch per send, however many recipients it had. Each row carries the batch name, sender, message, greeting card, send method and status, recipient and order counts, scheduling and expiry, plus previews of the first ten orders and recipients. Walk a batch's full lists with List a batch's orders and List a batch's recipients via GET /v1/order_batches
goody_get_v1_order_batches_by_idREADRead one order batch by id: its batch name and reference id, sender and `from_name`, message and greeting card, cart, send method and send status, recipient and order counts, scheduling, expiry, owning workspace, and previews of its first ten orders and recipients via GET /v1/order_batches/{id}
goody_get_v1_order_batches_by_id_ordersREADPage through every order in one batch -- one order per recipient -- with each order's status, amounts in cents, cart, recipient, individual gift link, expiry and shipments. The batch itself only previews the first ten, so this is the full list via GET /v1/order_batches/{id}/orders
goody_get_v1_order_batches_by_id_recipientsREADPage through the recipients of one batch -- first name, last name and email as they were submitted. The batch itself previews only the first ten via GET /v1/order_batches/{id}/recipients
goody_get_v1_ordersREADPage through the individual orders this account has sent -- one per recipient -- with status, amounts in cents, cart, recipient, gift link, expiry, swap state and thank-you note. `created_at[after]` and `created_at[before]` bound the window. An order's `event_times` are returned only by Get a gift, not here via GET /v1/orders
goody_get_v1_orders_by_idREADRead one order by id, with everything the listing carries plus `event_times` -- the timeline this endpoint alone returns. Also the individual gift link (which hides the price), the recipient's view count and thank-you note, shipments, whether the gift was SWAPPED and, when it was, both the original cart and amounts and the post-swap ones via GET /v1/orders/{id}
goody_get_v1_payment_methodsREADList the payment methods saved on this account: id, name, cardholder name where there is one, and the available balance for the balance-backed ones. A `payment_method_id` from here is what Send a gift batch charges; sending with none named charges the FIRST method on the account via GET /v1/payment_methods
goody_get_v1_productsREADPage through the gift catalogue: each product's name, brand, price in cents, subtitles, images, attributes, variants and restricted states, and the minimum and maximum when its price is variable (a flex gift or a gift card). `use_custom_catalog=true` reads this account's own curated catalogue instead of Goody's whole one, `custom_catalog_show_inactive` includes what has been deactivated in it, and `country_code` narrows to what ships to one country via GET /v1/products
goody_get_v1_products_by_idREADRead one product by id: name, brand, price in cents, its variable-price range, subtitle and recipient-facing description, images, attributes, restricted states, and the variant groups with `variants_num_selectable` -- the number of variant names Send a gift batch must pass for a Direct Send of this product. `use_custom_catalog` reads it out of this account's own catalogue via GET /v1/products/{id}
goody_get_v1_shipping_countriesREADList the countries Goody can ship to: ISO 3166-1 alpha-2 code, name, and the shipping groups each belongs to. The `domestic` group is what the domestic-only product filter means, and a country here is what `country_code` on the brand and product listings accepts via GET /v1/shipping_countries
goody_get_v1_workspacesREADList the workspaces this credential can reach -- id and name. An organization is divided into workspaces, orders and batches live inside one, and Send a gift batch puts a batch in the OLDEST workspace the user can reach unless `workspace_id` names another via GET /v1/workspaces
goody_post_v1_commerce_user_payment_methodsWRITEStore a payment method against one of YOUR app's users (Goody's Commerce surface), from an `interim_card_key` minted by Goody's card form plus the cardholder name and billing address. This SAVES a card rather than charging it -- no money moves here -- and the stored id is what `payment_method_id` on Send a gift batch then names, alongside the same `commerce_end_user_id`. Only `card` is supported as `payment_method_type` via POST /v1/commerce_user_payment_methods
goody_post_v1_order_batchesWRITESEND GIFTS, AND SPEND MONEY. This creates and sends an order batch: a cart of products, a list of recipients, a `from_name`, a `send_method` (`email_and_link` emails each recipient, `link_multiple_custom_list` returns gift links with no email, `direct_send` ships to a mailing address) and, optionally, a greeting card and message, a swap policy, an expiry, an international shipping tier and a workspace. It CHARGES `payment_method_id`, or the account's first payment method when none is named, and it is the only tool in this integration that moves money. `scheduled_send_on` defers the send; `customer_reference_id` is an idempotency key Goody rejects a duplicate of rather than sending twice. Price it first with Price a gift batch, which charges nothing via POST /v1/order_batches
goody_post_v1_order_batches_priceWRITEPrice a gift batch WITHOUT sending it: post the same cart, recipients and send method that Send a gift batch takes and get the cost back, in USD cents. Nothing is created, nobody is emailed and no payment method is charged, which is what makes this the safe way to quote a send or to check a cart is valid before committing to it via POST /v1/order_batches/price
goody_post_v1_orders_by_id_cancelWRITECancel one order that the recipient has not accepted yet, which refunds it. It only reaches an UNACCEPTED gift: once a recipient has accepted, the order is in fulfilment and this is not the way back. Goody's own scope prose files cancelling an unaccepted order under the permission that costs nothing, and cancelling returns money rather than spending it via POST /v1/orders/{id}/cancel
goody_post_v1_orders_by_id_update_expirationWRITEMove one order's expiry to a new ISO 8601 date and time. Costs nothing and sends nothing: it changes how long the recipient has to accept the gift they were already sent. Orders paid from account balance must carry an expiry via POST /v1/orders/{id}/update_expiration
goody_post_v1_webhooksWRITERegister a URL for Goody to call on order events, optionally filtered to named events. This is the push alternative to polling List order activity, and it sends Goody's order data to whatever host is named here -- so the URL must be one you control via POST /v1/webhooks
Often connected alongside
Put Goody behind one governed endpoint.
Same permissions, same audit trail, whatever else you connect next.