{"openapi":"3.1.0","info":{"title":"RUO Pro API","version":"0.0.1","description":"The external API of RUO Pro (the flightdeck white-label commerce platform): the fdk_-credentialed merchant API — orders, catalog, webhooks, subscriptions, gift cards, returns, reporting, and API-key management — plus the public storefront surface (catalog/search/collections + checkout). Authenticate merchant routes with `Authorization: Bearer fdk_...`; the tenant and granted scopes are carried by the credential itself. Internal operator routes are intentionally not documented here. See ADR-0007."},"servers":[{"url":"http://localhost:3000","description":"local dev"},{"url":"https://api.ruo.pro","description":"production"}],"tags":[{"name":"storefront","description":"Public, unauthenticated catalog/search/collections."},{"name":"checkout","description":"Storefront-token checkout placement + shopper order ops."},{"name":"merchant-orders","description":"fdk_ merchant: orders, catalog, webhooks."},{"name":"merchant-commerce","description":"fdk_ merchant: subscriptions, gift cards, returns."},{"name":"merchant-ops","description":"fdk_ merchant: marketing, media, purchasing, fraud, analytics."},{"name":"merchant-credentials","description":"fdk_ merchant: API-key lifecycle — list, issue (subset-gated), revoke."}],"components":{"securitySchemes":{"fdkBearer":{"type":"http","scheme":"bearer","bearerFormat":"fdk_<opaque>","description":"Tenant-scoped merchant credential (FD-8). The tenant and granted scopes are carried by the credential; never pass a tenant in the path or body."},"storefrontToken":{"type":"apiKey","in":"header","name":"x-storefront-token","description":"Narrow storefront BFF credential (B7-4). Places a checkout / reads a shopper's own data for one deployment; rejected on every operator route."}},"schemas":{"ErrorBody":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","example":"invalid_body"},"message":{"type":"string","example":"url and a non-empty events array are required"},"correlationId":{"type":"string","format":"uuid"}},"required":["code","message"]}},"required":["error"]},"SiteSection":{"type":"object","properties":{"type":{"type":"string","example":"header-nav"},"props":{"type":"object","additionalProperties":{},"description":"Section props — shape varies per section type."}},"required":["type","props"],"additionalProperties":{}},"SiteManifest":{"type":"object","properties":{"store":{"type":"object","additionalProperties":{},"description":"Store identity (id, slug, status)."},"brand":{"type":"object","additionalProperties":{},"description":"Brand identity (name, logo refs)."},"theme":{"type":"object","additionalProperties":{},"description":"Design tokens (color/type/layout) the renderer maps onto CSS custom properties."},"template":{"type":"object","properties":{"id":{"type":"string","example":"base-v1"},"sections":{"type":"array","items":{"$ref":"#/components/schemas/SiteSection"},"description":"The merchant-authored home-page section list, in render order (e.g. announcement-bar, header-nav, epic-hero, product-grid, legal-footer)."}},"additionalProperties":{}},"seo":{"type":"object","additionalProperties":{}},"behavior":{"type":"object","additionalProperties":{},"description":"Feature toggles (search, accounts, consent surfaces)."}},"additionalProperties":{}},"StorefrontVariant":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"product_id":{"type":"string"},"sku":{"type":"string","example":"NOVA-BPC-5MG"},"label":{"type":["string","null"],"example":"5mg vial"},"price_cents":{"type":"integer","example":4999},"currency":{"type":"string","example":"USD"}},"required":["id","tenant_ref","product_id","sku","label","price_cents","currency"]},"StorefrontProduct":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"slug":{"type":"string","example":"bpc-157"},"name":{"type":"string","example":"BPC-157"},"description":{"type":["string","null"]},"status":{"type":"string","enum":["draft","active","archived"],"example":"active"},"image_asset_ref":{"type":["string","null"]},"image_url":{"type":["string","null"],"example":"https://assets.ruo.pro/stores/ruo-demo/assets/<sha256>.png"},"is_subscription":{"type":"boolean"},"subscription_interval":{"type":["string","null"],"enum":["day","week","month","year"]},"subscription_interval_count":{"type":["integer","null"]},"subscription_price_cents":{"type":["integer","null"]},"variants":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontVariant"}}},"required":["id","tenant_ref","slug","name","description","status","image_asset_ref","image_url","is_subscription","subscription_interval","subscription_interval_count","subscription_price_cents","variants"]},"StorefrontSearchFilters":{"type":"object","properties":{"priceMinCents":{"type":["integer","null"]},"priceMaxCents":{"type":["integer","null"]},"collectionSlug":{"type":["string","null"]}},"required":["priceMinCents","priceMaxCents","collectionSlug"]},"StorefrontSearchFacets":{"type":"object","properties":{"price_buckets":{"type":"array","items":{"type":"object","properties":{"min_cents":{"type":"integer"},"max_cents":{"type":["integer","null"]},"count":{"type":"integer"}},"required":["min_cents","max_cents","count"]}},"collections":{"type":"array","items":{"type":"object","properties":{"slug":{"type":"string"},"title":{"type":"string"},"count":{"type":"integer"}},"required":["slug","title","count"]}}},"required":["price_buckets","collections"]},"StorefrontCollection":{"type":"object","properties":{"slug":{"type":"string","example":"peptides"},"title":{"type":"string","example":"Peptides"},"description":{"type":["string","null"]}},"required":["slug","title","description"]},"StorefrontShipTo":{"type":["object","null"],"properties":{"label":{"type":"string"},"line1":{"type":"string"},"line2":{"type":["string","null"]},"city":{"type":"string"},"state":{"type":"string"},"postal_code":{"type":"string"},"country":{"type":"string","example":"US"}},"required":["label","line1","line2","city","state","postal_code","country"]},"StorefrontOrder":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"order_number":{"type":"integer","example":1042},"customer_ref":{"type":"string"},"person_id":{"type":["string","null"]},"status":{"type":"string","enum":["pending_payment","placed","processing","on_hold","shipped","partially_shipped","delivered","cancelled","refunded","partially_refunded","payment_failed"],"example":"placed"},"coupon_code":{"type":["string","null"]},"subtotal_cents":{"type":"integer"},"discount_cents":{"type":"integer"},"shipping_cents":{"type":"integer"},"tax_cents":{"type":"integer"},"total_cents":{"type":"integer"},"currency":{"type":"string","example":"USD"},"idempotency_key":{"type":"string"},"ship_to":{"$ref":"#/components/schemas/StorefrontShipTo"}},"required":["id","tenant_ref","order_number","customer_ref","person_id","status","coupon_code","subtotal_cents","discount_cents","shipping_cents","tax_cents","total_cents","currency","idempotency_key","ship_to"]},"StorefrontOrderItem":{"type":"object","properties":{"id":{"type":"string"},"order_id":{"type":"string"},"product_id":{"type":"string"},"variant_id":{"type":"string"},"product_name":{"type":"string"},"sku":{"type":"string"},"quantity":{"type":"integer"},"unit_price_cents":{"type":"integer"},"line_total_cents":{"type":"integer"}},"required":["id","order_id","product_id","variant_id","product_name","sku","quantity","unit_price_cents","line_total_cents"]},"StorefrontCard":{"type":"object","properties":{"ccnumber":{"type":"string"},"ccexp":{"type":"string","example":"12/28"},"cvv":{"type":"string"}},"required":["ccnumber","ccexp"],"description":"Required only when a card charge is actually needed (store credit + gift card may cover the whole total)."},"StorefrontCheckoutRequest":{"allOf":[{"type":"object","properties":{"customer_ref":{"type":"string","example":"guest:jane@example.com"},"person_id":{"type":"string"},"coupon_code":{"type":"string"},"referral_code":{"type":"string","description":"Shopper referral code (?ref= landing, BFF-forwarded from the httpOnly fd_ref cookie). 1-64 chars [A-Za-z0-9_-]; anything else is dropped, never an error. Validated downstream by affiliates — an unknown code attributes nothing.","example":"lori-h"},"items":{"type":"array","items":{"type":"object","properties":{"variant_id":{"type":"string"},"quantity":{"type":"integer","exclusiveMinimum":0}},"required":["variant_id","quantity"]},"minItems":1},"card":{"$ref":"#/components/schemas/StorefrontCard"},"apply_store_credit":{"type":"boolean"},"gift_card_code":{"type":"string"},"subscribe":{"type":"boolean","description":"FD Epic 7 subscribe-and-save: also start a subscription for every subscription-eligible line."},"shipping_address":{"allOf":[{"$ref":"#/components/schemas/StorefrontShipTo"},{"type":"object"}]},"email":{"type":"string"},"ip":{"type":"string"}},"required":["customer_ref","items"]},{"type":"object","properties":{"shipping":{"type":"object","properties":{"mode":{"type":"string","enum":["flat"]},"flat_rate_cents":{"type":"integer","minimum":0},"expedited_rate_cents":{"type":"integer","minimum":0},"max_cents":{"type":"integer","minimum":0},"free_shipping_threshold_cents":{"type":["integer","null"],"minimum":0}},"required":["mode","flat_rate_cents","expedited_rate_cents","max_cents"]},"tax":{"type":"object","properties":{"provider":{"type":"string","enum":["null","flat_rate","stripe_tax"]},"rate_bps":{"type":"integer","minimum":0,"example":875}},"required":["provider","rate_bps"]},"expedited":{"type":"boolean"}},"description":"Store shipping+tax POLICY, forwarded server-side by the storefront BFF from the resolved manifest. Never a client total — the order total is always recomputed from commerce's own catalog prices. Omit for the legacy subtotal-only path (shipping/tax 0)."}]},"StorefrontCheckoutPreviewRequest":{"allOf":[{"type":"object","properties":{"customer_ref":{"type":"string","description":"Group pricing keys off this; omit/empty for a guest (list prices)."},"coupon_code":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"variant_id":{"type":"string"},"quantity":{"type":"integer","exclusiveMinimum":0}},"required":["variant_id","quantity"]},"minItems":1}},"required":["items"]},{"type":"object","properties":{"shipping":{"type":"object","properties":{"mode":{"type":"string","enum":["flat"]},"flat_rate_cents":{"type":"integer","minimum":0},"expedited_rate_cents":{"type":"integer","minimum":0},"max_cents":{"type":"integer","minimum":0},"free_shipping_threshold_cents":{"type":["integer","null"],"minimum":0}},"required":["mode","flat_rate_cents","expedited_rate_cents","max_cents"]},"tax":{"type":"object","properties":{"provider":{"type":"string","enum":["null","flat_rate","stripe_tax"]},"rate_bps":{"type":"integer","minimum":0,"example":875}},"required":["provider","rate_bps"]},"expedited":{"type":"boolean"}},"description":"Store shipping+tax POLICY, forwarded server-side by the storefront BFF from the resolved manifest. Never a client total — the order total is always recomputed from commerce's own catalog prices. Omit for the legacy subtotal-only path (shipping/tax 0)."}]},"StorefrontRefundRequest":{"type":"object","properties":{"charge_id":{"type":"string"},"amount_cents":{"type":"integer","exclusiveMinimum":0},"reason":{"type":"string"}},"required":["charge_id"]},"StorefrontCancelRequest":{"type":"object","properties":{"charge_id":{"type":"string"},"reason":{"type":"string"},"actor":{"type":"string"}}},"StorefrontEditRequest":{"allOf":[{"type":"object","properties":{"edits":{"type":"array","items":{"type":"object","properties":{"order_item_id":{"type":"string"},"quantity":{"type":"integer","minimum":0}},"required":["order_item_id","quantity"]},"minItems":1},"charge_id":{"type":"string"},"card":{"$ref":"#/components/schemas/StorefrontCard"},"actor":{"type":"string"}},"required":["edits"]},{"type":"object","properties":{"shipping":{"type":"object","properties":{"mode":{"type":"string","enum":["flat"]},"flat_rate_cents":{"type":"integer","minimum":0},"expedited_rate_cents":{"type":"integer","minimum":0},"max_cents":{"type":"integer","minimum":0},"free_shipping_threshold_cents":{"type":["integer","null"],"minimum":0}},"required":["mode","flat_rate_cents","expedited_rate_cents","max_cents"]},"tax":{"type":"object","properties":{"provider":{"type":"string","enum":["null","flat_rate","stripe_tax"]},"rate_bps":{"type":"integer","minimum":0,"example":875}},"required":["provider","rate_bps"]},"expedited":{"type":"boolean"}},"description":"Store shipping+tax POLICY, forwarded server-side by the storefront BFF from the resolved manifest. Never a client total — the order total is always recomputed from commerce's own catalog prices. Omit for the legacy subtotal-only path (shipping/tax 0)."}]},"MerchantShipTo":{"type":["object","null"],"properties":{"label":{"type":"string"},"line1":{"type":"string"},"line2":{"type":["string","null"]},"city":{"type":"string"},"state":{"type":"string"},"postal_code":{"type":"string"},"country":{"type":"string"}},"required":["label","line1","line2","city","state","postal_code","country"]},"MerchantOrder":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenant_ref":{"type":"string"},"order_number":{"type":"integer","example":1042},"customer_ref":{"type":"string"},"person_id":{"type":["string","null"],"format":"uuid"},"status":{"type":"string","enum":["pending_payment","placed","processing","on_hold","shipped","partially_shipped","delivered","cancelled","refunded","partially_refunded","payment_failed"],"example":"placed"},"coupon_code":{"type":["string","null"]},"subtotal_cents":{"type":"integer","example":4999},"discount_cents":{"type":"integer","example":0},"shipping_cents":{"type":"integer","example":500},"tax_cents":{"type":"integer","example":412},"total_cents":{"type":"integer","example":5911},"currency":{"type":"string","example":"usd"},"idempotency_key":{"type":"string"},"ship_to":{"$ref":"#/components/schemas/MerchantShipTo"},"is_test":{"type":"boolean","description":"Operator-flagged test order — excluded from money reports."}},"required":["id","tenant_ref","order_number","customer_ref","person_id","status","coupon_code","subtotal_cents","discount_cents","shipping_cents","tax_cents","total_cents","currency","idempotency_key","ship_to","is_test"]},"MerchantOrderItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"order_id":{"type":"string","format":"uuid"},"product_id":{"type":"string","format":"uuid"},"variant_id":{"type":"string","format":"uuid"},"product_name":{"type":"string"},"sku":{"type":"string"},"quantity":{"type":"integer","example":2},"unit_price_cents":{"type":"integer","example":2499},"line_total_cents":{"type":"integer","example":4998}},"required":["id","order_id","product_id","variant_id","product_name","sku","quantity","unit_price_cents","line_total_cents"]},"MerchantOrderRefund":{"type":"object","properties":{"refund_id":{"type":"string"},"amount_cents":{"type":"integer","example":1500},"currency":{"type":"string","example":"USD"},"reason":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}},"required":["refund_id","amount_cents","currency","reason","created_at"]},"MerchantProduct":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenant_ref":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":["string","null"]},"status":{"type":"string","enum":["draft","active","archived"],"example":"active"},"image_asset_ref":{"type":["string","null"],"example":"asset:nova-peptide/ab12….png"},"is_subscription":{"type":"boolean"},"subscription_interval":{"type":["string","null"],"enum":["day","week","month","year"]},"subscription_interval_count":{"type":["integer","null"]},"subscription_price_cents":{"type":["integer","null"]}},"required":["id","tenant_ref","slug","name","description","status","image_asset_ref","is_subscription","subscription_interval","subscription_interval_count","subscription_price_cents"]},"MerchantWebhookSubscription":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string","enum":["commerce.order.placed.v1"],"example":"commerce.order.placed.v1"},"example":["commerce.order.placed.v1"]},"active":{"type":"boolean"},"consecutive_failures":{"type":"integer","example":0},"auto_paused_at":{"type":["string","null"],"format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","url","description","events","active","consecutive_failures","auto_paused_at","created_at","updated_at"]},"MerchantWebhookSubscriptionCreated":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string","format":"uri"},"description":{"type":["string","null"]},"events":{"type":"array","items":{"type":"string","enum":["commerce.order.placed.v1"],"example":"commerce.order.placed.v1"}},"active":{"type":"boolean"}},"required":["id","url","description","events","active"]},"MerchantCreateWebhookBody":{"type":"object","properties":{"url":{"type":"string","format":"uri","example":"https://example.com/hooks/orders"},"description":{"type":"string"},"events":{"type":"array","items":{"type":"string","enum":["commerce.order.placed.v1"],"example":"commerce.order.placed.v1"},"minItems":1,"example":["commerce.order.placed.v1"]}},"required":["url","events"]},"MerchantWebhookDelivery":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"subscription_id":{"type":"string","format":"uuid"},"event_id":{"type":"string"},"event_type":{"type":"string","description":"A deliverable event name, or the reserved `platform.test.v1` for test-fired deliveries.","example":"commerce.order.placed.v1"},"status":{"type":"string","enum":["pending","delivered","dead_lettered"],"example":"delivered"},"attempt_count":{"type":"integer","example":1},"next_retry_at":{"type":["string","null"],"format":"date-time"},"last_status_code":{"type":["integer","null"],"example":200},"last_attempt_error":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"delivered_at":{"type":["string","null"],"format":"date-time"},"dead_lettered_at":{"type":["string","null"],"format":"date-time"}},"required":["id","subscription_id","event_id","event_type","status","attempt_count","next_retry_at","last_status_code","last_attempt_error","created_at","delivered_at","dead_lettered_at"]},"SubscriptionView":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"person_id":{"type":"string"},"plan_ref":{"type":"string"},"interval":{"type":"string","enum":["day","week","month","year"]},"interval_count":{"type":"integer","example":1},"unit_price_cents":{"type":"integer","example":4900},"currency":{"type":"string","example":"USD"},"status":{"type":"string","enum":["active","past_due","paused","canceled"]},"next_bill_at":{"type":"string","format":"date-time"},"failure_count":{"type":"integer","example":0},"created_at":{"type":"string","format":"date-time"},"canceled_at":{"type":["string","null"],"format":"date-time"},"paused_at":{"type":["string","null"],"format":"date-time"}},"required":["id","tenant_ref","person_id","plan_ref","interval","interval_count","unit_price_cents","currency","status","next_bill_at","failure_count","created_at","canceled_at","paused_at"]},"GiftCardSummary":{"type":"object","properties":{"gift_card_id":{"type":"string"},"initial_cents":{"type":"integer","example":5000},"balance_cents":{"type":"integer","example":5000},"currency":{"type":"string","example":"USD"},"status":{"type":"string","enum":["active","void","redeemed"]},"created_at":{"type":"string","format":"date-time"}},"required":["gift_card_id","initial_cents","balance_cents","currency","status","created_at"]},"IssuedGiftCard":{"type":"object","properties":{"gift_card_id":{"type":"string"},"code":{"type":"string","example":"A1B2-C3D4-E5F6-G7H8"},"initial_cents":{"type":"integer","example":5000},"balance_cents":{"type":"integer","example":5000},"currency":{"type":"string","example":"USD"},"status":{"type":"string","enum":["active","void","redeemed"]}},"required":["gift_card_id","code","initial_cents","balance_cents","currency","status"]},"IssueGiftCardBody":{"type":"object","properties":{"amount_cents":{"type":"integer","exclusiveMinimum":0,"example":5000},"currency":{"type":"string","example":"USD"}},"required":["amount_cents"]},"VoidedGiftCard":{"type":"object","properties":{"gift_card_id":{"type":"string"},"status":{"type":"string","enum":["active","void","redeemed"]},"balance_cents":{"type":"integer","example":0},"voided_cents":{"type":"integer","example":5000},"currency":{"type":"string","example":"USD"}},"required":["gift_card_id","status","balance_cents","voided_cents","currency"]},"MerchantOrderActionBody":{"type":"object","properties":{"reason":{"type":"string"}}},"OrderReturn":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"order_id":{"type":"string"},"person_id":{"type":["string","null"]},"status":{"type":"string","enum":["requested","approved","received","refunded","rejected"]},"reason":{"type":["string","null"]},"charge_id":{"type":["string","null"]},"refund_id":{"type":["string","null"]},"refunded_cents":{"type":"integer","example":0}},"required":["id","tenant_ref","order_id","person_id","status","reason","charge_id","refund_id","refunded_cents"]},"OrderReturnLine":{"type":"object","properties":{"id":{"type":"string"},"return_id":{"type":"string"},"order_item_id":{"type":"string"},"variant_id":{"type":"string"},"sku":{"type":"string"},"quantity":{"type":"integer","example":1},"unit_price_cents":{"type":"integer","example":4900},"line_refund_cents":{"type":"integer","example":4900},"restocked":{"type":"boolean"}},"required":["id","return_id","order_item_id","variant_id","sku","quantity","unit_price_cents","line_refund_cents","restocked"]},"ApproveReturnBody":{"type":"object","properties":{"reason":{"type":"string"}}},"RejectReturnBody":{"type":"object","properties":{"reason":{"type":"string"}}},"ReceivedReturn":{"type":"object","properties":{"return_id":{"type":"string"},"status":{"type":"string","enum":["requested","approved","received","refunded","rejected"]},"order_id":{"type":"string"},"order_status":{"type":"string"},"refund_id":{"type":"string"},"refunded_cents":{"type":"integer","example":4900},"refunded_total_cents":{"type":"integer","example":4900},"lines":{"type":"array","items":{"type":"object","properties":{"order_item_id":{"type":"string"},"sku":{"type":"string"},"quantity":{"type":"integer"},"line_refund_cents":{"type":"integer","example":4900},"restocked":{"type":"boolean"}},"required":["order_item_id","sku","quantity","line_refund_cents","restocked"]}},"restock_incomplete":{"type":"boolean"},"restock_errors":{"type":"array","items":{"type":"string"}}},"required":["return_id","status","order_id","order_status","refund_id","refunded_cents","refunded_total_cents","lines"]},"ReceiveReturnBody":{"type":"object","properties":{}},"MerchantCredential":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"label":{"type":"string","example":"ci-reader"},"scopes":{"type":"array","items":{"type":"string","description":"One scope from the closed tenant-scope allowlist.","example":"read:own_orders"}},"createdAt":{"type":"string","format":"date-time"},"revokedAt":{"type":["string","null"],"format":"date-time","description":"null = active. Revocation is a recorded state, never a delete."}},"required":["id","label","scopes","createdAt","revokedAt"]},"MarketingCampaign":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string","enum":["drip","broadcast","abandoned_cart"]},"status":{"type":"string","example":"draft"},"audience_query":{"type":"object","additionalProperties":{},"description":"The stored audience selector."},"exit_on_order":{"type":"boolean","description":"When true, an order placed by an enrolled person cancels their active enrollment."},"frequency_cap_days":{"type":["integer","null"],"description":"Re-enrollment cap for once_per_person=false triggers; null = no cap."},"step_count":{"type":"integer"},"enrollment_count":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}},"required":["id","name","kind","status","audience_query","exit_on_order","frequency_cap_days","step_count","enrollment_count","created_at"]},"CreateCampaignBody":{"type":"object","properties":{"name":{"type":"string","minLength":1},"kind":{"type":"string","enum":["drip","broadcast","abandoned_cart"]},"audience_query":{"type":"object","additionalProperties":{},"description":"REQUIRED: the audience, stated explicitly — {predicate}, {segment_id}, or a legacy {type} shape. There is no implicit everyone."},"exit_on_order":{"type":"boolean","description":"Defaults true: an order by an enrolled person ends their journey."},"frequency_cap_days":{"type":["integer","null"],"minimum":0},"steps":{"type":"array","items":{"type":"object","properties":{"delay_seconds":{"type":"integer","minimum":0},"template_ref":{"type":"string","minLength":1,"description":"Must be a merchant-sendable template (welcome, abandoned-cart, abandoned-cart-reminder) or a pinned tenant template (tenant:<template_version_id>). Internal platform templates are refused with 403."},"from_address":{"type":"string","description":"Ignored on this merchant route: every step sends from the store's default sender (no-reply@{comms.senderDomain}, else the platform sender)."}},"required":["delay_seconds","template_ref"]},"minItems":1}},"required":["name","kind","audience_query","steps"]},"MarketingCampaignStep":{"type":"object","properties":{"step_order":{"type":"integer"},"delay_seconds":{"type":"integer","minimum":0},"template_ref":{"type":"string"},"from_address":{"type":"string"}},"required":["step_order","delay_seconds","template_ref","from_address"]},"MarketingEnrollment":{"type":"object","properties":{"id":{"type":"string"},"subject_ref":{"type":"string"},"person_id":{"type":["string","null"],"description":"The persons CDP id this enrollment belongs to. Null only on legacy enrollments the subjects backfill has not linked yet."},"email":{"type":"string"},"current_step":{"type":"integer"},"status":{"type":"string"},"next_run_at":{"type":"string","format":"date-time"},"entered_via":{"type":["string","null"],"description":"Provenance: manual | audience | lead | cart | trigger:<event>. Null on pre-P3 rows."}},"required":["id","subject_ref","person_id","email","current_step","status","next_run_at","entered_via"]},"MarketingSegment":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"query":{"type":"object","additionalProperties":{},"description":"The stored criteria: { predicate: <allow-listed predicate tree> }."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","name","query","created_at","updated_at"]},"MarketingCampaignTrigger":{"type":"object","properties":{"id":{"type":"string"},"event_name":{"type":"string","enum":["commerce.order.placed.v1","person.created.v1","subscription.cancelled.v1"]},"filter_query":{"type":["object","null"],"additionalProperties":{}},"once_per_person":{"type":"boolean"},"created_at":{"type":"string","format":"date-time"}},"required":["id","event_name","filter_query","once_per_person","created_at"]},"MarketingTenantTemplate":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"description":{"type":["string","null"]},"channel":{"type":"string","enum":["email"]},"current_version_id":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["id","key","description","channel","current_version_id","created_at","updated_at"]},"MarketingTenantTemplateVersion":{"type":"object","properties":{"id":{"type":"string"},"version_number":{"type":"integer"},"subject":{"type":"string"},"body":{"type":"string"},"variables":{"type":"array","items":{"type":"string"},"description":"Declared {{var}} names, extracted at create time."},"created_at":{"type":"string","format":"date-time"}},"required":["id","version_number","subject","body","variables","created_at"]},"MediaAsset":{"type":"object","properties":{"asset_id":{"type":"string"},"tenant_ref":{"type":"string"},"kind":{"type":"string","enum":["product_image","og_image","favicon","other"]},"storage_key":{"type":"string"},"asset_ref":{"type":"string"},"cdn_url":{"type":"string"},"content_type":{"type":"string"},"byte_size":{"type":["integer","null"]},"width":{"type":["integer","null"]},"height":{"type":["integer","null"]},"status":{"type":"string","enum":["pending","ready"]}},"required":["asset_id","tenant_ref","kind","storage_key","asset_ref","cdn_url","content_type","byte_size","width","height","status"]},"PresignUploadBody":{"type":"object","properties":{"kind":{"type":"string","enum":["product_image","og_image","favicon","other"]},"content_type":{"type":"string","example":"image/png"},"sha256":{"type":"string","description":"64 lowercase hex chars over the bytes."},"byte_size":{"type":"integer","minimum":0}},"required":["kind","content_type","sha256"]},"FinalizeAssetBody":{"type":"object","properties":{"width":{"type":"integer"},"height":{"type":"integer"},"byte_size":{"type":"integer"}}},"Vendor":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"name":{"type":"string"}},"required":["id","tenant_ref","name"]},"CreateVendorBody":{"type":"object","properties":{"name":{"type":"string","minLength":1}},"required":["name"]},"PurchaseOrder":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"vendor_id":{"type":"string"},"status":{"type":"string","enum":["open","partially_received","received","cancelled"]},"reference":{"type":["string","null"]}},"required":["id","tenant_ref","vendor_id","status","reference"]},"PurchaseOrderLine":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"purchase_order_id":{"type":"string"},"canonical_item_id":{"type":"string"},"expected_qty":{"type":"integer"},"unit_cost_cents":{"type":"integer","description":"Integer cents."},"received_qty":{"type":"integer"}},"required":["id","tenant_ref","purchase_order_id","canonical_item_id","expected_qty","unit_cost_cents","received_qty"]},"CreatePurchaseOrderBody":{"type":"object","properties":{"vendor_id":{"type":"string","minLength":1},"reference":{"type":["string","null"]},"lines":{"type":"array","items":{"type":"object","properties":{"canonical_item_id":{"type":"string","minLength":1},"expected_qty":{"type":"integer","exclusiveMinimum":0},"unit_cost_cents":{"type":"integer","minimum":0,"description":"Integer cents."}},"required":["canonical_item_id","expected_qty","unit_cost_cents"]},"minItems":1}},"required":["vendor_id","lines"]},"InventoryLot":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"canonical_item_id":{"type":"string"},"vendor_lot":{"type":["string","null"]},"internal_lot":{"type":"string"},"mfg_date":{"type":["string","null"]},"exp_date":{"type":["string","null"]},"qty_received":{"type":"integer"},"disposition":{"type":"string"},"disposition_reason":{"type":["string","null"]},"unit_cost_cents":{"type":["integer","null"],"description":"Landed cost per unit (integer cents); null when unknown."}},"required":["id","tenant_ref","canonical_item_id","vendor_lot","internal_lot","mfg_date","exp_date","qty_received","disposition","disposition_reason","unit_cost_cents"]},"ReceivePurchaseOrderBody":{"type":"object","properties":{"line_id":{"type":"string","minLength":1},"internal_lot":{"type":"string","minLength":1},"qty_received":{"type":"integer","exclusiveMinimum":0},"vendor_lot":{"type":["string","null"]},"mfg_date":{"type":["string","null"]},"exp_date":{"type":["string","null"]},"location_id":{"type":["string","null"]}},"required":["line_id","internal_lot","qty_received"]},"FulfillmentNode":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"kind":{"type":"string","enum":["own_warehouse","threepl","dropship_vendor"]},"name":{"type":"string"},"location":{"type":["string","null"]},"vendor_ref":{"type":["string","null"]}},"required":["id","tenant_ref","kind","name","location","vendor_ref"]},"CreateFulfillmentNodeBody":{"type":"object","properties":{"kind":{"type":"string","enum":["own_warehouse","threepl","dropship_vendor"]},"name":{"type":"string","minLength":1},"location":{"type":["string","null"]},"vendor_ref":{"type":["string","null"]}},"required":["kind","name"]},"FulfillmentQueueRow":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"order_id":{"type":"string"},"order_number":{"type":"integer"},"customer_ref":{"type":"string"},"status":{"type":"string"},"mode":{"type":"string"},"node_id":{"type":["string","null"]}},"required":["id","tenant_ref","order_id","order_number","customer_ref","status","mode","node_id"]},"DropshipDispatch":{"type":"object","properties":{"id":{"type":"string"},"tenant_ref":{"type":"string"},"queue_id":{"type":"string"},"queue_item_id":{"type":"string"},"node_id":{"type":"string"},"sku":{"type":"string"},"qty":{"type":"integer"},"unit_cost_cents":{"type":["integer","null"],"description":"Resolved landed cost per unit (integer cents); null when unknown."},"status":{"type":"string","enum":["dispatched","shipped"]}},"required":["id","tenant_ref","queue_id","queue_item_id","node_id","sku","qty","unit_cost_cents","status"]},"DropshipBody":{"type":"object","properties":{"node_id":{"type":"string","minLength":1},"lines":{"type":"array","items":{"type":"object","properties":{"queue_item_id":{"type":"string","minLength":1},"unit_cost_cents":{"type":"integer","minimum":0,"description":"Fallback per-unit cost (integer cents)."}},"required":["queue_item_id","unit_cost_cents"]}}},"required":["node_id"]},"FraudBan":{"type":"object","properties":{"ban_id":{"type":"string"},"entity_type":{"type":"string","enum":["ip","email","card_fingerprint","person"]},"entity_hash_preview":{"type":"string","description":"A short preview of the fingerprint; the raw value is never stored."},"reason":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}},"required":["ban_id","entity_type","entity_hash_preview","reason","created_at"]},"AddBanBody":{"type":"object","properties":{"entity_type":{"type":"string","enum":["ip","email","card_fingerprint","person"]},"value":{"type":"string","minLength":1,"description":"The raw identifier to fingerprint."},"reason":{"type":["string","null"]}},"required":["entity_type","value"]},"RevenueDayBucket":{"type":"object","properties":{"date":{"type":"string","description":"UTC YYYY-MM-DD.","example":"2026-08-14"},"order_count":{"type":"integer"},"gross_cents":{"type":"integer"},"refund_cents":{"type":"integer"},"net_cents":{"type":"integer"}},"required":["date","order_count","gross_cents","refund_cents","net_cents"]}},"parameters":{}},"paths":{"/v1/tenants/{tenant}/site":{"get":{"tags":["storefront"],"summary":"Get a live store's active site manifest (sections, nav, theme)","security":[],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"}],"responses":{"200":{"description":"The ACTIVE manifest version for a live store — the same data the hosted renderer resolves. Sends an `ETag` (the manifest row hash); a conditional GET with `If-None-Match` answers 304. Fail-closed: an unknown tenant OR a store that is not live is a 404 (`unknown_tenant`) — never an empty manifest; a failed read is a 503, never absence.","content":{"application/json":{"schema":{"type":"object","properties":{"tenant_ref":{"type":"string","example":"nova-peptide"},"version":{"type":"integer","description":"The active manifest version number.","example":3},"manifest":{"$ref":"#/components/schemas/SiteManifest"}},"required":["tenant_ref","version","manifest"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/catalog/products":{"get":{"tags":["storefront"],"summary":"List a store's active catalog products (with variants)","security":[],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"}],"responses":{"200":{"description":"The store's active products, each with its variants.","content":{"application/json":{"schema":{"type":"object","properties":{"products":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontProduct"}}},"required":["products"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/catalog/products/{slug}":{"get":{"tags":["storefront"],"summary":"Get one active product by slug (with variants)","security":[],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"},{"schema":{"type":"string","example":"bpc-157"},"required":true,"name":"slug","in":"path"}],"responses":{"200":{"description":"The product and its variants.","content":{"application/json":{"schema":{"type":"object","properties":{"product":{"$ref":"#/components/schemas/StorefrontProduct"}},"required":["product"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/catalog/search":{"get":{"tags":["storefront"],"summary":"Full-text catalog search with price/collection facets","security":[],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"},{"schema":{"type":"string","example":"bpc"},"required":false,"name":"q","in":"query"},{"schema":{"type":"string","example":"peptides"},"required":false,"name":"collection","in":"query"},{"schema":{"type":["integer","null"],"minimum":0},"required":false,"name":"price_min_cents","in":"query"},{"schema":{"type":["integer","null"],"minimum":0},"required":false,"name":"price_max_cents","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"example":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"Matching active products (with variants) plus the applied filters and the full facet counts. An empty/blank `q` returns an empty, unfiltered result set — not an error.","content":{"application/json":{"schema":{"type":"object","properties":{"query":{"type":"string"},"result_count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"filters":{"$ref":"#/components/schemas/StorefrontSearchFilters"},"facets":{"$ref":"#/components/schemas/StorefrontSearchFacets"},"products":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontProduct"}}},"required":["query","result_count","limit","offset","filters","facets","products"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/catalog/collections":{"get":{"tags":["storefront"],"summary":"List a store's collections","security":[],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"}],"responses":{"200":{"description":"The store's collections.","content":{"application/json":{"schema":{"type":"object","properties":{"collections":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontCollection"}}},"required":["collections"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/catalog/collections/{slug}":{"get":{"tags":["storefront"],"summary":"Get one collection and its active products","security":[],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"},{"schema":{"type":"string","example":"peptides"},"required":true,"name":"slug","in":"path"}],"responses":{"200":{"description":"The collection and its active products (each with variants).","content":{"application/json":{"schema":{"type":"object","properties":{"collection":{"$ref":"#/components/schemas/StorefrontCollection"},"products":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontProduct"}}},"required":["collection","products"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/store-credit/balance":{"get":{"tags":["checkout"],"summary":"Read a shopper's store-credit balance (checkout affordance)","security":[{"storefrontToken":[]}],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"},{"schema":{"type":"string","example":"guest:jane@example.com"},"required":true,"name":"customer_ref","in":"query"}],"responses":{"200":{"description":"The shopper's known store-credit balance. A failed read is a 503, never a laundered zero balance.","content":{"application/json":{"schema":{"type":"object","properties":{"customer_ref":{"type":"string"},"balance_cents":{"type":"integer","example":1500},"currency":{"type":"string","example":"USD"}},"required":["customer_ref","balance_cents","currency"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/checkout":{"post":{"tags":["checkout"],"summary":"Place an order (tender + capture): store credit → gift card → card","security":[{"storefrontToken":[]}],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"},{"schema":{"type":"string","minLength":1,"description":"REQUIRED. Deterministic per business event (derive it from the cart/order attempt, never a fresh random value per retry) — a retried request with the same key replays the original outcome instead of re-charging.","example":"cart-8c1f2a:attempt-1"},"required":true,"name":"Idempotency-Key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorefrontCheckoutRequest"}}}},"responses":{"200":{"description":"Idempotent replay of a checkout that already placed (same Idempotency-Key). No re-charge.","content":{"application/json":{"schema":{"type":"object","properties":{"order":{"$ref":"#/components/schemas/StorefrontOrder"},"items":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontOrderItem"}},"replayed":{"type":"boolean"},"outcome":{"type":"string","enum":["already_placed"]},"issued_gift_cards":{"type":"array","items":{"type":"object","properties":{"order_item_id":{"type":"string"},"gift_card_id":{"type":"string"},"code":{"type":["string","null"]},"amount_cents":{"type":"integer"}},"required":["order_item_id","gift_card_id","code","amount_cents"]}},"subscriptions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"plan_ref":{"type":"string"},"interval":{"type":"string","enum":["day","week","month","year"]},"interval_count":{"type":"integer"},"unit_price_cents":{"type":"integer"},"currency":{"type":"string"},"status":{"type":"string","example":"active"},"next_bill_at":{"type":"string","format":"date-time"}},"required":["id","plan_ref","interval","interval_count","unit_price_cents","currency","status","next_bill_at"]}}},"required":["order","items","replayed","outcome","issued_gift_cards"]}}}},"201":{"description":"Order placed and captured. `card_charged_cents` + `store_credit_applied_cents` + `gift_card_applied_cents` are the tender split (integer cents).","content":{"application/json":{"schema":{"type":"object","properties":{"order":{"$ref":"#/components/schemas/StorefrontOrder"},"items":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontOrderItem"}},"charge_id":{"type":["string","null"]},"intent_id":{"type":["string","null"]},"card_charged_cents":{"type":"integer"},"store_credit_applied_cents":{"type":"integer"},"gift_card_applied_cents":{"type":"integer"},"gift_card_id":{"type":["string","null"]},"issued_gift_cards":{"type":"array","items":{"type":"object","properties":{"order_item_id":{"type":"string"},"gift_card_id":{"type":"string"},"code":{"type":["string","null"]},"amount_cents":{"type":"integer"}},"required":["order_item_id","gift_card_id","code","amount_cents"]}},"subscriptions":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"plan_ref":{"type":"string"},"interval":{"type":"string","enum":["day","week","month","year"]},"interval_count":{"type":"integer"},"unit_price_cents":{"type":"integer"},"currency":{"type":"string"},"status":{"type":"string","example":"active"},"next_bill_at":{"type":"string","format":"date-time"}},"required":["id","plan_ref","interval","interval_count","unit_price_cents","currency","status","next_bill_at"]}},"replayed":{"type":"boolean"},"outcome":{"type":"string","enum":["placed"]}},"required":["order","items","charge_id","intent_id","card_charged_cents","store_credit_applied_cents","gift_card_applied_cents","gift_card_id","issued_gift_cards","subscriptions","replayed","outcome"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/checkout/preview":{"post":{"tags":["checkout"],"summary":"Read-only coupon/pricing preview — the totals placing this cart would charge","security":[{"storefrontToken":[]}],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorefrontCheckoutPreviewRequest"}}}},"responses":{"200":{"description":"The SERVER-computed totals (same catalog-price + group-pricing + coupon + fail-closed shipping/tax legs placement runs). Nothing is written; no coupon redemption is consumed. A refused coupon answers with the SAME error codes placement refuses with (coupon_not_found / coupon_inactive / coupon_exhausted).","content":{"application/json":{"schema":{"type":"object","properties":{"subtotal_cents":{"type":"integer"},"discount_cents":{"type":"integer"},"shipping_cents":{"type":"integer"},"tax_cents":{"type":"integer"},"total_cents":{"type":"integer"},"currency":{"type":"string"},"coupon_code":{"type":["string","null"]}},"required":["subtotal_cents","discount_cents","shipping_cents","tax_cents","total_cents","currency","coupon_code"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/checkout/orders/{id}/refund":{"post":{"tags":["checkout"],"summary":"Refund a placed order's charge (full or partial)","security":[{"storefrontToken":[]}],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"},{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"description":"REQUIRED. Deterministic per business event (derive it from the cart/order attempt, never a fresh random value per retry) — a retried request with the same key replays the original outcome instead of re-charging.","example":"cart-8c1f2a:attempt-1"},"required":true,"name":"Idempotency-Key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorefrontRefundRequest"}}}},"responses":{"200":{"description":"Refund settled; the order was walked to (partially_)refunded.","content":{"application/json":{"schema":{"type":"object","properties":{"refund_id":{"type":"string"},"charge_id":{"type":"string"},"order_id":{"type":"string"},"order_status":{"type":"string","enum":["pending_payment","placed","processing","on_hold","shipped","partially_shipped","delivered","cancelled","refunded","partially_refunded","payment_failed"],"example":"placed"},"amount_cents":{"type":"integer"},"refunded_total_cents":{"type":"integer"},"replayed":{"type":"boolean"}},"required":["refund_id","charge_id","order_id","order_status","amount_cents","refunded_total_cents","replayed"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/checkout/orders/{id}/cancel":{"post":{"tags":["checkout"],"summary":"Cancel a pre-fulfillment order (release inventory, refund payment)","security":[{"storefrontToken":[]}],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"},{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"description":"REQUIRED. Deterministic per business event (derive it from the cart/order attempt, never a fresh random value per retry) — a retried request with the same key replays the original outcome instead of re-charging.","example":"cart-8c1f2a:attempt-1"},"required":true,"name":"Idempotency-Key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorefrontCancelRequest"}}}},"responses":{"200":{"description":"Order cancelled; any reserved inventory released and any captured payment refunded. A fulfilled (shipped/delivered) order is refused (409) — it must go through returns.","content":{"application/json":{"schema":{"type":"object","properties":{"order_id":{"type":"string"},"order_status":{"type":"string","enum":["pending_payment","placed","processing","on_hold","shipped","partially_shipped","delivered","cancelled","refunded","partially_refunded","payment_failed"],"example":"placed"},"cancelled":{"type":"boolean"},"reservations_released":{"type":"integer"},"refunded":{"type":"boolean"},"refund_id":{"type":["string","null"]},"refunded_cents":{"type":"integer"},"replayed":{"type":"boolean"},"release_incomplete":{"type":"boolean"},"release_errors":{"type":"array","items":{"type":"string"}}},"required":["order_id","order_status","cancelled","reservations_released","refunded","refund_id","refunded_cents","replayed"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/checkout/orders/{id}/edit":{"post":{"tags":["checkout"],"summary":"Edit a pre-fulfillment order's line quantities and re-price","security":[{"storefrontToken":[]}],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"},{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","minLength":1,"description":"REQUIRED. Deterministic per business event (derive it from the cart/order attempt, never a fresh random value per retry) — a retried request with the same key replays the original outcome instead of re-charging.","example":"cart-8c1f2a:attempt-1"},"required":true,"name":"Idempotency-Key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StorefrontEditRequest"}}}},"responses":{"200":{"description":"Order re-priced. `adjustment` names the settlement: 'refunded' (paid decrease), 'captured' (paid increase), or 'none' (unpaid re-price).","content":{"application/json":{"schema":{"type":"object","properties":{"order":{"$ref":"#/components/schemas/StorefrontOrder"},"items":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontOrderItem"}},"old_total_cents":{"type":"integer"},"new_total_cents":{"type":"integer"},"delta_cents":{"type":"integer"},"adjustment":{"type":"string","enum":["none","refunded","captured"]},"refund_id":{"type":["string","null"]},"refunded_cents":{"type":"integer"},"charge_id":{"type":["string","null"]},"intent_id":{"type":["string","null"]},"captured_cents":{"type":"integer"},"reservations_released":{"type":"integer"}},"required":["order","items","old_total_cents","new_total_cents","delta_cents","adjustment","refund_id","refunded_cents","charge_id","intent_id","captured_cents","reservations_released"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/shopper/orders":{"get":{"tags":["checkout"],"summary":"List a signed-in shopper's own orders","security":[{"storefrontToken":[]}],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"},{"schema":{"type":"string"},"required":true,"name":"person_id","in":"query"}],"responses":{"200":{"description":"The shopper's own orders (scoped to tenant + person).","content":{"application/json":{"schema":{"type":"object","properties":{"orders":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontOrder"}}},"required":["orders"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/tenants/{tenant}/shopper/orders/{id}":{"get":{"tags":["checkout"],"summary":"Get one of a shopper's own orders (with items)","security":[{"storefrontToken":[]}],"parameters":[{"schema":{"type":"string","description":"The store's tenant slug.","example":"nova-peptide"},"required":true,"name":"tenant","in":"path"},{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":true,"name":"person_id","in":"query"}],"responses":{"200":{"description":"The order and its items. A not-owned or unknown order id is the same 404 (no cross-shopper probing).","content":{"application/json":{"schema":{"type":"object","properties":{"order":{"$ref":"#/components/schemas/StorefrontOrder"},"items":{"type":"array","items":{"$ref":"#/components/schemas/StorefrontOrderItem"}}},"required":["order","items"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/orders":{"get":{"tags":["merchant-orders"],"summary":"List the tenant's orders","description":"Requires the `read:own_orders` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"Every order for the credential's tenant.","content":{"application/json":{"schema":{"type":"object","properties":{"orders":{"type":"array","items":{"$ref":"#/components/schemas/MerchantOrder"}}},"required":["orders"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/orders/{id}":{"get":{"tags":["merchant-orders"],"summary":"Get one order with its line items","description":"Requires the `read:own_orders` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The order, its line items, and its refund records. `refunds: []` is the verified 'no refund records' answer (a refunded status with no record means an operator set the status without money movement); `refunds: null` means the refund read failed — unknown, never 'none'.","content":{"application/json":{"schema":{"type":"object","properties":{"order":{"$ref":"#/components/schemas/MerchantOrder"},"items":{"type":"array","items":{"$ref":"#/components/schemas/MerchantOrderItem"}},"refunds":{"type":["array","null"],"items":{"$ref":"#/components/schemas/MerchantOrderRefund"}}},"required":["order","items","refunds"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such order for this tenant (also returned cross-tenant)."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/catalog":{"get":{"tags":["merchant-orders"],"summary":"List the tenant's catalog products","description":"Requires the `read:own_catalog` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"Every product for the credential's tenant.","content":{"application/json":{"schema":{"type":"object","properties":{"products":{"type":"array","items":{"$ref":"#/components/schemas/MerchantProduct"}}},"required":["products"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/webhooks":{"get":{"tags":["merchant-orders"],"summary":"List the tenant's webhook subscriptions","description":"Requires the `manage:own_webhooks` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"Every webhook subscription for the credential's tenant.","content":{"application/json":{"schema":{"type":"object","properties":{"subscriptions":{"type":"array","items":{"$ref":"#/components/schemas/MerchantWebhookSubscription"}}},"required":["subscriptions"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-orders"],"summary":"Create a webhook subscription","description":"Requires the `manage:own_webhooks` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantCreateWebhookBody"}}}},"responses":{"201":{"description":"The created subscription plus its signing secret. The plaintext `secret` is returned exactly once, here — it is never readable again.","content":{"application/json":{"schema":{"type":"object","properties":{"subscription":{"$ref":"#/components/schemas/MerchantWebhookSubscriptionCreated"},"secret":{"type":"string","example":"whsec_…"}},"required":["subscription","secret"]}}}},"400":{"description":"Missing url/events, or one or more unknown event names."},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"The url failed the SSRF guard (private/loopback/metadata host)."},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/webhooks/{id}":{"delete":{"tags":["merchant-orders"],"summary":"Delete a webhook subscription","description":"Requires the `manage:own_webhooks` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Whether a subscription was deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":["deleted"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such subscription for this tenant (also returned cross-tenant)."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/webhooks/{id}/test":{"post":{"tags":["merchant-orders"],"summary":"Fire a signed test delivery at a webhook endpoint","description":"Requires the `manage:own_webhooks` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The honest outcome of a real signed delivery (event type `platform.test.v1`, payload `test: true`) — same HMAC scheme, same headers, same delivery ledger as a real event. A connection failure or non-2xx status is `outcome: \"failed\"` with the endpoint's status/error as-is; failed tests are recorded `dead_lettered` immediately (never retried) and never count toward the subscription's auto-pause threshold.","content":{"application/json":{"schema":{"type":"object","properties":{"delivery_id":{"type":"string","format":"uuid"},"event_type":{"type":"string","example":"platform.test.v1"},"outcome":{"type":"string","enum":["delivered","failed"]},"status_code":{"type":["integer","null"],"example":200},"latency_ms":{"type":["integer","null"],"example":184},"error":{"type":["string","null"]}},"required":["delivery_id","event_type","outcome","status_code","latency_ms","error"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such subscription for this tenant (also returned cross-tenant)."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/deliveries":{"get":{"tags":["merchant-orders"],"summary":"List webhook delivery attempts","description":"Requires the `manage:own_webhooks` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Restrict to one subscription's deliveries."},"required":false,"name":"subscription_id","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"The tenant's webhook delivery attempts, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"deliveries":{"type":"array","items":{"$ref":"#/components/schemas/MerchantWebhookDelivery"}}},"required":["deliveries"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/subscriptions":{"get":{"tags":["merchant-commerce"],"summary":"List this tenant's subscriptions","description":"Requires the `manage:own_subscriptions` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"example":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of the tenant's subscriptions.","content":{"application/json":{"schema":{"type":"object","properties":{"subscriptions":{"type":"array","items":{"$ref":"#/components/schemas/SubscriptionView"}},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["subscriptions","limit","offset"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/subscriptions/{id}":{"get":{"tags":["merchant-commerce"],"summary":"Get one of this tenant's subscriptions","description":"Requires the `manage:own_subscriptions` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The subscription.","content":{"application/json":{"schema":{"type":"object","properties":{"subscription":{"$ref":"#/components/schemas/SubscriptionView"}},"required":["subscription"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/subscriptions/{id}/cancel":{"post":{"tags":["merchant-commerce"],"summary":"Cancel one of this tenant's subscriptions","description":"Requires the `manage:own_subscriptions` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The subscription after the transition.","content":{"application/json":{"schema":{"type":"object","properties":{"subscription":{"$ref":"#/components/schemas/SubscriptionView"}},"required":["subscription"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"Invalid state transition for the subscription's current status."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/subscriptions/{id}/pause":{"post":{"tags":["merchant-commerce"],"summary":"Pause one of this tenant's subscriptions","description":"Requires the `manage:own_subscriptions` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The subscription after the transition.","content":{"application/json":{"schema":{"type":"object","properties":{"subscription":{"$ref":"#/components/schemas/SubscriptionView"}},"required":["subscription"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"Invalid state transition for the subscription's current status."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/subscriptions/{id}/resume":{"post":{"tags":["merchant-commerce"],"summary":"Resume one of this tenant's subscriptions","description":"Requires the `manage:own_subscriptions` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The subscription after the transition.","content":{"application/json":{"schema":{"type":"object","properties":{"subscription":{"$ref":"#/components/schemas/SubscriptionView"}},"required":["subscription"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"Invalid state transition for the subscription's current status."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/gift-cards":{"get":{"tags":["merchant-commerce"],"summary":"List this tenant's gift cards","description":"Requires the `manage:own_giftcards` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"example":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of the tenant's gift cards (no plaintext codes).","content":{"application/json":{"schema":{"type":"object","properties":{"gift_cards":{"type":"array","items":{"$ref":"#/components/schemas/GiftCardSummary"}},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["gift_cards","limit","offset"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-commerce"],"summary":"Issue a gift card","description":"Requires the `manage:own_giftcards` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssueGiftCardBody"}}}},"responses":{"201":{"description":"The newly issued gift card. `code` is the one-time plaintext code — returned here and ONLY here; a later read yields the hash only.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IssuedGiftCard"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/gift-cards/{id}/void":{"post":{"tags":["merchant-commerce"],"summary":"Void a gift card (zeroes its remaining balance)","description":"Requires the `manage:own_giftcards` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The card after the void. `voided_cents` is the balance that was extinguished (its liability is reversed in accounting).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VoidedGiftCard"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such gift card for this tenant."},"409":{"description":"The gift card is already void (a double-void is refused, not replayed)."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/orders/{id}/refund":{"post":{"tags":["merchant-commerce"],"summary":"Refund an order in full (card charge + any store-credit/gift-card tenders)","description":"Requires the `manage:own_orders` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOrderActionBody"}}}},"responses":{"200":{"description":"The refund outcome. Idempotent per order — a retry replays, never double-refunds.","content":{"application/json":{"schema":{"type":"object","properties":{"refund_id":{"type":"string"},"charge_id":{"type":"string"},"order_id":{"type":"string"},"order_status":{"type":"string","example":"refunded"},"amount_cents":{"type":"integer"},"refunded_total_cents":{"type":"integer"},"store_credit_returned_cents":{"type":"integer"},"gift_card_returned_cents":{"type":"integer"},"replayed":{"type":"boolean"}},"required":["refund_id","charge_id","order_id","order_status","amount_cents","refunded_total_cents","store_credit_returned_cents","gift_card_returned_cents","replayed"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such order for this tenant."},"409":{"description":"Already fully refunded, or the order has no card charge to refund (tender-only)."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/orders/{id}/cancel":{"post":{"tags":["merchant-commerce"],"summary":"Cancel an unfulfilled order (releases inventory, refunds any captured payment)","description":"Requires the `manage:own_orders` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MerchantOrderActionBody"}}}},"responses":{"200":{"description":"The cancel outcome. Idempotent per order.","content":{"application/json":{"schema":{"type":"object","properties":{"order_id":{"type":"string"},"order_status":{"type":"string","example":"refunded"},"cancelled":{"type":"boolean"},"reservations_released":{"type":"integer"},"refunded":{"type":"boolean"},"refund_id":{"type":["string","null"]},"refunded_cents":{"type":"integer"},"replayed":{"type":"boolean"}},"required":["order_id","order_status","cancelled","reservations_released","refunded","refund_id","refunded_cents","replayed"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such order for this tenant."},"409":{"description":"The order has already shipped/delivered — it must go through returns instead."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/returns":{"get":{"tags":["merchant-commerce"],"summary":"List this tenant's returns (RMA queue)","description":"Requires the `manage:own_returns` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"example":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of the tenant's returns, newest first.","content":{"application/json":{"schema":{"type":"object","properties":{"returns":{"type":"array","items":{"$ref":"#/components/schemas/OrderReturn"}},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["returns","limit","offset"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/returns/{id}":{"get":{"tags":["merchant-commerce"],"summary":"Get one of this tenant's returns","description":"Requires the `manage:own_returns` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The return and its lines.","content":{"application/json":{"schema":{"type":"object","properties":{"return":{"$ref":"#/components/schemas/OrderReturn"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/OrderReturnLine"}}},"required":["return","lines"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/returns/{id}/approve":{"post":{"tags":["merchant-commerce"],"summary":"Approve a return","description":"Requires the `manage:own_returns` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApproveReturnBody"}}}},"responses":{"200":{"description":"The return after the transition.","content":{"application/json":{"schema":{"type":"object","properties":{"return":{"$ref":"#/components/schemas/OrderReturn"}},"required":["return"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"Invalid state transition for the return's current status."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/returns/{id}/reject":{"post":{"tags":["merchant-commerce"],"summary":"Reject a return","description":"Requires the `manage:own_returns` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectReturnBody"}}}},"responses":{"200":{"description":"The return after the transition.","content":{"application/json":{"schema":{"type":"object","properties":{"return":{"$ref":"#/components/schemas/OrderReturn"}},"required":["return"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"Invalid state transition for the return's current status."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/returns/{id}/receive":{"post":{"tags":["merchant-commerce"],"summary":"Receive a return — restock and settle the refund","description":"Requires the `manage:own_returns` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceiveReturnBody"}}}},"responses":{"200":{"description":"The return was received, restocked, and refunded. Requires an `Idempotency-Key` header.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceivedReturn"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/my/credentials":{"get":{"tags":["merchant-credentials"],"summary":"List the tenant's API keys (metadata only — never key material)","description":"Requires the `manage:own_credentials` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"Every credential row for the calling key's tenant, revoked rows included. No key value or hash is ever returned.","content":{"application/json":{"schema":{"type":"object","properties":{"credentials":{"type":"array","items":{"$ref":"#/components/schemas/MerchantCredential"}}},"required":["credentials"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-credentials"],"summary":"Issue a new API key (scopes must be a subset of the calling key's)","description":"Requires the `manage:own_credentials` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"label":{"type":"string","minLength":1,"example":"ci-reader"},"scopes":{"type":"array","items":{"type":"string","description":"One scope from the closed tenant-scope allowlist.","example":"read:own_orders"},"minItems":1}},"required":["label","scopes"]}}}},"responses":{"201":{"description":"The minted credential. The plaintext `key` appears here ONCE and is never retrievable again.","content":{"application/json":{"schema":{"type":"object","properties":{"credential":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"key":{"type":"string","example":"fdk_..."},"label":{"type":"string"},"scopes":{"type":"array","items":{"type":"string","description":"One scope from the closed tenant-scope allowlist.","example":"read:own_orders"}}},"required":["id","key","label","scopes"]}},"required":["credential"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"`scope_escalation`: a requested scope exceeds the ISSUING key's own grant (the message names it) — or the key lacks `manage:own_credentials`."},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/my/credentials/{id}/revoke":{"post":{"tags":["merchant-credentials"],"summary":"Revoke an API key (recorded, not deleted; self-revoke allowed as a last action)","description":"Requires the `manage:own_credentials` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The revoked credential. `selfRevoked: true` means the key that made THIS call is now dead (its next request will 401); `alreadyRevoked: true` means the end state held from a prior revocation and nothing changed now.","content":{"application/json":{"schema":{"type":"object","properties":{"credential":{"$ref":"#/components/schemas/MerchantCredential"},"alreadyRevoked":{"type":"boolean"},"selfRevoked":{"type":"boolean"},"warning":{"type":"string"}},"required":["credential","alreadyRevoked","selfRevoked"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such credential for this tenant (also returned cross-tenant)."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/campaigns":{"get":{"tags":["merchant-ops"],"summary":"List the tenant's marketing campaigns","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"example":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of campaigns.","content":{"application/json":{"schema":{"type":"object","properties":{"campaigns":{"type":"array","items":{"$ref":"#/components/schemas/MarketingCampaign"}},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["campaigns","limit","offset"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-ops"],"summary":"Create a marketing campaign","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateCampaignBody"}}}},"responses":{"201":{"description":"The created campaign.","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["drip","broadcast","abandoned_cart"]},"status":{"type":"string"},"steps":{"type":"integer"}},"required":["id","kind","status","steps"]}},"required":["campaign"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"A step names an internal platform template that store campaigns cannot send."},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/campaigns/{id}/pause":{"post":{"tags":["merchant-ops"],"summary":"Pause a campaign (the drip runner stops sending its steps)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The campaign after the transition.","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/MarketingCampaign"},"enrollments_cancelled":{"type":"integer"}},"required":["campaign","enrollments_cancelled"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such campaign for this tenant."},"409":{"description":"The campaign's current status does not allow this transition."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/campaigns/{id}/resume":{"post":{"tags":["merchant-ops"],"summary":"Resume a paused campaign (enrollments continue where they left off)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The campaign after the transition.","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/MarketingCampaign"},"enrollments_cancelled":{"type":"integer"}},"required":["campaign","enrollments_cancelled"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such campaign for this tenant."},"409":{"description":"The campaign's current status does not allow this transition."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/campaigns/{id}/cancel":{"post":{"tags":["merchant-ops"],"summary":"Cancel a campaign (archives it and ends its active enrollments)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The campaign after the transition.","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/MarketingCampaign"},"enrollments_cancelled":{"type":"integer"}},"required":["campaign","enrollments_cancelled"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such campaign for this tenant."},"409":{"description":"The campaign's current status does not allow this transition."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/campaigns/{id}":{"get":{"tags":["merchant-ops"],"summary":"Get a campaign and its steps","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The campaign and its ordered steps.","content":{"application/json":{"schema":{"type":"object","properties":{"campaign":{"$ref":"#/components/schemas/MarketingCampaign"},"steps":{"type":"array","items":{"$ref":"#/components/schemas/MarketingCampaignStep"}}},"required":["campaign","steps"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such campaign for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/campaigns/{id}/enroll":{"post":{"tags":["merchant-ops"],"summary":"Resolve a campaign's audience and enroll every match at step 0","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"How many subjects matched and how many were newly enrolled.","content":{"application/json":{"schema":{"type":"object","properties":{"matched":{"type":"integer"},"enrolled":{"type":"integer"}},"required":["matched","enrolled"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such campaign for this tenant."},"409":{"description":"abandoned_cart campaigns enroll via the cart-idle sweep, not here."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/campaigns/{id}/enrollments":{"get":{"tags":["merchant-ops"],"summary":"List a campaign's enrollments","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":100,"example":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of enrollments.","content":{"application/json":{"schema":{"type":"object","properties":{"enrollments":{"type":"array","items":{"$ref":"#/components/schemas/MarketingEnrollment"}},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["enrollments","limit","offset"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such campaign for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/segments":{"get":{"tags":["merchant-ops"],"summary":"List the tenant's saved audience segments","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"example":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of segments.","content":{"application/json":{"schema":{"type":"object","properties":{"segments":{"type":"array","items":{"$ref":"#/components/schemas/MarketingSegment"}},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["segments","limit","offset"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-ops"],"summary":"Create a saved audience segment","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1},"query":{"type":"object","additionalProperties":{},"description":"{ predicate: <tree> } — leaves are {field, op, value} over the allow-listed audience fields (email, name, created_at, order_count, lifetime_cents, last_order_at, subscription_status, marketing_opted_in, enrolled_in_campaign); branches are {op: 'and'|'or', children: [...]}. Validated on write; an unknown field or empty branch is a 400."}},"required":["name","query"]}}}},"responses":{"201":{"description":"The created segment.","content":{"application/json":{"schema":{"type":"object","properties":{"segment":{"$ref":"#/components/schemas/MarketingSegment"}},"required":["segment"]}}}},"400":{"description":"The query is not a valid allow-listed predicate."},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"A segment with this name already exists."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/segments/{id}":{"get":{"tags":["merchant-ops"],"summary":"Get a segment","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The segment.","content":{"application/json":{"schema":{"type":"object","properties":{"segment":{"$ref":"#/components/schemas/MarketingSegment"}},"required":["segment"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such segment for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"put":{"tags":["merchant-ops"],"summary":"Rename a segment and/or replace its criteria","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1},"query":{"type":"object","additionalProperties":{},"description":"{ predicate: <tree> } — leaves are {field, op, value} over the allow-listed audience fields (email, name, created_at, order_count, lifetime_cents, last_order_at, subscription_status, marketing_opted_in, enrolled_in_campaign); branches are {op: 'and'|'or', children: [...]}. Validated on write; an unknown field or empty branch is a 400."}}}}}},"responses":{"200":{"description":"The segment after the update.","content":{"application/json":{"schema":{"type":"object","properties":{"segment":{"$ref":"#/components/schemas/MarketingSegment"}},"required":["segment"]}}}},"400":{"description":"Neither name nor query supplied, or the query is invalid."},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such segment for this tenant."},"409":{"description":"A segment with this name already exists."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"delete":{"tags":["merchant-ops"],"summary":"Delete a segment (the create's inverse)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]}},"required":["deleted"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such segment for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/segments/{id}/count":{"get":{"tags":["merchant-ops"],"summary":"Count a segment's members RIGHT NOW (resolution-time, never cached)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The live count, labeled with the instant it was computed.","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"},"as_of":{"type":"string","format":"date-time"}},"required":["count","as_of"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such segment for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/campaigns/{id}/triggers":{"get":{"tags":["merchant-ops"],"summary":"List a campaign's event triggers","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The triggers.","content":{"application/json":{"schema":{"type":"object","properties":{"triggers":{"type":"array","items":{"$ref":"#/components/schemas/MarketingCampaignTrigger"}}},"required":["triggers"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such campaign for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-ops"],"summary":"Attach an event trigger (closed vocabulary) to a campaign","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"event_name":{"type":"string","enum":["commerce.order.placed.v1","person.created.v1","subscription.cancelled.v1"]},"filter_query":{"type":["object","null"],"additionalProperties":{},"description":"{ predicate: <allow-listed tree> } the person must match, or null."},"once_per_person":{"type":"boolean","description":"Defaults true. When false, a FINISHED enrollment may re-enroll once past the campaign's frequency_cap_days."}},"required":["event_name"]}}}},"responses":{"201":{"description":"The trigger.","content":{"application/json":{"schema":{"type":"object","properties":{"trigger":{"$ref":"#/components/schemas/MarketingCampaignTrigger"}},"required":["trigger"]}}}},"400":{"description":"Unknown trigger event (closed vocabulary) or invalid filter."},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such campaign for this tenant."},"409":{"description":"The campaign already has a trigger for this event, or is abandoned_cart."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/campaigns/{id}/triggers/{triggerId}":{"delete":{"tags":["merchant-ops"],"summary":"Remove a trigger (the create's inverse)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string"},"required":true,"name":"triggerId","in":"path"}],"responses":{"200":{"description":"Deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]}},"required":["deleted"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such campaign or trigger for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/campaigns/{id}/engagement-daily":{"get":{"tags":["merchant-ops"],"summary":"A campaign's daily engagement series (PII-free rollup)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":1,"maximum":365,"description":"Window in days (default 30)."},"required":false,"name":"days","in":"query"}],"responses":{"200":{"description":"One row per (day, event type) with events recorded. Sparse — days with nothing have no rows.","content":{"application/json":{"schema":{"type":"object","properties":{"days":{"type":"integer"},"series":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string"},"event_type":{"type":"string"},"event_count":{"type":"integer"}},"required":["day","event_type","event_count"]}}},"required":["days","series"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such campaign for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/send-caps":{"get":{"tags":["merchant-ops"],"summary":"The tenant's journey guardrails (read-only; writes are operator-gated)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"The effective caps. A tenant without an override reports the platform defaults with source = platform_default — never 'uncapped'.","content":{"application/json":{"schema":{"type":"object","properties":{"send_caps":{"type":"object","properties":{"max_marketing_sends_per_day":{"type":"integer"},"quiet_hours_start":{"type":["integer","null"]},"quiet_hours_end":{"type":["integer","null"]},"timezone":{"type":"string"},"attribution_click_window_hours":{"type":"integer"},"attribution_open_window_hours":{"type":"integer"},"source":{"type":"string","enum":["tenant","platform_default"]}},"required":["max_marketing_sends_per_day","quiet_hours_start","quiet_hours_end","timezone","attribution_click_window_hours","attribution_open_window_hours","source"]}},"required":["send_caps"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/templates":{"get":{"tags":["merchant-ops"],"summary":"List the tenant's marketing templates","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"example":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of templates.","content":{"application/json":{"schema":{"type":"object","properties":{"templates":{"type":"array","items":{"$ref":"#/components/schemas/MarketingTenantTemplate"}},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["templates","limit","offset"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-ops"],"summary":"Create a marketing template (versions are appended separately)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"key":{"type":"string","minLength":1},"description":{"type":"string"}},"required":["key"]}}}},"responses":{"201":{"description":"The template.","content":{"application/json":{"schema":{"type":"object","properties":{"template":{"$ref":"#/components/schemas/MarketingTenantTemplate"}},"required":["template"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"409":{"description":"A template with this key already exists."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/templates/{id}":{"get":{"tags":["merchant-ops"],"summary":"Get a template with its full version history","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The template and its versions (newest first).","content":{"application/json":{"schema":{"type":"object","properties":{"template":{"$ref":"#/components/schemas/MarketingTenantTemplate"},"versions":{"type":"array","items":{"$ref":"#/components/schemas/MarketingTenantTemplateVersion"}}},"required":["template","versions"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such template for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/templates/{id}/versions":{"post":{"tags":["merchant-ops"],"summary":"Append a draft version (append-only; publish moves the pointer)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"subject":{"type":"string","minLength":1},"body":{"type":"string","minLength":1}},"required":["subject","body"]}}}},"responses":{"201":{"description":"The version.","content":{"application/json":{"schema":{"type":"object","properties":{"version":{"$ref":"#/components/schemas/MarketingTenantTemplateVersion"}},"required":["version"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such template for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/marketing/templates/{id}/publish":{"post":{"tags":["merchant-ops"],"summary":"Publish a version (or roll back by publishing an older one)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"version_id":{"type":"string"}},"required":["version_id"]}}}},"responses":{"200":{"description":"The template with its pointer moved.","content":{"application/json":{"schema":{"type":"object","properties":{"template":{"$ref":"#/components/schemas/MarketingTenantTemplate"}},"required":["template"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such template/version for this tenant."},"422":{"description":"Blocked by the RUO-claims compliance scan: CRITICAL findings are returned and the publish pointer does not move."},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"503":{"description":"The compliance scan did not run — publish refused, never waved through."}}}},"/v1/merchant/marketing/templates/{id}/preview":{"post":{"tags":["merchant-ops"],"summary":"Render a version with sample data (no send; missing variables reported)","description":"Requires the `manage:own_marketing` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"version_id":{"type":"string","description":"Defaults to the published version."},"data":{"type":"object","additionalProperties":{}}}}}}},"responses":{"200":{"description":"The rendered content.","content":{"application/json":{"schema":{"type":"object","properties":{"subject":{"type":"string"},"body":{"type":"string"},"missing_variables":{"type":"array","items":{"type":"string"}},"version_number":{"type":"integer"}},"required":["subject","body","missing_variables","version_number"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such template/version for this tenant."},"409":{"description":"The template has no versions yet."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/media/assets":{"get":{"tags":["merchant-ops"],"summary":"List the tenant's media assets","description":"Requires the `manage:own_media` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"integer","minimum":1,"maximum":100,"example":20},"required":false,"name":"limit","in":"query"},{"schema":{"type":["integer","null"],"minimum":0,"example":0},"required":false,"name":"offset","in":"query"}],"responses":{"200":{"description":"A page of assets.","content":{"application/json":{"schema":{"type":"object","properties":{"assets":{"type":"array","items":{"$ref":"#/components/schemas/MediaAsset"}},"limit":{"type":"integer"},"offset":{"type":"integer"}},"required":["assets","limit","offset"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/media/assets/{id}":{"get":{"tags":["merchant-ops"],"summary":"Get a media asset","description":"Requires the `manage:own_media` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The asset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaAsset"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such asset for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/media/uploads":{"post":{"tags":["merchant-ops"],"summary":"Presign a content-addressed upload and create a pending asset","description":"Requires the `manage:own_media` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PresignUploadBody"}}}},"responses":{"201":{"description":"The pending asset plus the presigned upload target.","content":{"application/json":{"schema":{"type":"object","properties":{"asset_id":{"type":"string"},"asset_ref":{"type":"string"},"storage_key":{"type":"string"},"cdn_url":{"type":"string"},"status":{"type":"string","enum":["pending","ready"]},"replayed":{"type":"boolean"},"upload":{"type":"object","properties":{"url":{"type":"string"},"method":{"type":"string"},"fields":{"type":"object","additionalProperties":{"type":"string"}}},"required":["url","method","fields"]}},"required":["asset_id","asset_ref","storage_key","cdn_url","status","replayed","upload"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/media/assets/{id}/finalize":{"post":{"tags":["merchant-ops"],"summary":"Confirm the uploaded object and mark the asset ready","description":"Requires the `manage:own_media` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FinalizeAssetBody"}}}},"responses":{"200":{"description":"The finalized asset.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaAsset"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such asset for this tenant."},"409":{"description":"No object at the presigned key yet — upload before finalizing."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/inventory/vendors":{"get":{"tags":["merchant-ops"],"summary":"List the tenant's vendors","description":"Requires the `manage:own_inventory` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"The tenant's vendors.","content":{"application/json":{"schema":{"type":"object","properties":{"vendors":{"type":"array","items":{"$ref":"#/components/schemas/Vendor"}}},"required":["vendors"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-ops"],"summary":"Create a vendor","description":"Requires the `manage:own_inventory` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVendorBody"}}}},"responses":{"201":{"description":"The created vendor.","content":{"application/json":{"schema":{"type":"object","properties":{"vendor":{"$ref":"#/components/schemas/Vendor"}},"required":["vendor"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/inventory/purchase-orders":{"get":{"tags":["merchant-ops"],"summary":"List the tenant's purchase orders","description":"Requires the `manage:own_inventory` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"The tenant's purchase orders.","content":{"application/json":{"schema":{"type":"object","properties":{"purchase_orders":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseOrder"}}},"required":["purchase_orders"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-ops"],"summary":"Create a purchase order with its lines","description":"Requires the `manage:own_inventory` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePurchaseOrderBody"}}}},"responses":{"201":{"description":"The created purchase order and its lines.","content":{"application/json":{"schema":{"type":"object","properties":{"purchase_order":{"$ref":"#/components/schemas/PurchaseOrder"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseOrderLine"}}},"required":["purchase_order","lines"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/inventory/purchase-orders/{id}":{"get":{"tags":["merchant-ops"],"summary":"Get a purchase order and its lines","description":"Requires the `manage:own_inventory` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The purchase order and its lines.","content":{"application/json":{"schema":{"type":"object","properties":{"purchase_order":{"$ref":"#/components/schemas/PurchaseOrder"},"lines":{"type":"array","items":{"$ref":"#/components/schemas/PurchaseOrderLine"}}},"required":["purchase_order","lines"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No such purchase order for this tenant."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/inventory/purchase-orders/{id}/receive":{"post":{"tags":["merchant-ops"],"summary":"Receive stock against a purchase-order line into a lot","description":"Requires the `manage:own_inventory` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReceivePurchaseOrderBody"}}}},"responses":{"201":{"description":"The created lot, the updated line, and the purchase order.","content":{"application/json":{"schema":{"type":"object","properties":{"lot":{"$ref":"#/components/schemas/InventoryLot"},"line":{"$ref":"#/components/schemas/PurchaseOrderLine"},"purchase_order":{"$ref":"#/components/schemas/PurchaseOrder"}},"required":["lot","line","purchase_order"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/fulfillment/nodes":{"get":{"tags":["merchant-ops"],"summary":"List the tenant's fulfillment nodes","description":"Requires the `manage:own_fulfillment` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"The tenant's routing nodes.","content":{"application/json":{"schema":{"type":"object","properties":{"nodes":{"type":"array","items":{"$ref":"#/components/schemas/FulfillmentNode"}}},"required":["nodes"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-ops"],"summary":"Create a fulfillment node","description":"Requires the `manage:own_fulfillment` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateFulfillmentNodeBody"}}}},"responses":{"201":{"description":"The created node.","content":{"application/json":{"schema":{"type":"object","properties":{"node":{"$ref":"#/components/schemas/FulfillmentNode"}},"required":["node"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/fulfillment/{id}/dropship":{"post":{"tags":["merchant-ops"],"summary":"Route a queued fulfillment to a dropship vendor node","description":"Requires the `manage:own_fulfillment` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DropshipBody"}}}},"responses":{"201":{"description":"The advanced queue row and the recorded dropship dispatches.","content":{"application/json":{"schema":{"type":"object","properties":{"queue":{"$ref":"#/components/schemas/FulfillmentQueueRow"},"dispatches":{"type":"array","items":{"$ref":"#/components/schemas/DropshipDispatch"}}},"required":["queue","dispatches"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Queue row or node not found for this tenant."},"409":{"description":"Queue is not in a state that permits dropship routing."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/fraud/bans":{"get":{"tags":["merchant-ops"],"summary":"List the tenant's active fraud bans","description":"Requires the `manage:own_fraud` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"The active bans.","content":{"application/json":{"schema":{"type":"object","properties":{"bans":{"type":"array","items":{"$ref":"#/components/schemas/FraudBan"}}},"required":["bans"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}},"post":{"tags":["merchant-ops"],"summary":"Add a fraud ban (the raw value is fingerprinted, never stored)","description":"Requires the `manage:own_fraud` scope.","security":[{"fdkBearer":[]}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AddBanBody"}}}},"responses":{"200":{"description":"The ban already existed (idempotent replay).","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/FraudBan"},{"type":"object","properties":{"replayed":{"type":"boolean"}},"required":["replayed"]}]}}}},"201":{"description":"The newly created ban.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/FraudBan"},{"type":"object","properties":{"replayed":{"type":"boolean"}},"required":["replayed"]}]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/fraud/bans/{id}":{"delete":{"tags":["merchant-ops"],"summary":"Lift an active fraud ban","description":"Requires the `manage:own_fraud` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","example":"camp_01H..."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"The ban was lifted.","content":{"application/json":{"schema":{"type":"object","properties":{"ban_id":{"type":"string"},"lifted":{"type":"boolean","enum":[true]}},"required":["ban_id","lifted"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"No active ban with that id."},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/analytics/revenue":{"get":{"tags":["merchant-ops"],"summary":"Revenue / orders rollup over a date range","description":"Requires the `manage:own_analytics` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","format":"date-time","example":"2026-08-01T00:00:00.000Z"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time","example":"2026-08-31T00:00:00.000Z"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Revenue rollup in integer cents, with per-day buckets.","content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"order_count":{"type":"integer"},"gross_cents":{"type":"integer"},"refund_cents":{"type":"integer"},"net_cents":{"type":"integer"},"buckets":{"type":"array","items":{"$ref":"#/components/schemas/RevenueDayBucket"}}},"required":["from","to","order_count","gross_cents","refund_cents","net_cents","buckets"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/analytics/mrr":{"get":{"tags":["merchant-ops"],"summary":"Active-subscription MRR rollup by currency","description":"Requires the `manage:own_analytics` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"MRR rollup in integer cents, per currency.","content":{"application/json":{"schema":{"type":"object","properties":{"total_active":{"type":"integer"},"by_currency":{"type":"array","items":{"type":"object","properties":{"currency":{"type":"string"},"active_subscriptions":{"type":"integer"},"mrr_cents":{"type":"integer"}},"required":["currency","active_subscriptions","mrr_cents"]}}},"required":["total_active","by_currency"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/analytics/margin":{"get":{"tags":["merchant-ops"],"summary":"COGS margin over a date range","description":"Requires the `manage:own_analytics` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","format":"date-time","example":"2026-08-01T00:00:00.000Z"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time","example":"2026-08-31T00:00:00.000Z"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Margin rollup in integer cents; margin_bps is null when revenue is 0.","content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"revenue_cents":{"type":"integer"},"cogs_cents":{"type":"integer"},"gross_margin_cents":{"type":"integer"},"margin_bps":{"type":["integer","null"]}},"required":["from","to","revenue_cents","cogs_cents","gross_margin_cents","margin_bps"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/analytics/campaigns":{"get":{"tags":["merchant-ops"],"summary":"Campaign performance — enrollments, steps, and send counts","description":"Requires the `manage:own_analytics` scope.","security":[{"fdkBearer":[]}],"responses":{"200":{"description":"Per-campaign performance rows.","content":{"application/json":{"schema":{"type":"object","properties":{"campaigns":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"kind":{"type":"string"},"status":{"type":"string"},"enrollment_count":{"type":"integer"},"step_count":{"type":"integer"},"send_count":{"type":"integer"},"open_count":{"type":"integer"},"click_count":{"type":"integer"},"conversion_count":{"type":"integer","description":"Last-touch attributed orders (marketing-hub port P4)."},"attributed_revenue_cents":{"type":"integer","description":"Integer cents of last-touch attributed order revenue."}},"required":["id","name","kind","status","enrollment_count","step_count","send_count","open_count","click_count","conversion_count","attributed_revenue_cents"]}}},"required":["campaigns"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}},"/v1/merchant/analytics/search-trends":{"get":{"tags":["merchant-ops"],"summary":"Top search queries over a date range","description":"Requires the `manage:own_analytics` scope.","security":[{"fdkBearer":[]}],"parameters":[{"schema":{"type":"string","format":"date-time","example":"2026-08-01T00:00:00.000Z"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time","example":"2026-08-31T00:00:00.000Z"},"required":false,"name":"to","in":"query"},{"schema":{"type":"integer","minimum":1,"example":20},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"The most-searched queries, most-searched first.","content":{"application/json":{"schema":{"type":"object","properties":{"from":{"type":"string","format":"date-time"},"to":{"type":"string","format":"date-time"},"queries":{"type":"array","items":{"type":"object","properties":{"query":{"type":"string"},"search_count":{"type":"integer"},"distinct_days":{"type":"integer"},"avg_result_count":{"type":"number"},"zero_result_count":{"type":"integer"}},"required":["query","search_count","distinct_days","avg_result_count","zero_result_count"]}}},"required":["from","to","queries"]}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"422":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}},"500":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorBody"}}}}}}}},"webhooks":{}}