Skip to main content

Partner API, Website, Blog, Flower & Product Catalogs

What it is​

A grab-bag of external-facing surfaces: third-party-api (a scoped, permissioned API for external partners), website (a per-event public landing page), blog and flower (content/commerce verticals with their own admin+public split), and product/partybundle (additional catalog surfaces alongside Giftstore).

How it works​

Third-Party API (partner integrations)​

A separate permission model from the rest of the platform — partners get scoped API keys rather than user JWTs, checked via requirePermission(ApiPermission.X). Permissions: events:read, tickets:read, purchases:create, purchases:direct, purchases:read, bundled into presets (readonly, standard, full) for quick assignment rather than hand-picking permissions per partner. This is the caller behind the third-party-purchase payout service type in Payments & Payouts — a partner-initiated purchase settles through the same payout pipeline as any other, just tagged with a different destination.

Website​

A minimal public landing page per event: POST/PUT/DELETE /website/event/:eventId (planner manages it, authenticated), GET /website/public/:websiteId (public view), GET /website/public/memories (recent public memories feed — cross-references Memories & Comments). Distinct from an event's normal invite/RSVP flow — this is a shareable standalone page.

Blog​

Conventional CMS split: GET /blog, GET /blog/:slug public; full CRUD (listAll, getById, create, update, delete) admin-gated (Zod-validated create/update).

Flower​

An admin-managed product vertical (SKUs, orders) with a public product listing (GET /flower/products) but everything else — order management, product create/update — admin-only. Structurally similar to a lightweight version of Giftstore, scoped to one product category rather than a general catalog.

Product & Partybundle​

product is yet another catalog surface (findAll, getSingleProduct, plus a gift-store/items alias overlapping with the giftstore module) and partybundle is simple bundle CRUD (addPartyBundle, findOnePartyBundle, admin-gated findAllPartyBundles) — referenced from Budget, Cart & Orders as the partybundle cart namespace.

Key business rules & edge cases​

  • There are now multiple overlapping product/catalog surfaces (giftstore, product, flower, partybundle) — before adding a new product type, check whether it belongs in an existing catalog rather than becoming a fifth one. This guide doesn't attempt to fully reconcile them; treat the overlap as a real architectural question worth asking rather than an already-settled distinction.
  • Third-party API permissions are additive scopes, not a single access level — a partner with purchases:create but not purchases:direct can create normal-flow purchases but not whatever the "direct" flow specifically unlocks; check the exact preset/permission set granted rather than assuming "the partner has API access" implies full access.

Not yet in the generated OpenAPI spec. GET /v1/blog, GET /v1/website/public/{websiteId}, GET /v1/flower/products, partner endpoints under the third-party-api prefix (partner-specific base path, not /v1/*).

  • src/modules/third-party-api/ — routes/controllers, types/permissions.types.ts (ApiPermission, PERMISSION_PRESETS)
  • src/modules/website/website.routes.ts, website.controller.ts
  • src/modules/blog/blog.routes.ts, blog.controller.ts
  • src/modules/flower/ — routes/controller
  • src/modules/product/ — routes/controller
  • src/modules/partybundle/partybundle.route.ts, partybundle.controller.ts