{
  "openapi": "3.1.0",
  "info": {
    "title": "Venon Public API",
    "version": "1.0.0",
    "description": "The Venon Public API provides programmatic access to your advertising analytics and profit-tracking cost data.\n\n## Authentication\n\nAll endpoints (except /v1/health) require API key authentication. You can authenticate using either:\n\n1. **Bearer Token** (recommended):\n   ```\n   Authorization: Bearer vnon_xxx...\n   ```\n\n2. **X-API-Key Header**:\n   ```\n   X-API-Key: vnon_xxx...\n   ```\n\nAPI keys are created and managed through the Venon Dashboard.\n\n## Rate Limiting\n\nLimits apply per credential: **60 requests per minute** per API key for REST (ads write endpoints: **10 per minute**), and 60 per minute per API key or OAuth token for MCP. Requests without credentials, and repeated failed authentication, are limited per IP address.\n\nResponses include `RateLimit-Policy`, `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the window resets). When rate limited, you'll receive a 429 response with a `Retry-After` header (seconds).\n\n## Scopes\n\nAPI keys have specific scopes that control access:\n\n- `analytics:read` - Read analytics, product performance, attribution, and insight endpoints\n- `orders:read` - Read orders and per-order cost breakdowns\n- `cost:read` - Read profit-tracking cost settings: COGS, shipping, and payment fees\n- `cost:write` - Create and update profit-tracking cost settings\n- `ads:write` - Activate/pause campaigns, ad sets, and ads, and update campaign / ad-set daily budgets (Meta + Google)\n- `filters:read` - Read saved data filters (applying them to a report needs only that report's scope)\n- `filters:write` - Create, update and delete saved data filters\n\n## Response Format\n\nAll responses follow a consistent structure:\n\n**Success:**\n```json\n{\n  \"success\": true,\n  \"data\": { ... },\n  \"metadata\": {\n    \"request_id\": \"req_xxx\",\n    \"timestamp\": \"2025-04-15T12:00:00.000Z\"\n  }\n}\n```\n\n**Error:**\n```json\n{\n  \"success\": false,\n  \"error\": {\n    \"code\": \"ERROR_CODE\",\n    \"message\": \"Human-readable message\",\n    \"details\": [{ \"field\": \"...\", \"message\": \"...\" }]\n  },\n  \"metadata\": { ... }\n}\n```\n\n## Choosing an Endpoint\n\nUse the shop summary for headline profit, timeseries for trends, and profit-loss for a statement. Use channel/campaign/ad performance for attributed marketing results, and attribution drill-downs for the matching orders or products. Use the product catalog to resolve identities before a product/variant cost write; product performance only answers sales questions for a date window.\n\nCost writes configure Venon's profit calculations. Ads writes change the connected ad platform immediately. A read-before-write workflow needs the relevant read scope as well as the write scope.\n\n## Dates, Pagination and IDs\n\nDate parameters use shop-local calendar dates; keep dates, attribution settings and filters consistent when comparing reports. Follow each endpoint's range and result limits. Cohort follow-up depth and report breakdown limits are separate from pagination.\n\nEndpoints exposing `page`/`per_page` use 1-based pages (default 50 items, maximum 100 per page). Read the returned pagination metadata and keep filters unchanged between pages. COGS rules instead use `limit`/`offset`; shipping profiles and payment-gateway lists do not use page pagination. Totals covering the full filtered set must not be added again for each page.\n\nUse IDs returned by the corresponding read operation, preserving the schema's string/number type. Display names, SKUs, product IDs, cost-history row IDs and ad-platform IDs are not interchangeable. Resolve ambiguous matches before writing.\n\n## Interpreting Results\n\n`metadata.timestamp` is the response creation time, not the last data-sync time. Use report-specific `data_updated_at` and availability fields where provided. Preserve null metrics when a value is unavailable or its denominator is zero. Ratios and cumulative totals are not additive.\n\nA successful bulk cost response can contain failed targets; inspect its `applied` and `failed` fields. A dry-run plan performs no write and does not reserve state. Keep `metadata.request_id` when reporting an error; on a REST 429, wait for `Retry-After` before retrying.\n\n## MCP Conventions\n\nUse each tool's input schema: REST body wrappers are not automatically MCP arguments. For example, analytics multi-ID filters are comma-separated strings in REST and arrays of strings in MCP. Successful MCP results expose `structuredContent.data` while retaining the existing text result; handler business errors use `isError: true` and `structuredContent.error`. Inspect the error rather than treating the MCP transport's HTTP success as a successful operation.\n\n## Attribution Models\n\n- `linear_paid` - Credit distributed evenly across paid touchpoints\n- `linear_all` - Credit distributed evenly across all touchpoints\n- `first_click` - All credit to first touchpoint\n- `last_click` - All credit to last touchpoint\n- `last_paid_click` - All credit to last paid touchpoint\n- `all_clicks` - Each touchpoint gets full credit, so channel totals can exceed revenue\n\n## Attribution Windows\n\n- `1_day`, `7_day`, `14_day`, `28_day`, `90_day`, `lifetime`\n\nWhen omitted, `attribution_model` defaults to `last_paid_click` and `attribution_window` to `lifetime` on every endpoint and MCP tool. The dashboard opens on all_clicks with a lifetime window and remembers each user's choice; pass the model and window shown there to reproduce its numbers.\n",
    "contact": {
      "name": "Venon Support",
      "url": "mailto:info@venon.io",
      "email": "info@venon.io"
    }
  },
  "servers": [
    { "url": "https://developer-next.venon.io", "description": "Staging" }
  ],
  "tags": [
    { "name": "System", "description": "System and health endpoints" },
    {
      "name": "Analytics",
      "description": "Advertising analytics, performance metrics, and shop insights (P&L, timeseries, cohorts, retention)"
    },
    {
      "name": "Orders",
      "description": "Orders — list with financials, and per-order cost breakdowns"
    },
    {
      "name": "Products",
      "description": "Product performance — units, revenue, COGS, and margin per product/variant"
    },
    {
      "name": "Attribution",
      "description": "Attribution drill-downs — orders and products a channel/campaign drove, non-ad campaign performance"
    },
    {
      "name": "Cost",
      "description": "Profit-tracking cost settings — COGS, payment fees, shipping profiles"
    },
    {
      "name": "Ads",
      "description": "Ads management — campaign / ad-set / ad status and budget writes (Meta + Google)"
    },
    {
      "name": "Data Filters",
      "description": "Saved data filters: the dashboard report filters, and how to apply them to report endpoints"
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key",
        "description": "API key authentication. Use your API key with the format: `Bearer vnon_xxx...`"
      },
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Alternative: Pass API key in X-API-Key header"
      }
    },
    "schemas": {
      "DataFilterWarning": {
        "type": "object",
        "properties": {
          "code": { "type": "string", "enum": ["data_filters_skipped"] },
          "message": {
            "type": "string",
            "description": "Readable summary, e.g. \"1 of 4 saved data filters is not applied: ...\""
          },
          "stored": {
            "type": "integer",
            "description": "Saved data filters stored for the shop"
          },
          "skipped": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Saved data filter id; update or delete it by this id"
                },
                "title": { "type": ["string", "null"] },
                "enabled": {
                  "type": ["boolean", "null"],
                  "description": "Saved toggle, null when unreadable"
                },
                "reasons": {
                  "type": "array",
                  "items": { "type": "string" },
                  "description": "Failing field paths and checks, e.g. \"groups: Use 10 conditions or fewer\""
                }
              },
              "required": ["id", "title", "enabled", "reasons"]
            },
            "description": "Filters left out of this response"
          }
        },
        "required": ["code", "message", "stored", "skipped"]
      },
      "ResponseMetadata": {
        "type": "object",
        "properties": {
          "request_id": {
            "type": "string",
            "description": "Unique request identifier for tracing"
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 timestamp of the response"
          },
          "shop_name": {
            "type": "string",
            "description": "Shopify shop this response belongs to (authenticated requests only)"
          },
          "currency": {
            "type": ["string", "null"],
            "description": "Shop currency code (ISO 4217). This is the DEFAULT for monetary values in `data`, not a guarantee for every amount: an object carrying its own currency field overrides it — ad-platform budgets use `budget_currency` (the ad account currency) and shipping-profile fees use the profile's own `currency`. Null when the shop has no currency configured yet."
          },
          "timezone": {
            "type": ["string", "null"],
            "description": "Shop IANA timezone that shop-local dates in `data` are expressed in. Null when the shop has no timezone configured yet."
          },
          "data_filters": {
            "type": "object",
            "properties": {
              "mode": {
                "type": "string",
                "enum": ["none", "enabled", "selected"],
                "description": "Effective filter_mode"
              },
              "ids": {
                "type": "array",
                "items": { "type": "string", "format": "uuid" },
                "description": "Saved data filters applied to `data`"
              }
            },
            "required": ["mode", "ids"],
            "description": "Saved data filters applied to this report (filter-capable report endpoints only). Pass the same filter_mode and filter_ids to reproduce the result."
          },
          "warnings": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/DataFilterWarning" },
            "description": "Present only when something was left out: saved data filters whose stored rules no longer pass the current rules or limits (GET /v1/data-filters, and report endpoints with filter_mode=enabled). The response still succeeds without them."
          }
        },
        "required": ["request_id", "timestamp"]
      },
      "ErrorDetail": {
        "type": "object",
        "properties": {
          "field": {
            "type": "string",
            "description": "Field that caused the error"
          },
          "message": {
            "type": "string",
            "description": "Error message for the field"
          }
        },
        "required": ["field", "message"]
      },
      "ApiError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "UNAUTHORIZED",
              "KEY_EXPIRED",
              "KEY_REVOKED",
              "FORBIDDEN",
              "VALIDATION_ERROR",
              "CONFLICT",
              "SHIPPING_PROFILE_SCOPE_CONFLICT",
              "SHIPPING_PROFILE_IDENTITY_CONFLICT",
              "SHIPPING_PROFILE_REVISION_CONFLICT",
              "NOT_FOUND",
              "RATE_LIMITED",
              "INTERNAL_ERROR"
            ],
            "description": "Stable error code; use this for recovery decisions"
          },
          "message": {
            "type": "string",
            "description": "Human-readable error message"
          },
          "details": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ErrorDetail" },
            "description": "Detailed field-level errors"
          },
          "conflicting_profiles": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "integer", "exclusiveMinimum": 0 },
                "name": { "type": "string" }
              },
              "required": ["id", "name"]
            },
            "description": "Same-shop profiles whose scopes overlap. Fetch each by id to inspect its full scope and costs."
          },
          "recovery": {
            "type": "string",
            "description": "How to resolve the error; this does not authorize overwriting existing data"
          }
        },
        "required": ["code", "message"]
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": { "type": "boolean", "enum": [false] },
          "error": { "$ref": "#/components/schemas/ApiError" },
          "metadata": { "$ref": "#/components/schemas/ResponseMetadata" }
        },
        "required": ["success", "error"]
      },
      "PaginationMetadata": {
        "type": "object",
        "properties": {
          "page": { "type": "number", "description": "Current page number" },
          "per_page": { "type": "number", "description": "Items per page" },
          "total_items": {
            "type": "number",
            "description": "Total number of items"
          },
          "total_pages": {
            "type": "number",
            "description": "Total number of pages"
          },
          "has_next": {
            "type": "boolean",
            "description": "Whether there is a next page"
          },
          "has_previous": {
            "type": "boolean",
            "description": "Whether there is a previous page"
          }
        },
        "required": [
          "page",
          "per_page",
          "total_items",
          "total_pages",
          "has_next",
          "has_previous"
        ]
      },
      "ApiKeyResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "API key ID"
          },
          "name": { "type": "string", "description": "API key name" },
          "key_prefix": {
            "type": "string",
            "description": "First characters of the key for identification"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "analytics:read",
                "orders:read",
                "cost:read",
                "cost:write",
                "ads:write",
                "filters:read",
                "filters:write"
              ]
            },
            "description": "Granted scopes"
          },
          "expires_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Expiration timestamp"
          },
          "last_used_at": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Last usage timestamp"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Creation timestamp"
          }
        },
        "required": [
          "id",
          "name",
          "key_prefix",
          "scopes",
          "expires_at",
          "last_used_at",
          "created_at"
        ]
      },
      "CreatedApiKeyResponse": {
        "allOf": [
          { "$ref": "#/components/schemas/ApiKeyResponse" },
          {
            "type": "object",
            "properties": {
              "key": {
                "type": "string",
                "description": "Full API key (shown only once at creation)"
              }
            },
            "required": ["key"]
          }
        ]
      },
      "DataFilterInput": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "shopify",
              "meta-ads",
              "google-ads",
              "taboola",
              "tiktok-ads",
              "outbrain",
              "microsoft-ads",
              "pinterest-ads"
            ]
          },
          "title": { "type": "string", "minLength": 1, "maxLength": 60 },
          "description": { "type": ["string", "null"], "maxLength": 200 },
          "enabled": { "type": "boolean" },
          "groups": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "field": {
                    "type": "string",
                    "enum": [
                      "campaign_name",
                      "ad_set_name",
                      "ad_name",
                      "order_name",
                      "campaign_id",
                      "ad_set_id",
                      "ad_id",
                      "shipping_country",
                      "payment_gateway"
                    ]
                  },
                  "operator": {
                    "type": "string",
                    "enum": [
                      "is_any_of",
                      "is_none_of",
                      "contains",
                      "does_not_contain",
                      "starts_with"
                    ]
                  },
                  "values": {
                    "type": "array",
                    "items": { "type": "string", "maxLength": 256 },
                    "maxItems": 100
                  }
                },
                "required": ["field", "operator", "values"],
                "additionalProperties": false
              },
              "minItems": 1,
              "maxItems": 10
            },
            "minItems": 1,
            "maxItems": 10
          }
        },
        "required": ["source", "title", "description", "enabled", "groups"],
        "additionalProperties": false,
        "example": {
          "source": "shopify",
          "title": "Only DACH orders",
          "description": null,
          "enabled": true,
          "groups": [
            [
              {
                "field": "shipping_country",
                "operator": "is_any_of",
                "values": ["DE", "AT", "CH"]
              }
            ]
          ]
        }
      },
      "DataFilter": {
        "type": "object",
        "properties": {
          "source": {
            "type": "string",
            "enum": [
              "shopify",
              "meta-ads",
              "google-ads",
              "taboola",
              "tiktok-ads",
              "outbrain",
              "microsoft-ads",
              "pinterest-ads"
            ]
          },
          "title": { "type": "string", "minLength": 1, "maxLength": 60 },
          "description": { "type": ["string", "null"], "maxLength": 200 },
          "enabled": { "type": "boolean" },
          "groups": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "field": {
                    "type": "string",
                    "enum": [
                      "campaign_name",
                      "ad_set_name",
                      "ad_name",
                      "order_name",
                      "campaign_id",
                      "ad_set_id",
                      "ad_id",
                      "shipping_country",
                      "payment_gateway"
                    ]
                  },
                  "operator": {
                    "type": "string",
                    "enum": [
                      "is_any_of",
                      "is_none_of",
                      "contains",
                      "does_not_contain",
                      "starts_with"
                    ]
                  },
                  "values": {
                    "type": "array",
                    "items": { "type": "string", "maxLength": 256 },
                    "maxItems": 100
                  }
                },
                "required": ["field", "operator", "values"],
                "additionalProperties": false
              },
              "minItems": 1,
              "maxItems": 10
            },
            "minItems": 1,
            "maxItems": 10
          },
          "id": { "type": "string", "format": "uuid" }
        },
        "required": [
          "source",
          "title",
          "description",
          "enabled",
          "groups",
          "id"
        ],
        "additionalProperties": false
      },
      "DataFilterList": {
        "type": "object",
        "properties": {
          "data_filters": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/DataFilter" }
          }
        },
        "required": ["data_filters"]
      },
      "AdMetrics": {
        "type": "object",
        "properties": {
          "ad_spend": { "type": "number" },
          "attributed_orders": { "type": "number" },
          "attributed_revenue": { "type": "number" },
          "roas": { "type": "number" },
          "net_profit": { "type": "number" },
          "first_time_customer_orders": { "type": "number" },
          "first_time_customer_costs": {
            "type": "number",
            "description": "Attributed product, shipping and payment costs of first orders, excluding ad spend. Loaded CAC = (ad_spend + first_time_customer_costs) / first_time_customer_orders."
          },
          "first_time_customer_revenue": { "type": "number" },
          "first_time_customer_roas": { "type": "number" },
          "impressions": { "type": "number" },
          "clicks": { "type": "number" },
          "platform_conversions": {
            "type": "number",
            "description": "Conversions reported by the ad platform itself (Meta: purchase actions; Google: the configured conversion actions), using the platform’s own attribution. Only present for meta-ads and google-ads; absent for other channels. Compare with attributed_orders (Venon-attributed)."
          },
          "platform_conversion_value": {
            "type": "number",
            "description": "Conversion value reported by the ad platform itself, converted to the shop currency, using the platform’s own attribution. Only present for meta-ads and google-ads; absent for other channels. Compare with attributed_revenue (Venon-attributed)."
          },
          "creative_metrics": {
            "type": "object",
            "properties": {
              "raw": {
                "type": "object",
                "properties": {
                  "delivery": {
                    "type": "object",
                    "properties": {
                      "impressions": { "type": ["number", "null"] },
                      "reach": {
                        "type": ["number", "null"],
                        "description": "Unique reach: ad level and single-day ranges only."
                      },
                      "daily_reach_sum": {
                        "type": ["number", "null"],
                        "description": "Sum of daily ad reach (ad level only); not unique reach over the range."
                      }
                    },
                    "required": ["impressions", "reach", "daily_reach_sum"]
                  },
                  "clicks": {
                    "type": "object",
                    "properties": {
                      "inline_link_clicks": { "type": ["number", "null"] },
                      "outbound_clicks": { "type": ["number", "null"] }
                    },
                    "required": ["inline_link_clicks", "outbound_clicks"]
                  },
                  "video": {
                    "type": "object",
                    "properties": {
                      "video_3s_views": { "type": ["number", "null"] },
                      "video_plays": { "type": ["number", "null"] },
                      "video_thruplays": { "type": ["number", "null"] },
                      "video_p25": { "type": ["number", "null"] },
                      "video_p50": { "type": ["number", "null"] },
                      "video_p75": { "type": ["number", "null"] },
                      "video_p95": { "type": ["number", "null"] },
                      "video_p100": { "type": ["number", "null"] },
                      "video_avg_time_watched": {
                        "type": ["number", "null"],
                        "description": "Average seconds watched, weighted by video plays across days."
                      }
                    },
                    "required": [
                      "video_3s_views",
                      "video_plays",
                      "video_thruplays",
                      "video_p25",
                      "video_p50",
                      "video_p75",
                      "video_p95",
                      "video_p100",
                      "video_avg_time_watched"
                    ]
                  },
                  "funnel": {
                    "type": "object",
                    "properties": {
                      "landing_page_view": { "type": ["number", "null"] },
                      "view_content": { "type": ["number", "null"] },
                      "add_to_cart": { "type": ["number", "null"] },
                      "initiated_checkout": { "type": ["number", "null"] },
                      "lead": { "type": ["number", "null"] }
                    },
                    "required": [
                      "landing_page_view",
                      "view_content",
                      "add_to_cart",
                      "initiated_checkout",
                      "lead"
                    ]
                  },
                  "engagement": {
                    "type": "object",
                    "properties": {
                      "post_shares": { "type": ["number", "null"] },
                      "post_comments": { "type": ["number", "null"] },
                      "post_saves": { "type": ["number", "null"] }
                    },
                    "required": ["post_shares", "post_comments", "post_saves"]
                  }
                },
                "required": [
                  "delivery",
                  "clicks",
                  "video",
                  "funnel",
                  "engagement"
                ]
              },
              "calculated": {
                "type": "object",
                "properties": {
                  "cpm": { "type": ["number", "null"] },
                  "link_ctr": { "type": ["number", "null"] },
                  "link_cpc": { "type": ["number", "null"] },
                  "outbound_ctr": { "type": ["number", "null"] },
                  "hook_rate": {
                    "type": ["number", "null"],
                    "description": "3-second video views / impressions."
                  },
                  "first_frame_retention": {
                    "type": ["number", "null"],
                    "description": "Video plays / impressions on the ad-account day; null unless timezone_aligned."
                  },
                  "thumbstop_ctr": {
                    "type": ["number", "null"],
                    "description": "Link clicks / 3-second video views."
                  },
                  "hold_rate": {
                    "type": ["number", "null"],
                    "description": "ThruPlays / impressions on the ad-account day; null unless timezone_aligned."
                  },
                  "hold_to_hook_rate": {
                    "type": ["number", "null"],
                    "description": "ThruPlays / 3-second video views; null unless timezone_aligned."
                  },
                  "average_daily_frequency": {
                    "type": ["number", "null"],
                    "description": "Impressions / daily reach (ad level only); null unless timezone_aligned."
                  },
                  "video_p25_rate": { "type": ["number", "null"] },
                  "video_p50_rate": { "type": ["number", "null"] },
                  "video_p75_rate": { "type": ["number", "null"] },
                  "video_p95_rate": { "type": ["number", "null"] },
                  "video_p100_rate": { "type": ["number", "null"] },
                  "landing_page_view_rate": { "type": ["number", "null"] },
                  "view_content_rate": { "type": ["number", "null"] },
                  "add_to_cart_rate": { "type": ["number", "null"] },
                  "initiated_checkout_rate": { "type": ["number", "null"] },
                  "lead_rate": { "type": ["number", "null"] },
                  "cost_per_landing_page_view": { "type": ["number", "null"] },
                  "cost_per_view_content": { "type": ["number", "null"] },
                  "cost_per_add_to_cart": { "type": ["number", "null"] },
                  "cost_per_initiated_checkout": { "type": ["number", "null"] },
                  "cost_per_lead": { "type": ["number", "null"] }
                },
                "required": [
                  "cpm",
                  "link_ctr",
                  "link_cpc",
                  "outbound_ctr",
                  "hook_rate",
                  "first_frame_retention",
                  "thumbstop_ctr",
                  "hold_rate",
                  "hold_to_hook_rate",
                  "average_daily_frequency",
                  "video_p25_rate",
                  "video_p50_rate",
                  "video_p75_rate",
                  "video_p95_rate",
                  "video_p100_rate",
                  "landing_page_view_rate",
                  "view_content_rate",
                  "add_to_cart_rate",
                  "initiated_checkout_rate",
                  "lead_rate",
                  "cost_per_landing_page_view",
                  "cost_per_view_content",
                  "cost_per_add_to_cart",
                  "cost_per_initiated_checkout",
                  "cost_per_lead"
                ]
              },
              "availability": {
                "type": "object",
                "properties": {
                  "level": {
                    "type": "string",
                    "enum": ["campaign", "ad_set", "ad", "group"],
                    "description": "group: several ads combined by creative, landing page or copy."
                  },
                  "reach": {
                    "type": "string",
                    "enum": ["exact", "daily_sum", "unavailable"]
                  },
                  "timezone_aligned": {
                    "type": "boolean",
                    "description": "Every daily row in the range has the Meta ad-account timezone."
                  }
                },
                "required": ["level", "reach", "timezone_aligned"]
              }
            },
            "required": ["raw", "calculated", "availability"],
            "description": "Meta creative metrics; meta-ads only, with include=creative_metrics."
          }
        },
        "required": [
          "ad_spend",
          "attributed_orders",
          "attributed_revenue",
          "roas",
          "net_profit",
          "first_time_customer_orders",
          "first_time_customer_costs",
          "first_time_customer_revenue",
          "first_time_customer_roas",
          "impressions",
          "clicks"
        ]
      },
      "ChannelMetrics": {
        "type": "object",
        "properties": {
          "ad_spend": { "type": "number" },
          "attributed_orders": { "type": "number" },
          "attributed_revenue": { "type": "number" },
          "roas": { "type": "number" },
          "net_profit": { "type": "number" },
          "first_time_customer_orders": { "type": "number" },
          "first_time_customer_costs": {
            "type": "number",
            "description": "Attributed product, shipping and payment costs of first orders, excluding ad spend. Loaded CAC = (ad_spend + first_time_customer_costs) / first_time_customer_orders."
          },
          "first_time_customer_revenue": { "type": "number" },
          "first_time_customer_roas": { "type": "number" }
        },
        "required": [
          "ad_spend",
          "attributed_orders",
          "attributed_revenue",
          "roas",
          "net_profit",
          "first_time_customer_orders",
          "first_time_customer_costs",
          "first_time_customer_revenue",
          "first_time_customer_roas"
        ]
      },
      "PerformanceTotals": {
        "type": "object",
        "properties": {
          "impressions": { "type": "number" },
          "clicks": { "type": "number" },
          "ad_spend": { "type": "number" },
          "attributed_orders": { "type": "number" },
          "first_time_customer_orders": { "type": "number" },
          "first_time_customer_costs": {
            "type": "number",
            "description": "Attributed product, shipping and payment costs of first orders, excluding ad spend. Loaded CAC = (ad_spend + first_time_customer_costs) / first_time_customer_orders."
          },
          "attributed_revenue": { "type": "number" },
          "roas": { "type": "number" }
        },
        "required": [
          "impressions",
          "clicks",
          "ad_spend",
          "attributed_orders",
          "first_time_customer_orders",
          "first_time_customer_costs",
          "attributed_revenue",
          "roas"
        ]
      },
      "ChannelTotals": {
        "type": "object",
        "properties": {
          "ad_spend": { "type": "number" },
          "attributed_orders": { "type": "number" },
          "first_time_customer_orders": { "type": "number" },
          "first_time_customer_costs": {
            "type": "number",
            "description": "Attributed product, shipping and payment costs of first orders, excluding ad spend. Loaded CAC = (ad_spend + first_time_customer_costs) / first_time_customer_orders."
          },
          "attributed_revenue": { "type": "number" },
          "roas": { "type": "number" }
        },
        "required": [
          "ad_spend",
          "attributed_orders",
          "first_time_customer_orders",
          "first_time_customer_costs",
          "attributed_revenue",
          "roas"
        ]
      },
      "AdSetPerformanceData": {
        "type": "object",
        "properties": {
          "ad_set_id": {
            "type": "string",
            "description": "Platform ad set ID"
          },
          "ad_set_name": {
            "type": ["string", "null"],
            "description": "Ad set name"
          },
          "channel": { "type": "string", "description": "Channel identifier" },
          "campaign_id": {
            "type": "string",
            "description": "Parent campaign platform ID (list mode)"
          },
          "active": {
            "type": "boolean",
            "description": "Platform lifecycle flag (list mode)"
          },
          "budget": {
            "type": ["number", "null"],
            "description": "Ad set budget (list mode). Quoted in the AD ACCOUNT currency, which can differ from the shop currency that every other monetary field here uses."
          },
          "metrics": { "$ref": "#/components/schemas/AdMetrics" }
        },
        "required": ["ad_set_id", "ad_set_name", "channel", "metrics"]
      },
      "AdSetPerformanceResponseData": {
        "type": "object",
        "properties": {
          "ad_sets": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AdSetPerformanceData" },
            "description": "Performance data for each ad set"
          },
          "totals": {
            "allOf": [
              { "$ref": "#/components/schemas/PerformanceTotals" },
              { "description": "Aggregated totals across the filtered set" }
            ]
          },
          "pagination": {
            "allOf": [
              { "$ref": "#/components/schemas/PaginationMetadata" },
              {
                "description": "Pagination metadata — present in list mode only"
              }
            ]
          }
        },
        "required": ["ad_sets", "totals"]
      },
      "AdPerformanceData": {
        "type": "object",
        "properties": {
          "ad_id": { "type": "string", "description": "Platform ad ID" },
          "ad_name": { "type": ["string", "null"], "description": "Ad name" },
          "channel": { "type": "string", "description": "Channel identifier" },
          "campaign_id": {
            "type": "string",
            "description": "Parent campaign platform ID (list mode)"
          },
          "ad_set_id": {
            "type": "string",
            "description": "Parent ad-set platform ID (list mode)"
          },
          "active": {
            "type": "boolean",
            "description": "Platform lifecycle flag (list mode)"
          },
          "metrics": { "$ref": "#/components/schemas/AdMetrics" }
        },
        "required": ["ad_id", "ad_name", "channel", "metrics"]
      },
      "AdPerformanceResponseData": {
        "type": "object",
        "properties": {
          "ads": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AdPerformanceData" },
            "description": "Performance data for each ad"
          },
          "totals": {
            "allOf": [
              { "$ref": "#/components/schemas/PerformanceTotals" },
              { "description": "Aggregated totals across the filtered set" }
            ]
          },
          "pagination": {
            "allOf": [
              { "$ref": "#/components/schemas/PaginationMetadata" },
              {
                "description": "Pagination metadata — present in list mode only"
              }
            ]
          }
        },
        "required": ["ads", "totals"]
      },
      "CampaignPerformanceData": {
        "type": "object",
        "properties": {
          "campaign_id": {
            "type": "string",
            "description": "Platform ad campaign ID"
          },
          "campaign_name": {
            "type": ["string", "null"],
            "description": "Campaign name"
          },
          "channel": { "type": "string", "description": "Channel identifier" },
          "active": {
            "type": "boolean",
            "description": "Platform lifecycle flag (list mode)"
          },
          "budget": {
            "type": ["number", "null"],
            "description": "Campaign budget (list mode). Quoted in the AD ACCOUNT currency, which can differ from the shop currency that every other monetary field here uses."
          },
          "metrics": { "$ref": "#/components/schemas/AdMetrics" }
        },
        "required": ["campaign_id", "campaign_name", "channel", "metrics"]
      },
      "CampaignPerformanceResponseData": {
        "type": "object",
        "properties": {
          "campaigns": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CampaignPerformanceData" },
            "description": "Performance data for each campaign"
          },
          "totals": {
            "allOf": [
              { "$ref": "#/components/schemas/PerformanceTotals" },
              { "description": "Aggregated totals across the filtered set" }
            ]
          },
          "pagination": {
            "allOf": [
              { "$ref": "#/components/schemas/PaginationMetadata" },
              {
                "description": "Pagination metadata — present in list mode only"
              }
            ]
          }
        },
        "required": ["campaigns", "totals"]
      },
      "ChannelPerformanceData": {
        "type": "object",
        "properties": {
          "channel": { "type": "string", "description": "Channel identifier" },
          "metrics": {
            "allOf": [
              { "$ref": "#/components/schemas/ChannelMetrics" },
              { "description": "Channel performance metrics" }
            ]
          }
        },
        "required": ["channel", "metrics"]
      },
      "ChannelPerformanceResponseData": {
        "type": "object",
        "properties": {
          "channels": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ChannelPerformanceData" },
            "description": "Performance data for each channel"
          },
          "totals": {
            "allOf": [
              { "$ref": "#/components/schemas/ChannelTotals" },
              { "description": "Aggregated totals across all channels" }
            ]
          }
        },
        "required": ["channels", "totals"]
      },
      "AnalyticsSummaryData": {
        "type": "object",
        "properties": {
          "orders": {
            "type": "number",
            "description": "Total orders in the window"
          },
          "gross_revenue": {
            "type": "number",
            "description": "Gross revenue (order totals)"
          },
          "refunds": {
            "type": "number",
            "description": "Total refunded amount"
          },
          "net_revenue": {
            "type": "number",
            "description": "Gross revenue − tax − refunds"
          },
          "tax": {
            "type": "number",
            "description": "Tax total (0 for VAT-ignoring shops)"
          },
          "cogs": { "type": "number", "description": "Cost of goods sold" },
          "payment_fees": {
            "type": "number",
            "description": "Payment provider fees"
          },
          "shipping_fees": {
            "type": "number",
            "description": "Shipping costs (from shipping profiles)"
          },
          "ad_spend": {
            "type": "number",
            "description": "Total ad spend across all connected channels"
          },
          "cm1": {
            "type": "number",
            "description": "Contribution margin 1 = net revenue − COGS"
          },
          "cm2": {
            "type": "number",
            "description": "Contribution margin 2 = CM1 − payment − shipping"
          },
          "cm3": {
            "type": "number",
            "description": "Contribution margin 3 (net profit) = CM2 − ad spend"
          },
          "roas": {
            "type": ["number", "null"],
            "description": "Blended ROAS = gross_revenue / ad_spend; null when ad_spend is 0"
          },
          "mer": {
            "type": ["number", "null"],
            "description": "Marketing efficiency ratio = gross_revenue / ad_spend (identical to blended ROAS here); null when ad_spend is 0"
          },
          "poas": {
            "type": ["number", "null"],
            "description": "Profit on ad spend = CM2 / ad_spend; null when ad_spend is 0"
          },
          "aov": {
            "type": ["number", "null"],
            "description": "Average order value = gross_revenue / orders"
          },
          "new_customers": {
            "type": "number",
            "description": "First-time customers acquired in the window"
          },
          "new_customer_revenue": {
            "type": "number",
            "description": "Revenue from first-time customers"
          },
          "cac": {
            "type": ["number", "null"],
            "description": "Customer acquisition cost = ad_spend / new_customers; null when 0 new customers"
          }
        },
        "required": [
          "orders",
          "gross_revenue",
          "refunds",
          "net_revenue",
          "tax",
          "cogs",
          "payment_fees",
          "shipping_fees",
          "ad_spend",
          "cm1",
          "cm2",
          "cm3",
          "roas",
          "mer",
          "poas",
          "aov",
          "new_customers",
          "new_customer_revenue",
          "cac"
        ]
      },
      "MetricsTimeseriesPoint": {
        "type": "object",
        "properties": {
          "timestamp": {
            "type": "string",
            "description": "Bucket start (shop-local)"
          },
          "total_orders": { "type": "number" },
          "total_revenue": {
            "type": "number",
            "description": "Gross revenue in the bucket"
          },
          "total_refunds": { "type": "number" },
          "total_cogs": { "type": "number" },
          "total_ad_spend": { "type": "number" },
          "total_payment_fees": { "type": "number" },
          "total_shipping_fees": { "type": "number" },
          "total_tax": { "type": "number" },
          "net_revenue": { "type": "number" },
          "cm1": { "type": "number" },
          "cm2": { "type": "number" },
          "profit": { "type": "number", "description": "CM3 = CM2 − ad spend" },
          "roas": {
            "type": "number",
            "description": "Blended ROAS in the bucket (0 when no spend)"
          },
          "new_customer_count": { "type": "number" },
          "new_customer_revenue": { "type": "number" },
          "new_customer_roas": { "type": "number" },
          "cac": {
            "type": "number",
            "description": "Ad spend / new customers in the bucket (0 when none)"
          }
        },
        "required": [
          "timestamp",
          "total_orders",
          "total_revenue",
          "total_refunds",
          "total_cogs",
          "total_ad_spend",
          "total_payment_fees",
          "total_shipping_fees",
          "total_tax",
          "net_revenue",
          "cm1",
          "cm2",
          "profit",
          "roas",
          "new_customer_count",
          "new_customer_revenue",
          "new_customer_roas",
          "cac"
        ]
      },
      "MetricsTimeseriesResponseData": {
        "type": "object",
        "properties": {
          "timeseries": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/MetricsTimeseriesPoint" }
          },
          "aggregation_level": {
            "type": "string",
            "enum": ["hourly", "daily", "weekly"],
            "description": "Bucket size actually used"
          }
        },
        "required": ["timeseries", "aggregation_level"]
      },
      "ProfitLossRow": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "Stable row identifier (e.g. gross_revenue, cm1)"
          },
          "label": {
            "type": "string",
            "description": "Human-readable row label"
          },
          "kind": {
            "type": "string",
            "enum": ["currency", "number"],
            "description": "Value unit"
          },
          "emphasis": {
            "type": "string",
            "enum": ["subtotal"],
            "description": "Present on subtotal rows"
          },
          "muted": { "type": "boolean" },
          "inverted": {
            "type": "boolean",
            "description": "True when the value is a deduction"
          },
          "value": { "type": ["number", "null"] },
          "percent": {
            "type": ["number", "null"],
            "description": "Share of gross revenue (percent)"
          }
        },
        "required": ["key", "label", "kind", "value"]
      },
      "ProfitLossWaterfallStep": {
        "type": "object",
        "properties": {
          "key": { "type": "string" },
          "label": { "type": "string" },
          "type": { "type": "string", "enum": ["subtotal", "cost"] },
          "value": { "type": "number" },
          "from": { "type": "number" },
          "to": { "type": "number" },
          "pct": { "type": ["number", "null"] }
        },
        "required": ["key", "label", "type", "value", "from", "to", "pct"]
      },
      "ProfitLossResponseData": {
        "type": "object",
        "properties": {
          "rows": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ProfitLossRow" },
            "description": "P&L statement rows, top to bottom"
          },
          "waterfall": {
            "type": ["object", "null"],
            "properties": {
              "steps": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ProfitLossWaterfallStep"
                }
              },
              "max": { "type": "number" }
            },
            "required": ["steps", "max"],
            "description": "Waterfall chart data (null when the statement is empty)"
          }
        },
        "required": ["rows", "waterfall"]
      },
      "CohortMetrics": {
        "type": "object",
        "properties": {
          "active_customers": { "type": "number" },
          "active_customers_percentage": { "type": "number" },
          "orders": { "type": "number" },
          "net_revenue": { "type": "number" },
          "contribution_margin_one": { "type": "number" },
          "contribution_margin_three": { "type": "number" },
          "average_order_value": { "type": "number" }
        },
        "required": [
          "active_customers",
          "active_customers_percentage",
          "orders",
          "net_revenue",
          "contribution_margin_one",
          "contribution_margin_three",
          "average_order_value"
        ]
      },
      "CohortCumulativeMetrics": {
        "allOf": [
          { "$ref": "#/components/schemas/CohortMetrics" },
          {
            "type": "object",
            "properties": {
              "ltv_to_date": {
                "type": "number",
                "description": "Cumulative net revenue per cohort customer"
              },
              "net_ltv_to_date": {
                "type": "number",
                "description": "Cumulative CM1 per cohort customer"
              },
              "ltv_to_cac_ratio": { "type": "number" },
              "net_ltv_to_cac_ratio": { "type": "number" },
              "is_payback_achieved": {
                "type": "boolean",
                "description": "Whether cumulative CM3 per customer has covered CAC"
              },
              "cumulative_contribution_margin_three_per_customer": {
                "type": "number"
              }
            },
            "required": [
              "ltv_to_date",
              "net_ltv_to_date",
              "ltv_to_cac_ratio",
              "net_ltv_to_cac_ratio",
              "is_payback_achieved",
              "cumulative_contribution_margin_three_per_customer"
            ]
          }
        ]
      },
      "CohortData": {
        "type": "object",
        "properties": {
          "cohort": {
            "type": "string",
            "description": "Cohort start date (YYYY-MM-DD)"
          },
          "cohort_size": {
            "type": "number",
            "description": "Customers acquired in the cohort period"
          },
          "cohort_ad_spend": {
            "type": "number",
            "description": "Ad spend during the cohort period"
          },
          "cac_per_customer": { "type": "number" },
          "periods": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "period": {
                  "type": "number",
                  "description": "Periods since acquisition (0 = cohort period itself)"
                },
                "metrics": {
                  "type": "object",
                  "properties": {
                    "incremental": {
                      "$ref": "#/components/schemas/CohortMetrics"
                    },
                    "cumulative": {
                      "$ref": "#/components/schemas/CohortCumulativeMetrics"
                    }
                  },
                  "required": ["incremental", "cumulative"]
                }
              },
              "required": ["period", "metrics"]
            }
          }
        },
        "required": [
          "cohort",
          "cohort_size",
          "cohort_ad_spend",
          "cac_per_customer",
          "periods"
        ]
      },
      "CohortsResponseData": {
        "type": "object",
        "properties": {
          "cohorts": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CohortData" }
          },
          "cohort_type": { "type": "string" },
          "max_periods": { "type": "number" },
          "currency": { "type": "string", "description": "Shop currency code" }
        },
        "required": ["cohorts", "cohort_type", "max_periods"]
      },
      "RetentionResponseData": {
        "type": "object",
        "properties": {
          "metadata": {
            "type": "object",
            "properties": {
              "start_date": { "type": "string" },
              "end_date": { "type": "string" },
              "currency": { "type": "string" },
              "timezone": { "type": "string" },
              "refund_attribution": {
                "type": "string",
                "enum": ["refund_date", "order_date", "ignore_refunds"]
              },
              "data_updated_at": { "type": ["string", "null"] },
              "availability": {
                "type": "object",
                "additionalProperties": {
                  "type": "object",
                  "properties": {
                    "available": { "type": "boolean" },
                    "reason": { "type": ["string", "null"] },
                    "coverage": { "type": ["number", "null"] },
                    "sample_size": { "type": ["number", "null"] }
                  },
                  "required": ["available", "reason", "coverage", "sample_size"]
                }
              },
              "limits": {
                "type": "object",
                "properties": {
                  "product_limit": { "type": "number" },
                  "channel_limit": { "type": "number" }
                },
                "required": ["product_limit", "channel_limit"]
              }
            },
            "required": [
              "start_date",
              "end_date",
              "currency",
              "timezone",
              "refund_attribution",
              "data_updated_at",
              "availability",
              "limits"
            ]
          },
          "kpis": {
            "type": "object",
            "properties": {
              "avg_clv": {
                "type": ["number", "null"],
                "description": "Average customer lifetime value"
              },
              "pct_repeat_purchasers": { "type": ["number", "null"] },
              "avg_days_to_second_purchase": { "type": ["number", "null"] },
              "clv_to_cac_ratio": { "type": ["number", "null"] },
              "avg_days_between_orders": { "type": ["number", "null"] },
              "new_customer_aov": { "type": ["number", "null"] },
              "returning_customer_aov": { "type": ["number", "null"] },
              "avg_orders_per_customer": { "type": ["number", "null"] },
              "avg_products_per_order": { "type": ["number", "null"] },
              "avg_contribution_profit": { "type": ["number", "null"] },
              "avg_net_profit": { "type": ["number", "null"] },
              "contribution_margin_pct": { "type": ["number", "null"] },
              "avg_cm_per_order": { "type": ["number", "null"] },
              "paid_new_customer_cac": { "type": ["number", "null"] }
            },
            "required": [
              "avg_clv",
              "pct_repeat_purchasers",
              "avg_days_to_second_purchase",
              "clv_to_cac_ratio",
              "avg_days_between_orders",
              "new_customer_aov",
              "returning_customer_aov",
              "avg_orders_per_customer",
              "avg_products_per_order",
              "avg_contribution_profit",
              "avg_net_profit",
              "contribution_margin_pct",
              "avg_cm_per_order",
              "paid_new_customer_cac"
            ]
          },
          "clv_cac_trend": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "period_label": { "type": "string" },
                "clv": { "type": ["number", "null"] },
                "cac": { "type": ["number", "null"] },
                "clv_to_cac": { "type": ["number", "null"] }
              },
              "required": ["period_label", "clv", "cac", "clv_to_cac"]
            }
          },
          "expected_next_order": {
            "type": ["object", "null"],
            "properties": {
              "avg_days_to_second_purchase": { "type": "number" },
              "avg_days_between_orders": { "type": "number" },
              "winback_start_days": { "type": "number" },
              "at_risk_days": { "type": "number" },
              "lost_days": { "type": "number" },
              "sample_size": { "type": "number" },
              "method": { "type": "string" }
            },
            "required": [
              "avg_days_to_second_purchase",
              "avg_days_between_orders",
              "winback_start_days",
              "at_risk_days",
              "lost_days",
              "sample_size",
              "method"
            ]
          },
          "aov_timeseries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": { "type": "string" },
                "new_aov": { "type": ["number", "null"] },
                "returning_aov": { "type": ["number", "null"] }
              },
              "required": ["date", "new_aov", "returning_aov"]
            }
          },
          "order_gap_distribution": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "from_order": { "type": "number" },
                "to_order": { "type": "number" },
                "avg_days": { "type": "number" },
                "sample_size": { "type": "number" }
              },
              "required": ["from_order", "to_order", "avg_days", "sample_size"]
            }
          },
          "channel_breakdown": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "channel": { "type": "string" },
                "customer_count": { "type": "number" },
                "new_customer_aov": { "type": ["number", "null"] },
                "repeat_rate": { "type": ["number", "null"] },
                "avg_days_to_second_purchase": { "type": ["number", "null"] },
                "paid_new_customer_cac": { "type": ["number", "null"] },
                "cm3_per_customer": { "type": ["number", "null"] },
                "is_paid": { "type": ["boolean", "null"] }
              },
              "required": [
                "channel",
                "customer_count",
                "new_customer_aov",
                "repeat_rate",
                "avg_days_to_second_purchase",
                "paid_new_customer_cac",
                "cm3_per_customer",
                "is_paid"
              ]
            }
          },
          "repurchase_windows": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "window_days": { "type": "number" },
                "pct_customers": { "type": ["number", "null"] },
                "mature_customer_count": { "type": "number" },
                "repeat_customer_count": { "type": "number" }
              },
              "required": [
                "window_days",
                "pct_customers",
                "mature_customer_count",
                "repeat_customer_count"
              ]
            }
          },
          "ltv_by_first_product": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "product_id": { "type": "string" },
                "product_name": { "type": "string" },
                "image_url": { "type": "string" },
                "first_purchase_customers": { "type": "number" },
                "ltv_90d": { "type": ["number", "null"] },
                "ltv_180d": { "type": ["number", "null"] },
                "ltv_365d": { "type": ["number", "null"] },
                "repeat_rate": { "type": ["number", "null"] },
                "net_ltv_90d": { "type": ["number", "null"] },
                "net_ltv_180d": { "type": ["number", "null"] },
                "net_ltv_365d": { "type": ["number", "null"] },
                "contribution_margin_pct": { "type": ["number", "null"] },
                "mature_customers": {
                  "type": "object",
                  "properties": {
                    "days_90": { "type": "number" },
                    "days_180": { "type": "number" },
                    "days_365": { "type": "number" }
                  },
                  "required": ["days_90", "days_180", "days_365"]
                }
              },
              "required": [
                "product_id",
                "product_name",
                "first_purchase_customers",
                "ltv_90d",
                "ltv_180d",
                "ltv_365d",
                "repeat_rate",
                "net_ltv_90d",
                "net_ltv_180d",
                "net_ltv_365d",
                "contribution_margin_pct",
                "mature_customers"
              ]
            }
          },
          "period_ltv": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "window_days": { "type": "number" },
                "ltv": { "type": ["number", "null"] },
                "cumulative_revenue": { "type": ["number", "null"] },
                "profit_ltv": { "type": ["number", "null"] },
                "cumulative_profit": { "type": ["number", "null"] },
                "mature_customer_count": { "type": "number" }
              },
              "required": [
                "window_days",
                "ltv",
                "cumulative_revenue",
                "profit_ltv",
                "cumulative_profit",
                "mature_customer_count"
              ]
            }
          }
        },
        "required": [
          "metadata",
          "kpis",
          "clv_cac_trend",
          "expected_next_order",
          "aov_timeseries",
          "order_gap_distribution",
          "channel_breakdown",
          "repurchase_windows",
          "ltv_by_first_product",
          "period_ltv"
        ]
      },
      "ProductRelationshipsResponseData": {
        "type": "object",
        "properties": {
          "top_bought_together": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "product_a_id": { "type": "string" },
                "product_a": { "type": "string" },
                "product_b_id": { "type": "string" },
                "product_b": { "type": "string" },
                "order_count": {
                  "type": "number",
                  "description": "Orders containing both products"
                },
                "pair_rate": {
                  "type": "number",
                  "description": "order_count / product A's orders"
                }
              },
              "required": [
                "product_a_id",
                "product_a",
                "product_b_id",
                "product_b",
                "order_count",
                "pair_rate"
              ]
            }
          },
          "top_buy_next": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "first_product_id": { "type": "string" },
                "first_product": { "type": "string" },
                "next_product_id": { "type": "string" },
                "next_product": { "type": "string" },
                "customer_count": {
                  "type": "number",
                  "description": "Customers whose next order contained the next product"
                },
                "next_rate": {
                  "type": "number",
                  "description": "customer_count / first product's customers"
                }
              },
              "required": [
                "first_product_id",
                "first_product",
                "next_product_id",
                "next_product",
                "customer_count",
                "next_rate"
              ]
            }
          },
          "products": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "product_id": { "type": "string" },
                "product_name": { "type": "string" },
                "image_url": { "type": "string" },
                "customers": { "type": "number" },
                "orders": { "type": "number" },
                "total_units_sold": { "type": "number" },
                "avg_units_per_customer": { "type": "number" },
                "repurchase_rate": { "type": "number" },
                "first_order_rate": { "type": "number" },
                "repeat_order_rate": { "type": "number" },
                "related_products": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "product_id": { "type": "string" },
                      "product_name": { "type": "string" },
                      "same_order_count": {
                        "type": "number",
                        "description": "Orders containing both products"
                      },
                      "same_order_rate": { "type": "number" },
                      "first_order_together_count": { "type": "number" },
                      "first_order_together_rate": { "type": "number" },
                      "bought_directly_after_count": { "type": "number" },
                      "bought_directly_after_rate": { "type": "number" },
                      "bought_after_count": { "type": "number" },
                      "bought_after_rate": { "type": "number" },
                      "same_customer_count": { "type": "number" },
                      "same_customer_rate": { "type": "number" }
                    },
                    "required": [
                      "product_id",
                      "product_name",
                      "same_order_count",
                      "same_order_rate",
                      "first_order_together_count",
                      "first_order_together_rate",
                      "bought_directly_after_count",
                      "bought_directly_after_rate",
                      "bought_after_count",
                      "bought_after_rate",
                      "same_customer_count",
                      "same_customer_rate"
                    ]
                  }
                }
              },
              "required": [
                "product_id",
                "product_name",
                "customers",
                "orders",
                "total_units_sold",
                "avg_units_per_customer",
                "repurchase_rate",
                "first_order_rate",
                "repeat_order_rate",
                "related_products"
              ]
            }
          },
          "data_updated_at": {
            "type": ["string", "null"],
            "description": "When the relationships were last rebuilt (daily job)"
          },
          "currency": { "type": "string" }
        },
        "required": [
          "top_bought_together",
          "top_buy_next",
          "products",
          "data_updated_at"
        ]
      },
      "OrderSummaryData": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "description": "Shopify order ID" },
          "order_number": {
            "type": ["string", "null"],
            "description": "Shopify order name/number (e.g. \"#1001\")"
          },
          "order_timestamp": {
            "type": ["string", "null"],
            "description": "Order creation timestamp (UTC, ISO 8601-like \"YYYY-MM-DD HH:MM:SS\")"
          },
          "total_price": {
            "type": ["number", "null"],
            "description": "Gross order total (shop currency)"
          },
          "total_tax": {
            "type": ["number", "null"],
            "description": "Order tax total"
          },
          "total_refund_amount": {
            "type": ["number", "null"],
            "description": "Total refunded amount"
          },
          "refund_status": {
            "type": "string",
            "enum": ["none", "partial", "full"],
            "description": "Derived refund state: none (no refund), partial (refunded < order total), full (refunded >= order total). Venon does not mirror Shopify financial_status."
          },
          "net_revenue": {
            "type": ["number", "null"],
            "description": "Net revenue = gross total − effective tax − refunds"
          },
          "cm1": {
            "type": ["number", "null"],
            "description": "Contribution margin 1 = net revenue − COGS"
          },
          "cm2": {
            "type": ["number", "null"],
            "description": "Contribution margin 2 = CM1 − payment fees − shipping fees"
          },
          "is_first_customer_order": {
            "type": ["boolean", "null"],
            "description": "Whether this is the customer's first order in the shop"
          },
          "customer_first_name": {
            "type": ["string", "null"],
            "description": "Customer first name"
          },
          "customer_last_name": {
            "type": ["string", "null"],
            "description": "Customer last name"
          },
          "payment_gateway": {
            "type": ["string", "null"],
            "description": "Payment gateway that processed the order"
          },
          "shipping_country": {
            "type": ["string", "null"],
            "description": "Shipping country code"
          }
        },
        "required": [
          "id",
          "order_number",
          "order_timestamp",
          "total_price",
          "total_tax",
          "total_refund_amount",
          "refund_status",
          "net_revenue",
          "cm1",
          "cm2",
          "is_first_customer_order",
          "customer_first_name",
          "customer_last_name",
          "payment_gateway",
          "shipping_country"
        ]
      },
      "OrdersListResponseData": {
        "type": "object",
        "properties": {
          "orders": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/OrderSummaryData" },
            "description": "Orders in the requested window"
          },
          "pagination": { "$ref": "#/components/schemas/PaginationMetadata" }
        },
        "required": ["orders", "pagination"]
      },
      "OrderCostLineItem": {
        "type": "object",
        "properties": {
          "id": { "type": "string", "description": "Line item ID" },
          "product_id": {
            "type": ["string", "null"],
            "description": "Shopify product ID"
          },
          "variant_id": {
            "type": ["string", "null"],
            "description": "Shopify variant ID"
          },
          "title": {
            "type": "string",
            "description": "Product title (falls back to variant/line label)"
          },
          "variant_title": {
            "type": ["string", "null"],
            "description": "Variant title"
          },
          "sku": {
            "type": ["string", "null"],
            "description": "Merchant-assigned Shopify SKU (null when unset or not yet re-synced)"
          },
          "image_url": {
            "type": ["string", "null"],
            "description": "Product image URL"
          },
          "quantity": { "type": "number", "description": "Quantity ordered" },
          "sale_price": {
            "type": ["number", "null"],
            "description": "Per-unit sale price"
          },
          "product_cost": {
            "type": ["number", "null"],
            "description": "Per-unit resolved COGS at order time"
          },
          "product_profit": {
            "type": ["number", "null"],
            "description": "Per-unit sale price − per-unit COGS"
          }
        },
        "required": [
          "id",
          "product_id",
          "variant_id",
          "title",
          "variant_title",
          "sku",
          "image_url",
          "quantity",
          "sale_price",
          "product_cost",
          "product_profit"
        ]
      },
      "OrderCostSummary": {
        "type": "object",
        "properties": {
          "gross_revenue": {
            "type": ["number", "null"],
            "description": "Gross order total"
          },
          "effective_tax": {
            "type": ["number", "null"],
            "description": "Tax actually deducted by the profit engine (0 for VAT-ignoring shops)"
          },
          "net_revenue": {
            "type": ["number", "null"],
            "description": "Gross − effective tax − refunds"
          },
          "total_cogs": {
            "type": ["number", "null"],
            "description": "Total cost of goods sold"
          },
          "payment_fees": {
            "type": ["number", "null"],
            "description": "Payment provider fees"
          },
          "shipping_fees": {
            "type": ["number", "null"],
            "description": "Shipping cost resolved from shipping profiles, in `shipping_profile_currency` (which normally equals, but is not guaranteed to equal, the shop currency)"
          },
          "shipping_profile": {
            "type": ["string", "null"],
            "description": "Name of the shipping profile that resolved the shipping fee"
          },
          "shipping_profile_currency": {
            "type": ["string", "null"],
            "description": "Currency the resolving shipping profile denominates its fees in, and therefore the currency of `shipping_fees`. Profiles carry their own currency independent of the shop, so compare it against the shop currency in response metadata before mixing this amount with the other totals. Null when no profile resolved."
          },
          "total_refund_amount": {
            "type": ["number", "null"],
            "description": "Total refunded amount"
          },
          "recovered_cogs": {
            "type": ["number", "null"],
            "description": "COGS recovered through restocked refunds"
          },
          "recovered_vat": {
            "type": ["number", "null"],
            "description": "VAT recovered through refunds"
          },
          "cm1": {
            "type": ["number", "null"],
            "description": "Contribution margin 1 = net revenue − COGS"
          },
          "cm2": {
            "type": ["number", "null"],
            "description": "Contribution margin 2 = CM1 − payment − shipping"
          },
          "net_margin": {
            "type": ["number", "null"],
            "description": "CM2 / net revenue × 100 (percent)"
          },
          "break_even_roas": {
            "type": ["number", "null"],
            "description": "Net revenue / CM2 — ROAS needed to break even"
          },
          "cm3": {
            "type": "null",
            "description": "Always null: ad spend is not attributable to a single order yet"
          }
        },
        "required": [
          "gross_revenue",
          "effective_tax",
          "net_revenue",
          "total_cogs",
          "payment_fees",
          "shipping_fees",
          "shipping_profile",
          "shipping_profile_currency",
          "total_refund_amount",
          "recovered_cogs",
          "recovered_vat",
          "cm1",
          "cm2",
          "net_margin",
          "break_even_roas",
          "cm3"
        ]
      },
      "OrderCostBreakdownResponseData": {
        "type": "object",
        "properties": {
          "order": {
            "type": "object",
            "properties": {
              "id": { "type": "string", "description": "Shopify order ID" },
              "name": {
                "type": "string",
                "description": "Shopify order name/number"
              }
            },
            "required": ["id", "name"]
          },
          "has_cost_data": {
            "type": "boolean",
            "description": "Whether any cost component resolved for this order"
          },
          "line_items": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/OrderCostLineItem" }
          },
          "summary": { "$ref": "#/components/schemas/OrderCostSummary" },
          "unavailable_metrics": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Human-readable notes about metrics not available per order"
          }
        },
        "required": [
          "order",
          "has_cost_data",
          "line_items",
          "summary",
          "unavailable_metrics"
        ]
      },
      "ProductPerformanceData": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": ["string", "null"],
            "description": "Shopify product ID (null if unresolvable)"
          },
          "product_name": {
            "type": ["string", "null"],
            "description": "Product name"
          },
          "variant_id": {
            "type": ["string", "null"],
            "description": "Shopify variant ID (present when level=variant)"
          },
          "variant_title": {
            "type": ["string", "null"],
            "description": "Variant title (present when level=variant)"
          },
          "sku": {
            "type": ["string", "null"],
            "description": "Merchant-assigned SKU from Shopify (present when level=variant; null when the merchant left it empty or the variant hasn't re-synced since SKU support shipped)"
          },
          "units": {
            "type": "number",
            "description": "Units sold in the window"
          },
          "orders": {
            "type": "number",
            "description": "Distinct orders containing this product/variant"
          },
          "gross_revenue": {
            "type": "number",
            "description": "Gross line-item revenue (unit price × quantity)"
          },
          "cogs": {
            "type": "number",
            "description": "Total resolved COGS (unresolvable lines count 0)"
          },
          "margin": { "type": "number", "description": "gross_revenue − cogs" },
          "margin_pct": {
            "type": ["number", "null"],
            "description": "margin / gross_revenue × 100; null when revenue is 0"
          }
        },
        "required": [
          "product_id",
          "product_name",
          "units",
          "orders",
          "gross_revenue",
          "cogs",
          "margin",
          "margin_pct"
        ]
      },
      "ProductPerformanceTotals": {
        "type": "object",
        "properties": {
          "units": { "type": "number" },
          "gross_revenue": { "type": "number" },
          "cogs": { "type": "number" },
          "margin": { "type": "number" }
        },
        "required": ["units", "gross_revenue", "cogs", "margin"]
      },
      "ProductPerformanceResponseData": {
        "type": "object",
        "properties": {
          "products": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ProductPerformanceData" }
          },
          "totals": {
            "allOf": [
              { "$ref": "#/components/schemas/ProductPerformanceTotals" },
              { "description": "Totals over the full filtered set" }
            ]
          },
          "pagination": { "$ref": "#/components/schemas/PaginationMetadata" }
        },
        "required": ["products", "totals", "pagination"]
      },
      "CatalogVariant": {
        "type": "object",
        "properties": {
          "variant_id": {
            "type": "string",
            "description": "Shopify variant ID"
          },
          "variant_title": {
            "type": ["string", "null"],
            "description": "Variant title"
          },
          "sku": {
            "type": ["string", "null"],
            "description": "Merchant-assigned Shopify SKU (null when unset or not yet re-synced)"
          },
          "price": {
            "type": ["number", "null"],
            "description": "Variant price"
          }
        },
        "required": ["variant_id", "variant_title", "sku", "price"]
      },
      "CatalogProduct": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "string",
            "description": "Shopify product ID"
          },
          "product_name": { "type": "string", "description": "Product name" },
          "product_type": {
            "type": ["string", "null"],
            "description": "Shopify product type"
          },
          "variants": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CatalogVariant" }
          }
        },
        "required": ["product_id", "product_name", "product_type", "variants"]
      },
      "ProductCatalogResponseData": {
        "type": "object",
        "properties": {
          "products": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CatalogProduct" }
          },
          "pagination": { "$ref": "#/components/schemas/PaginationMetadata" }
        },
        "required": ["products", "pagination"]
      },
      "AttributedOrder": {
        "type": "object",
        "properties": {
          "order_id": { "type": "string", "description": "Shopify order ID" },
          "order_number": {
            "type": "string",
            "description": "Shopify order name/number"
          },
          "order_timestamp": {
            "type": "string",
            "description": "Order timestamp"
          },
          "total_price": {
            "type": "number",
            "description": "Gross order total (shop currency)"
          },
          "is_first_customer_order": {
            "type": "boolean",
            "description": "Whether this was the customer's first order"
          }
        },
        "required": [
          "order_id",
          "order_number",
          "order_timestamp",
          "total_price"
        ]
      },
      "AttributedOrdersResponseData": {
        "type": "object",
        "properties": {
          "orders": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AttributedOrder" },
            "description": "Orders attributed to the scope"
          },
          "pagination": { "$ref": "#/components/schemas/PaginationMetadata" }
        },
        "required": ["orders", "pagination"]
      },
      "AttributedProduct": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "string",
            "description": "Shopify product ID"
          },
          "product_name": { "type": "string", "description": "Product name" },
          "variant_id": {
            "type": ["string", "null"],
            "description": "Shopify variant ID"
          },
          "variant_name": {
            "type": ["string", "null"],
            "description": "Variant name"
          },
          "sku": {
            "type": ["string", "null"],
            "description": "Merchant-assigned Shopify SKU (null when unset or not yet re-synced)"
          },
          "image_url": {
            "type": ["string", "null"],
            "description": "Product image URL"
          },
          "quantity": {
            "type": "number",
            "description": "Units bought in the attributed orders"
          },
          "revenue": {
            "type": "number",
            "description": "Line revenue in the attributed orders"
          }
        },
        "required": [
          "product_id",
          "product_name",
          "variant_id",
          "variant_name",
          "sku",
          "image_url",
          "quantity",
          "revenue"
        ]
      },
      "AttributedProductsResponseData": {
        "type": "object",
        "properties": {
          "products": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/AttributedProduct" },
            "description": "Products bought in the attributed orders"
          },
          "pagination": { "$ref": "#/components/schemas/PaginationMetadata" }
        },
        "required": ["products", "pagination"]
      },
      "NonAdCampaign": {
        "type": "object",
        "properties": {
          "channel": { "type": "string" },
          "campaign": {
            "type": ["string", "null"],
            "description": "Campaign name from tracking parameters (null = no campaign tag)"
          },
          "attributed_orders": { "type": "number" },
          "attributed_revenue": { "type": "number" },
          "distinct_orders_touched": { "type": "number" },
          "attributed_cogs": { "type": "number" },
          "attributed_payment_fees": { "type": "number" },
          "attributed_tax": { "type": "number" },
          "gross_revenue": { "type": "number" },
          "net_profit": { "type": "number" },
          "profit_margin_pct": { "type": "number" },
          "avg_order_value": { "type": "number" },
          "revenue_per_order_touched": { "type": "number" },
          "first_time_customer_orders": { "type": "number" },
          "first_time_customer_revenue": { "type": "number" }
        },
        "required": [
          "channel",
          "campaign",
          "attributed_orders",
          "attributed_revenue",
          "distinct_orders_touched",
          "attributed_cogs",
          "attributed_payment_fees",
          "attributed_tax",
          "gross_revenue",
          "net_profit",
          "profit_margin_pct",
          "avg_order_value",
          "revenue_per_order_touched",
          "first_time_customer_orders",
          "first_time_customer_revenue"
        ]
      },
      "NonAdCampaignsResponseData": {
        "type": "object",
        "properties": {
          "campaigns": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/NonAdCampaign" },
            "description": "Campaign-level attributed performance"
          }
        },
        "required": ["campaigns"]
      },
      "ShippingTier": {
        "type": "object",
        "properties": {
          "up_to": {
            "type": ["integer", "null"],
            "exclusiveMinimum": 0,
            "description": "Upper bound of this tier (kg/g/lbs/oz for weight, count for item). null = open-ended top tier."
          },
          "cost": {
            "type": "number",
            "minimum": 0,
            "description": "Shipping cost for this tier."
          }
        },
        "required": ["up_to", "cost"]
      },
      "SetShippingTiersBody": {
        "type": "object",
        "properties": {
          "profile_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Target shipping profile id."
          },
          "axis": {
            "type": "string",
            "enum": ["per_order", "per_order_return"],
            "default": "per_order",
            "description": "Which axis: outbound shipping (per_order) or returns (per_order_return)."
          },
          "type": {
            "type": "string",
            "enum": ["weight", "item"],
            "description": "Tier basis: weight or item count."
          },
          "weight_unit": {
            "type": "string",
            "enum": ["g", "kg", "lbs", "oz"],
            "description": "Display unit for weight tiers (default kg); ignored for item tiers."
          },
          "tiers": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ShippingTier" },
            "minItems": 1,
            "maxItems": 50,
            "description": "Graduated tiers, ascending. Exactly one may be open-ended (up_to:null) and it must be last."
          },
          "dry_run": {
            "type": "boolean",
            "default": false,
            "description": "When true, validate + return a plan only; performs NO write (axis replace is destructive)."
          }
        },
        "required": ["profile_id", "type", "tiers"]
      },
      "BulkCogsTarget": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Shopify product id (set this XOR variant_id)"
          },
          "variant_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Shopify variant id (set this XOR product_id)"
          }
        }
      },
      "BulkSetCogsBody": {
        "type": "object",
        "properties": {
          "targets": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/BulkCogsTarget" },
            "minItems": 1,
            "maxItems": 100,
            "description": "Products/variants to write the COGS rule for (one rule each)."
          },
          "mode": {
            "type": "string",
            "enum": ["shopify", "constant", "percent"],
            "description": "Cost mode: shopify (use Shopify cost), constant (absolute), or percent of price."
          },
          "value": {
            "type": "number",
            "minimum": 0,
            "description": "Cost value. Required for constant (>=0) and percent (0-100); omit/ignored for shopify."
          },
          "basis": {
            "type": "string",
            "enum": ["selling"],
            "description": "Percent basis — only 'selling' is supported (required when mode=percent)."
          },
          "recover_on_return": {
            "type": ["boolean", "null"],
            "description": "Override charge-COGS-on-returns for these targets; null/omit inherits global."
          },
          "effective_from": {
            "type": "string",
            "format": "date-time",
            "description": "Reserved — period start is implicit (server uses NOW). Accepted but not applied."
          },
          "dry_run": {
            "type": "boolean",
            "default": false,
            "description": "When true, validate + plan only; performs NO write."
          }
        },
        "required": ["targets", "mode"]
      },
      "BulkSetPaymentFeesBody": {
        "type": "object",
        "properties": {
          "gateways": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": { "type": "integer", "exclusiveMinimum": 0 },
                "cost": { "type": ["number", "null"], "minimum": 0 },
                "fee": { "type": ["number", "null"], "minimum": 0 },
                "effectiveAt": {
                  "anyOf": [
                    { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
                    { "type": "string", "format": "date-time" }
                  ]
                }
              },
              "required": ["id", "cost", "fee"]
            },
            "minItems": 1,
            "maxItems": 50,
            "description": "Payment-gateway upserts to apply (one upsert each)."
          },
          "dry_run": {
            "type": "boolean",
            "default": false,
            "description": "When true, validate + plan only; performs NO write."
          }
        },
        "required": ["gateways"]
      },
      "BulkDryRunResult": {
        "type": "object",
        "properties": {
          "dry_run": { "type": "boolean", "enum": [true] },
          "planned": {
            "type": "integer",
            "description": "Total targets/entries in the request"
          },
          "valid": {
            "type": "integer",
            "description": "How many passed validation and would be written"
          },
          "applied": { "type": "number", "enum": [0] },
          "invalid": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "target": {
                  "description": "The target/entry that would fail validation"
                },
                "reason": {
                  "type": "string",
                  "description": "Why it would fail (e.g. not found for this shop)"
                }
              },
              "required": ["reason"]
            },
            "description": "Targets/entries that would fail — product/variant/gateway not found for the shop."
          },
          "sample": {
            "type": "array",
            "items": {},
            "description": "First few VALID targets/entries that would be written (for confirmation)."
          }
        },
        "required": [
          "dry_run",
          "planned",
          "valid",
          "applied",
          "invalid",
          "sample"
        ]
      },
      "BulkApplyResult": {
        "type": "object",
        "properties": {
          "dry_run": { "type": "boolean", "enum": [false] },
          "applied": {
            "type": "integer",
            "description": "Number of writes that succeeded"
          },
          "failed": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "target": { "description": "The target/entry that failed" },
                "error": { "type": "string", "description": "Failure reason" }
              },
              "required": ["error"]
            },
            "description": "Per-target failures; one bad target does not abort the rest."
          }
        },
        "required": ["applied", "failed"]
      },
      "CogsHistoryPeriod": {
        "type": "object",
        "properties": {
          "value": {
            "type": "number",
            "minimum": 0,
            "description": "Cost value for this period. Required for constant (>=0) / percent (0-100)."
          },
          "until": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Period END (ISO datetime). null marks the final, currently-active period."
          }
        },
        "required": ["until"]
      },
      "SetCogsHistoryBody": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Shopify product id (set this XOR variant_id)."
          },
          "variant_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Shopify variant id (set this XOR product_id)."
          },
          "mode": {
            "type": "string",
            "enum": ["shopify", "constant", "percent"],
            "description": "Cost mode for EVERY period: shopify, constant (absolute), or percent of price."
          },
          "recover_on_return": {
            "type": ["boolean", "null"],
            "description": "Override charge-COGS-on-returns for every period; null/omit inherits global."
          },
          "periods": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CogsHistoryPeriod" },
            "minItems": 1,
            "maxItems": 20,
            "description": "Full timeline, ascending by `until`. Every period except the last has a finite `until`; the last has until=null (the active row). REPLACES the existing chain for this scope."
          },
          "dry_run": {
            "type": "boolean",
            "default": false,
            "description": "When true, validate + read existing + return a plan; performs NO write."
          }
        },
        "required": ["mode", "periods"]
      },
      "PaymentFeeHistoryPeriod": {
        "type": "object",
        "properties": {
          "cost": {
            "type": ["number", "null"],
            "minimum": 0,
            "description": "Fixed fee per transaction in the shop currency for this period (NOT a percent)."
          },
          "fee": {
            "type": ["number", "null"],
            "minimum": 0,
            "description": "Percent fee 0-100 for this period (NOT a fixed amount)."
          },
          "until": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Period END (ISO datetime). null marks the final, currently-active period."
          }
        },
        "required": ["cost", "fee", "until"]
      },
      "SetPaymentFeeHistoryBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "Payment gateway name (the (shop, name) chain to replace)."
          },
          "periods": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/PaymentFeeHistoryPeriod" },
            "minItems": 1,
            "maxItems": 20,
            "description": "Full fee timeline, ascending by `until`; the last has until=null (active). REPLACES the chain."
          },
          "dry_run": {
            "type": "boolean",
            "default": false,
            "description": "When true, validate + read existing + return a plan; performs NO write."
          }
        },
        "required": ["name", "periods"]
      },
      "ShippingFeeHistoryPeriod": {
        "type": "object",
        "properties": {
          "value": {
            "type": "number",
            "minimum": 0,
            "description": "Fee value for this period."
          },
          "until": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Period END (ISO datetime). null marks the final, currently-active period."
          }
        },
        "required": ["value", "until"]
      },
      "SetShippingFeeHistoryBody": {
        "type": "object",
        "properties": {
          "profile_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Target shipping profile id."
          },
          "value_name": {
            "type": "string",
            "enum": [
              "per_order_flat",
              "per_order_return_flat",
              "packaging_fee",
              "picking_first_item_fee",
              "picking_following_items_fee",
              "other_per_item_fee",
              "per_item_return_fee"
            ],
            "description": "Which scalar fee chain to replace (e.g. packaging_fee, per_item_return_fee)."
          },
          "periods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShippingFeeHistoryPeriod"
            },
            "minItems": 1,
            "maxItems": 20,
            "description": "Full timeline for this fee, ascending by `until`; the last has until=null (active). REPLACES the chain."
          },
          "dry_run": {
            "type": "boolean",
            "default": false,
            "description": "When true, validate + read existing + return a plan; performs NO write."
          }
        },
        "required": ["profile_id", "value_name", "periods"]
      },
      "ShippingBucketHistoryPeriod": {
        "type": "object",
        "properties": {
          "cost": {
            "type": "number",
            "minimum": 0,
            "description": "Bucket cost for this period."
          },
          "until": {
            "type": ["string", "null"],
            "format": "date-time",
            "description": "Period END (ISO datetime). null marks the final, currently-active period."
          }
        },
        "required": ["cost", "until"]
      },
      "SetShippingBucketHistoryBody": {
        "type": "object",
        "properties": {
          "profile_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Target shipping profile id."
          },
          "bucket_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Id of an existing bucket in this profile (from get_shipping_profile)."
          },
          "periods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShippingBucketHistoryPeriod"
            },
            "minItems": 1,
            "maxItems": 20,
            "description": "Full cost timeline for this bucket, ascending by `until`; the last has until=null (active). REPLACES the chain."
          },
          "dry_run": {
            "type": "boolean",
            "default": false,
            "description": "When true, validate + read existing + return a plan; performs NO write."
          }
        },
        "required": ["profile_id", "bucket_id", "periods"]
      },
      "CogsGlobalSettingsResponse": {
        "type": "object",
        "properties": {
          "fallbackPercent": {
            "type": ["number", "null"],
            "description": "Fallback COGS as % of price when no rule/variant cost resolves"
          },
          "fallbackBasis": {
            "type": "string",
            "enum": ["selling", "compare_at"],
            "description": "Price the fallback % applies to"
          },
          "chargeCogsOnReturns": {
            "type": "boolean",
            "description": "Whether returned items still incur COGS"
          }
        },
        "required": ["fallbackPercent", "fallbackBasis", "chargeCogsOnReturns"]
      },
      "CogsRuleRow": {
        "type": "object",
        "properties": {
          "id": { "type": "number", "description": "COGS rule row id" },
          "productId": {
            "type": ["number", "null"],
            "description": "Product scope (null for a variant-scoped rule)"
          },
          "variantId": {
            "type": ["number", "null"],
            "description": "Variant scope (null for a product-scoped rule)"
          },
          "mode": {
            "type": "string",
            "enum": ["shopify", "constant", "percent"],
            "description": "COGS mode: `shopify` = use the variant cost synced from Shopify; `constant` = fixed per-unit cost (`value`, shop currency); `percent` = percentage of the selling price (`value`, 0–100)."
          },
          "value": {
            "type": ["number", "null"],
            "description": "Cost value (constant: amount; percent: 0–100)"
          },
          "basis": {
            "type": ["string", "null"],
            "enum": ["selling", "compare_at"]
          },
          "recoverOnReturn": {
            "type": ["boolean", "null"],
            "description": "Per-rule return-recovery override (null = inherit the global setting)"
          },
          "effectiveTo": {
            "type": ["string", "null"],
            "description": "End of validity; null = currently active period"
          }
        },
        "required": [
          "id",
          "productId",
          "variantId",
          "mode",
          "value",
          "basis",
          "recoverOnReturn",
          "effectiveTo"
        ]
      },
      "CogsRuleHistoryEntry": {
        "type": "object",
        "properties": {
          "id": { "type": "number" },
          "effectiveFrom": {
            "type": "string",
            "description": "When the NEXT value took over (TimedValue polarity)"
          },
          "mode": {
            "type": "string",
            "enum": ["shopify", "constant", "percent"],
            "description": "COGS mode: `shopify` = use the variant cost synced from Shopify; `constant` = fixed per-unit cost (`value`, shop currency); `percent` = percentage of the selling price (`value`, 0–100)."
          },
          "value": { "type": ["number", "null"] },
          "basis": {
            "type": ["string", "null"],
            "enum": ["selling", "compare_at"]
          },
          "recoverOnReturn": { "type": ["boolean", "null"] }
        },
        "required": [
          "id",
          "effectiveFrom",
          "mode",
          "value",
          "basis",
          "recoverOnReturn"
        ]
      },
      "CogsRuleScopeView": {
        "type": "object",
        "properties": {
          "scope": {
            "type": "object",
            "properties": {
              "productId": { "type": ["number", "null"] },
              "variantId": { "type": ["number", "null"] }
            },
            "required": ["productId", "variantId"]
          },
          "effectiveAt": {
            "type": "string",
            "description": "The as-of timestamp the `effective` row was resolved for"
          },
          "effective": {
            "allOf": [
              { "$ref": "#/components/schemas/CogsRuleRow" },
              {
                "type": ["object", "null"],
                "description": "Rule effective at `effectiveAt` (null = none)"
              }
            ]
          },
          "current": {
            "allOf": [
              { "$ref": "#/components/schemas/CogsRuleRow" },
              {
                "type": ["object", "null"],
                "description": "Open-ended latest rule (null = none active)"
              }
            ]
          },
          "history": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CogsRuleHistoryEntry" },
            "description": "Prior periods, newest first"
          }
        },
        "required": ["scope", "effectiveAt", "effective", "current", "history"]
      },
      "CogsRulesListResponse": {
        "type": "object",
        "properties": {
          "scopes": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CogsRuleScopeView" }
          },
          "totalCount": { "type": "number" },
          "limit": { "type": "number" },
          "offset": { "type": "number" }
        },
        "required": ["scopes", "totalCount", "limit", "offset"]
      },
      "AdsCampaignResult": {
        "type": "object",
        "properties": {
          "campaign_id": {
            "type": "string",
            "description": "Platform ad campaign ID"
          },
          "channel": {
            "type": "string",
            "enum": ["meta-ads", "google-ads"],
            "description": "Ad channel — only Meta and Google Ads support writes."
          },
          "name": { "type": "string", "description": "Campaign name" },
          "active": {
            "type": "boolean",
            "description": "Whether the campaign is active after the update"
          },
          "budget": {
            "type": "number",
            "description": "Daily budget after the update (budget writes only)"
          },
          "budget_currency": {
            "type": ["string", "null"],
            "description": "ISO 4217 currency the `budget` value is expressed in — the ad account currency, NOT the shop currency in response metadata. Budget writes only."
          }
        },
        "required": ["campaign_id", "channel", "name", "active"]
      },
      "AdsAdSetResult": {
        "type": "object",
        "properties": {
          "ad_set_id": {
            "type": "string",
            "description": "Platform ad set (ad group) ID"
          },
          "channel": {
            "type": "string",
            "enum": ["meta-ads", "google-ads"],
            "description": "Ad channel — only Meta and Google Ads support writes."
          },
          "name": { "type": "string", "description": "Ad set name" },
          "active": {
            "type": "boolean",
            "description": "Whether the ad set is active after the update"
          },
          "budget": {
            "type": "number",
            "description": "Daily budget after the update (budget writes only)"
          },
          "budget_currency": {
            "type": ["string", "null"],
            "description": "ISO 4217 currency the `budget` value is expressed in — the ad account currency, NOT the shop currency in response metadata. Budget writes only."
          }
        },
        "required": ["ad_set_id", "channel", "name", "active"]
      },
      "AdsAdResult": {
        "type": "object",
        "properties": {
          "ad_id": { "type": "string", "description": "Platform ad ID" },
          "channel": {
            "type": "string",
            "enum": ["meta-ads", "google-ads"],
            "description": "Ad channel — only Meta and Google Ads support writes."
          },
          "name": { "type": "string", "description": "Ad name" },
          "active": {
            "type": "boolean",
            "description": "Whether the ad is active after the update"
          }
        },
        "required": ["ad_id", "channel", "name", "active"]
      },
      "HealthResponseData": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": ["ok"],
            "description": "Service health status"
          },
          "version": { "type": "string", "description": "API version" },
          "service": { "type": "string", "description": "Service identifier" }
        },
        "required": ["status", "version", "service"]
      },
      "CostCogsRulesListQuery": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Filter to one product scope (at most one of product_id / variant_id)",
            "example": 10592895992072
          },
          "variant_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Filter to one variant scope (at most one of product_id / variant_id)",
            "example": 52778432299272
          },
          "sku": {
            "type": "string",
            "minLength": 1,
            "description": "Filter by merchant SKU (at most one of product_id / variant_id / sku) — resolved to one variant; an ambiguous SKU is rejected with the candidate variant ids"
          },
          "as_of": {
            "anyOf": [
              { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
              { "type": "string", "format": "date-time" }
            ],
            "description": "Resolve the effective rule at this historical point",
            "example": "2026-01-01"
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 100,
            "default": 50,
            "description": "Page size. Default 50."
          },
          "offset": {
            "type": ["integer", "null"],
            "minimum": 0,
            "default": 0,
            "description": "Page offset. Default 0."
          }
        },
        "additionalProperties": false
      },
      "CostCogsRuleCreateBody": {
        "type": "object",
        "properties": {
          "mode": {
            "type": "string",
            "enum": ["shopify", "constant", "percent"],
            "description": "Cost mode: shopify (use Shopify cost), constant (absolute), percent of price"
          },
          "value": {
            "type": "number",
            "minimum": 0,
            "description": "Cost value. Required for constant (>=0) and percent (0-100); omit for shopify."
          },
          "basis": {
            "type": "string",
            "enum": ["selling"],
            "description": "Percent basis — only 'selling'"
          },
          "recover_on_return": {
            "type": ["boolean", "null"],
            "description": "Override charge-COGS-on-returns for this rule; null/omit inherits global"
          },
          "product_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Product scope"
          },
          "variant_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Variant scope"
          },
          "sku": {
            "type": "string",
            "minLength": 1,
            "description": "Merchant SKU of the target variant (set exactly one of product_id / variant_id / sku). Resolved to one variant id; an ambiguous SKU is rejected with the candidate ids."
          }
        },
        "required": ["mode"]
      },
      "CostCogsHistoryOp": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": ["delete"],
                "description": "Remove one history row"
              },
              "id": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "description": "COGS rule (SCD row) id to delete"
              }
            },
            "required": ["kind", "id"]
          },
          {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": ["update"],
                "description": "Edit one history row"
              },
              "id": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "description": "COGS rule (SCD row) id to update"
              },
              "effective_to": {
                "anyOf": [
                  { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
                  { "type": "string", "format": "date-time" }
                ],
                "description": "When this row's period ends"
              },
              "mode": {
                "type": "string",
                "enum": ["shopify", "constant", "percent"],
                "description": "Cost mode of this period: shopify | constant | percent"
              },
              "value": {
                "type": "number",
                "minimum": 0,
                "description": "Cost value. Required for constant (>=0) and percent (0-100); omit for shopify."
              },
              "basis": {
                "type": "string",
                "enum": ["selling"],
                "description": "Percent basis — only 'selling'"
              },
              "recover_on_return": {
                "type": ["boolean", "null"],
                "description": "Override charge-COGS-on-returns; null/omit inherits global"
              }
            },
            "required": ["kind", "id", "effective_to", "mode"]
          },
          {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": ["add"],
                "description": "Insert a new past period"
              },
              "effective_to": {
                "anyOf": [
                  { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
                  { "type": "string", "format": "date-time" }
                ],
                "description": "When this row's period ends"
              },
              "mode": {
                "type": "string",
                "enum": ["shopify", "constant", "percent"],
                "description": "Cost mode of this period: shopify | constant | percent"
              },
              "value": {
                "type": "number",
                "minimum": 0,
                "description": "Cost value. Required for constant (>=0) and percent (0-100); omit for shopify."
              },
              "basis": {
                "type": "string",
                "enum": ["selling"],
                "description": "Percent basis — only 'selling'"
              },
              "recover_on_return": {
                "type": ["boolean", "null"],
                "description": "Override charge-COGS-on-returns; null/omit inherits global"
              }
            },
            "required": ["kind", "effective_to", "mode"]
          }
        ]
      },
      "CostCogsRulesOpsBody": {
        "type": "object",
        "properties": {
          "product_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Product scope"
          },
          "variant_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Variant scope"
          },
          "ops": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/CostCogsHistoryOp" },
            "maxItems": 20,
            "description": "Diff operations against the scope’s history (max 20 per call)"
          }
        },
        "required": ["ops"]
      },
      "CostCogsGlobalPutBody": {
        "type": "object",
        "properties": {
          "fallback_percent": {
            "type": ["number", "null"],
            "minimum": 0,
            "maximum": 100,
            "description": "Fallback COGS as % of price when no rule/variant cost resolves; null disables"
          },
          "fallback_basis": {
            "type": "string",
            "enum": ["selling"],
            "description": "Price the fallback percent applies to — 'selling'"
          },
          "charge_cogs_on_returns": {
            "type": "boolean",
            "description": "Whether returned items still incur COGS by default"
          }
        },
        "required": [
          "fallback_percent",
          "fallback_basis",
          "charge_cogs_on_returns"
        ]
      },
      "CostPaymentGatewaysListQuery": {
        "type": "object",
        "properties": {
          "history": {
            "anyOf": [
              { "type": "string", "enum": ["1"] },
              { "type": "string", "enum": ["true"] }
            ],
            "description": "Return the full fee history instead of only the active rows"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "Filter to one gateway by name"
          }
        },
        "additionalProperties": false
      },
      "CostPaymentGatewayUpsertBody": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Id of any existing row in the gateway’s (shop, name) chain"
          },
          "cost": {
            "type": ["number", "null"],
            "minimum": 0,
            "description": "Fixed fee per transaction in the shop currency (e.g. 0.35), NOT a percent; or null"
          },
          "fee": {
            "type": ["number", "null"],
            "minimum": 0,
            "description": "Percent fee 0-100 (e.g. 2.99 = 2.99%), NOT a fixed amount; or null"
          },
          "effective_at": {
            "anyOf": [
              { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
              { "type": "string", "format": "date-time" }
            ],
            "description": "Omit to supersede the active row now; supply to period-split at this date"
          }
        },
        "required": ["id", "cost", "fee"]
      },
      "CostPaymentGatewayHistoryOp": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": ["delete"],
                "description": "Remove one history row"
              },
              "id": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "description": "Fee row id to delete"
              }
            },
            "required": ["kind", "id"]
          },
          {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": ["update"],
                "description": "Edit one history row"
              },
              "id": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "description": "Fee row id to update"
              },
              "effective_to": {
                "anyOf": [
                  { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
                  { "type": "string", "format": "date-time" },
                  { "type": "string", "enum": ["infinity"] }
                ],
                "description": "When this row's period ends; the literal 'infinity' marks the active row"
              },
              "cost": {
                "type": ["number", "null"],
                "minimum": 0,
                "description": "Fixed fee per transaction in the shop currency (e.g. 0.35), NOT a percent; or null"
              },
              "fee": {
                "type": ["number", "null"],
                "minimum": 0,
                "description": "Percent fee 0-100 (e.g. 2.99 = 2.99%), NOT a fixed amount; or null"
              }
            },
            "required": ["kind", "id", "effective_to", "cost", "fee"]
          },
          {
            "type": "object",
            "properties": {
              "kind": {
                "type": "string",
                "enum": ["add"],
                "description": "Insert a new period"
              },
              "effective_to": {
                "anyOf": [
                  { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
                  { "type": "string", "format": "date-time" },
                  { "type": "string", "enum": ["infinity"] }
                ],
                "description": "When this row's period ends; the literal 'infinity' marks the active row"
              },
              "cost": {
                "type": ["number", "null"],
                "minimum": 0,
                "description": "Fixed fee per transaction in the shop currency (e.g. 0.35), NOT a percent; or null"
              },
              "fee": {
                "type": ["number", "null"],
                "minimum": 0,
                "description": "Percent fee 0-100 (e.g. 2.99 = 2.99%), NOT a fixed amount; or null"
              }
            },
            "required": ["kind", "effective_to", "cost", "fee"]
          }
        ]
      },
      "CostPaymentGatewayOpsBody": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "Gateway name (the (shop, name) chain to edit)"
          },
          "ops": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CostPaymentGatewayHistoryOp"
            },
            "maxItems": 20,
            "description": "Diff operations against the gateway’s fee history (max 20 per call)"
          }
        },
        "required": ["name", "ops"]
      },
      "CostShippingProfileUpsertBody": {
        "type": "object",
        "properties": {
          "profile": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[1-9]\\d*$",
                "description": "Existing profile id to update; omit to create. Never matched by name or scope."
              },
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120,
                "description": "Unique name within the shop. Changing it does not bypass scope conflicts."
              },
              "is_default": {
                "type": "boolean",
                "description": "The default profile is a pure catch-all (no scoping)"
              },
              "country_codes": {
                "type": "array",
                "items": { "type": "string", "minLength": 2, "maxLength": 2 },
                "description": "ISO 3166-1 alpha-2 codes; [] matches every country"
              },
              "shipping_methods": {
                "type": "array",
                "items": { "type": "string", "minLength": 1, "maxLength": 80 },
                "description": "[] (recommended default) applies to all current and future shipping methods. For differentiated pricing call GET /v1/cost/shipping-methods first and copy titles byte-for-byte."
              },
              "products": {
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "object",
                      "properties": {
                        "kind": { "type": "string", "enum": ["product"] },
                        "id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "description": "Shopify product id"
                        },
                        "label": { "type": "string" }
                      },
                      "required": ["kind", "id"]
                    },
                    {
                      "type": "object",
                      "properties": {
                        "kind": { "type": "string", "enum": ["variant"] },
                        "id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "description": "Shopify variant id"
                        },
                        "product_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "description": "Parent product id"
                        },
                        "label": { "type": "string" }
                      },
                      "required": ["kind", "id"]
                    }
                  ]
                },
                "description": "[] matches every product. A product includes all its variants; overlapping product/variant scopes conflict when countries and methods also overlap."
              },
              "currency": { "type": "string", "minLength": 1, "maxLength": 8 },
              "fees": {
                "type": "object",
                "properties": {
                  "packaging_fee": { "type": "number", "minimum": 0 },
                  "picking_first_item_fee": { "type": "number", "minimum": 0 },
                  "picking_following_items_fee": {
                    "type": "number",
                    "minimum": 0
                  },
                  "other_per_item_fee": { "type": "number", "minimum": 0 },
                  "per_item_return_fee": { "type": "number", "minimum": 0 },
                  "per_order": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": ["flat"],
                            "description": "Single flat cost for the axis"
                          },
                          "value": {
                            "type": "number",
                            "minimum": 0,
                            "description": "Flat cost"
                          }
                        },
                        "required": ["type", "value"]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": ["weight"],
                            "description": "Weight-graduated buckets"
                          },
                          "weight_display_unit": {
                            "type": "string",
                            "enum": ["g", "kg", "lbs", "oz"]
                          },
                          "buckets": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "max_value": {
                                  "type": ["integer", "null"],
                                  "exclusiveMinimum": 0,
                                  "description": "Upper bound of this bucket (in weight_display_unit for weight sets, item count for item sets). null = open-ended (∞), allowed only on the LAST bucket."
                                },
                                "cost": {
                                  "type": "number",
                                  "minimum": 0,
                                  "description": "Shipping cost for this bucket"
                                }
                              },
                              "required": ["max_value", "cost"]
                            },
                            "minItems": 1,
                            "maxItems": 50
                          }
                        },
                        "required": ["type", "weight_display_unit", "buckets"]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": ["item"],
                            "description": "Item-count-graduated buckets"
                          },
                          "buckets": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "max_value": {
                                  "type": ["integer", "null"],
                                  "exclusiveMinimum": 0,
                                  "description": "Upper bound of this bucket (in weight_display_unit for weight sets, item count for item sets). null = open-ended (∞), allowed only on the LAST bucket."
                                },
                                "cost": {
                                  "type": "number",
                                  "minimum": 0,
                                  "description": "Shipping cost for this bucket"
                                }
                              },
                              "required": ["max_value", "cost"]
                            },
                            "minItems": 1,
                            "maxItems": 50
                          }
                        },
                        "required": ["type", "buckets"]
                      }
                    ],
                    "description": "Ascending buckets; finite max_value boundaries must strictly increase and the LAST bucket must be open-ended (max_value: null)."
                  },
                  "per_order_return": {
                    "anyOf": [
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": ["flat"],
                            "description": "Single flat cost for the axis"
                          },
                          "value": {
                            "type": "number",
                            "minimum": 0,
                            "description": "Flat cost"
                          }
                        },
                        "required": ["type", "value"]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": ["weight"],
                            "description": "Weight-graduated buckets"
                          },
                          "weight_display_unit": {
                            "type": "string",
                            "enum": ["g", "kg", "lbs", "oz"]
                          },
                          "buckets": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "max_value": {
                                  "type": ["integer", "null"],
                                  "exclusiveMinimum": 0,
                                  "description": "Upper bound of this bucket (in weight_display_unit for weight sets, item count for item sets). null = open-ended (∞), allowed only on the LAST bucket."
                                },
                                "cost": {
                                  "type": "number",
                                  "minimum": 0,
                                  "description": "Shipping cost for this bucket"
                                }
                              },
                              "required": ["max_value", "cost"]
                            },
                            "minItems": 1,
                            "maxItems": 50
                          }
                        },
                        "required": ["type", "weight_display_unit", "buckets"]
                      },
                      {
                        "type": "object",
                        "properties": {
                          "type": {
                            "type": "string",
                            "enum": ["item"],
                            "description": "Item-count-graduated buckets"
                          },
                          "buckets": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "max_value": {
                                  "type": ["integer", "null"],
                                  "exclusiveMinimum": 0,
                                  "description": "Upper bound of this bucket (in weight_display_unit for weight sets, item count for item sets). null = open-ended (∞), allowed only on the LAST bucket."
                                },
                                "cost": {
                                  "type": "number",
                                  "minimum": 0,
                                  "description": "Shipping cost for this bucket"
                                }
                              },
                              "required": ["max_value", "cost"]
                            },
                            "minItems": 1,
                            "maxItems": 50
                          }
                        },
                        "required": ["type", "buckets"]
                      }
                    ],
                    "description": "Ascending buckets; finite max_value boundaries must strictly increase and the LAST bucket must be open-ended (max_value: null)."
                  }
                },
                "description": "On CREATE omitted chains seed at 0; on UPDATE scalars overwrite the active value and a provided axis payload REPLACES that axis (resets its history)."
              }
            },
            "required": [
              "name",
              "is_default",
              "country_codes",
              "shipping_methods",
              "products",
              "currency"
            ],
            "description": "Shipping-profile scope uniqueness is independent of the profile name. Two non-default profiles conflict when their countries, shipping methods AND products/variants all overlap. An empty array matches every value on that dimension. Any intersecting combination is enough; the complete lists do not need to be equal. A product includes all its variants, so a product profile and one of its variant profiles conflict when country and method scopes also overlap. Distinct variants of the same product can coexist. The catch-all default is excluded from this overlap check; other profiles must narrow at least one dimension. Provide the existing profile id to update; omit it to create. The server never finds an update target by name or matching scope. Updates exclude their own id from conflict detection but still check every other non-default profile in the shop. Names must be unique within the shop and there can be only one default; is_default cannot be changed on an existing profile. Upsert requires the complete identity/scope fields. Omit fees to preserve all costs and history. Provided scalar fees overwrite current values while preserving history; a provided per_order or per_order_return axis REPLACES that axis and resets its history, including for flat axes."
          }
        },
        "required": ["profile"]
      },
      "CostBulkSetPaymentFeesBody": {
        "type": "object",
        "properties": {
          "gateways": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CostPaymentGatewayUpsertBody"
            },
            "minItems": 1,
            "maxItems": 50,
            "description": "Payment-gateway upserts to apply (one upsert each)"
          },
          "dry_run": {
            "type": "boolean",
            "default": false,
            "description": "When true, validate + plan only; performs NO write"
          }
        },
        "required": ["gateways"]
      },
      "CogsBulkReadBody": {
        "type": "object",
        "properties": {
          "targets": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "product_id": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991
                },
                "variant_id": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "additionalProperties": false,
              "description": "Exactly one of product_id or variant_id, as a safe positive integer"
            },
            "minItems": 1,
            "maxItems": 100
          },
          "as_of": {
            "anyOf": [
              { "type": "string", "format": "date" },
              { "type": "string", "format": "date-time" }
            ],
            "description": "Shop-local YYYY-MM-DD day or ISO instant converted to the shop timezone"
          }
        },
        "required": ["targets"],
        "additionalProperties": false
      },
      "CogsBulkWriteBody": {
        "type": "object",
        "properties": {
          "entries": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "mode": {
                  "type": "string",
                  "enum": ["shopify", "constant", "percent"],
                  "description": "Cost mode: shopify (use Shopify cost), constant (absolute), percent of price"
                },
                "value": {
                  "type": "number",
                  "minimum": 0,
                  "description": "Cost value. Required for constant (>=0) and percent (0-100); omit for shopify."
                },
                "basis": {
                  "type": "string",
                  "enum": ["selling"],
                  "description": "Percent basis — only 'selling'"
                },
                "recover_on_return": {
                  "type": ["boolean", "null"],
                  "description": "Override charge-COGS-on-returns for this rule; null/omit inherits global"
                },
                "product_id": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991
                },
                "variant_id": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991
                }
              },
              "required": ["mode"],
              "additionalProperties": false
            },
            "minItems": 1,
            "maxItems": 100
          },
          "dry_run": { "type": "boolean", "default": false }
        },
        "required": ["entries"],
        "additionalProperties": false
      },
      "CogsBulkReadResult": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "type": "object",
                  "properties": {
                    "index": { "type": "integer", "minimum": 0 },
                    "target": {
                      "type": "object",
                      "properties": {
                        "product_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        },
                        "variant_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "additionalProperties": false,
                      "description": "Exactly one of product_id or variant_id, as a safe positive integer"
                    },
                    "success": { "type": "boolean", "enum": [true] },
                    "data": { "$ref": "#/components/schemas/CogsRuleScopeView" }
                  },
                  "required": ["index", "target", "success", "data"]
                },
                {
                  "type": "object",
                  "properties": {
                    "index": { "type": "integer", "minimum": 0 },
                    "target": {
                      "type": "object",
                      "properties": {
                        "product_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        },
                        "variant_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "additionalProperties": false,
                      "description": "Exactly one of product_id or variant_id, as a safe positive integer"
                    },
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": { "type": "string", "enum": ["NOT_FOUND"] },
                        "message": {
                          "type": "string",
                          "enum": ["Product or variant not found"]
                        }
                      },
                      "required": ["code", "message"]
                    }
                  },
                  "required": ["index", "target", "success", "error"]
                }
              ]
            }
          }
        },
        "required": ["results"]
      },
      "CogsBulkWriteResult": {
        "type": "object",
        "properties": {
          "dry_run": { "type": "boolean" },
          "planned": {
            "type": "integer",
            "description": "Requested entry count"
          },
          "valid": {
            "type": "integer",
            "description": "Valid preview entries, or confirmed successful writes for a real batch"
          },
          "applied": {
            "type": "integer",
            "description": "Confirmed successful writes; always zero for a dry run"
          },
          "failed": {
            "type": "integer",
            "description": "Failed or uncertain outcomes; uncertain entries may have persisted"
          },
          "results": {
            "type": "array",
            "items": {
              "anyOf": [
                {
                  "type": "object",
                  "properties": {
                    "index": { "type": "integer", "minimum": 0 },
                    "target": {
                      "type": "object",
                      "properties": {
                        "product_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        },
                        "variant_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "additionalProperties": false,
                      "description": "Exactly one of product_id or variant_id, as a safe positive integer"
                    },
                    "success": { "type": "boolean", "enum": [true] },
                    "history_reset": { "type": "boolean" }
                  },
                  "required": ["index", "target", "success", "history_reset"]
                },
                {
                  "type": "object",
                  "properties": {
                    "index": { "type": "integer", "minimum": 0 },
                    "target": {
                      "type": "object",
                      "properties": {
                        "product_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        },
                        "variant_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "additionalProperties": false,
                      "description": "Exactly one of product_id or variant_id, as a safe positive integer"
                    },
                    "success": { "type": "boolean", "enum": [true] }
                  },
                  "required": ["index", "target", "success"]
                },
                {
                  "type": "object",
                  "properties": {
                    "index": { "type": "integer", "minimum": 0 },
                    "target": {
                      "type": "object",
                      "properties": {
                        "product_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        },
                        "variant_id": {
                          "type": "integer",
                          "exclusiveMinimum": 0,
                          "maximum": 9007199254740991
                        }
                      },
                      "additionalProperties": false,
                      "description": "Exactly one of product_id or variant_id, as a safe positive integer"
                    },
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": [
                            "NOT_FOUND",
                            "CONFLICT",
                            "INVALID_RULE",
                            "WRITE_UNCERTAIN"
                          ]
                        },
                        "message": { "type": "string" },
                        "requires_reread": {
                          "type": "boolean",
                          "description": "Re-read this target before retrying; never replay the whole batch"
                        }
                      },
                      "required": ["code", "message", "requires_reread"]
                    }
                  },
                  "required": ["index", "target", "success", "error"]
                }
              ]
            }
          }
        },
        "required": [
          "dry_run",
          "planned",
          "valid",
          "applied",
          "failed",
          "results"
        ]
      },
      "ShippingProfileSummary": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Profile id; pass as a string for upsert, as a number for MCP reads/tiers/history"
          },
          "name": { "type": "string" },
          "isDefault": {
            "type": "boolean",
            "description": "Catch-all fallback profile, excluded from non-default overlap checks"
          },
          "countryCodes": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Country scope; [] matches every country"
          },
          "shippingMethods": {
            "type": "array",
            "items": { "type": "string" },
            "description": "Exact method titles; [] matches every method"
          },
          "products": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "type": "object",
                  "properties": {
                    "kind": { "type": "string", "enum": ["product"] },
                    "id": { "type": "integer", "exclusiveMinimum": 0 },
                    "label": { "type": "string" }
                  },
                  "required": ["kind", "id", "label"]
                },
                {
                  "type": "object",
                  "properties": {
                    "kind": { "type": "string", "enum": ["variant"] },
                    "id": { "type": "integer", "exclusiveMinimum": 0 },
                    "productId": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Parent product id; 0 means the parent could not be resolved"
                    },
                    "label": { "type": "string" }
                  },
                  "required": ["kind", "id", "productId", "label"]
                }
              ]
            },
            "description": "Product/variant scope; [] matches every product. A product includes its variants."
          },
          "currency": {
            "type": "string",
            "description": "Currency for all fees on this profile"
          }
        },
        "required": [
          "id",
          "name",
          "isDefault",
          "countryCodes",
          "shippingMethods",
          "products",
          "currency"
        ]
      },
      "ShippingTimedValue": {
        "type": "object",
        "properties": {
          "current": {
            "type": "number",
            "description": "Current fee amount in the profile currency"
          },
          "currentId": {
            "type": ["integer", "null"],
            "exclusiveMinimum": 0,
            "description": "Active fee-row id"
          },
          "history": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Historical fee-row id"
                },
                "effectiveFrom": {
                  "type": "string",
                  "description": "Legacy field name: exclusive END of this historical value, when the next value took over (YYYY-MM-DD)"
                },
                "value": {
                  "type": "number",
                  "description": "Fee amount before the effectiveFrom boundary"
                }
              },
              "required": ["id", "effectiveFrom", "value"]
            },
            "description": "Historical values ordered by end boundary, newest first"
          }
        },
        "required": ["current", "currentId", "history"]
      },
      "ShippingBucket": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Bucket id; convert to a number for bucket_id write parameters"
          },
          "max": {
            "type": ["number", "null"],
            "description": "Upper bound in displayUnit for weight tiers, or item count; null is open-ended"
          },
          "cost": { "$ref": "#/components/schemas/ShippingTimedValue" }
        },
        "required": ["id", "max", "cost"]
      },
      "ShippingAxis": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "enum": ["flat"] },
              "value": { "$ref": "#/components/schemas/ShippingTimedValue" }
            },
            "required": ["type", "value"]
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "enum": ["weight"] },
              "bucketSetId": {
                "type": ["integer", "null"],
                "exclusiveMinimum": 0
              },
              "buckets": {
                "type": "array",
                "items": { "$ref": "#/components/schemas/ShippingBucket" }
              },
              "displayUnit": {
                "type": "string",
                "enum": ["g", "kg", "lbs", "oz"]
              }
            },
            "required": ["type", "bucketSetId", "buckets"]
          },
          {
            "type": "object",
            "properties": {
              "type": { "type": "string", "enum": ["item"] },
              "bucketSetId": {
                "type": ["integer", "null"],
                "exclusiveMinimum": 0
              },
              "buckets": {
                "type": "array",
                "items": { "$ref": "#/components/schemas/ShippingBucket" }
              }
            },
            "required": ["type", "bucketSetId", "buckets"]
          }
        ]
      },
      "ShippingFees": {
        "type": "object",
        "properties": {
          "perOrderShipping": { "$ref": "#/components/schemas/ShippingAxis" },
          "packagingFee": { "$ref": "#/components/schemas/ShippingTimedValue" },
          "pickingFirstItemFee": {
            "$ref": "#/components/schemas/ShippingTimedValue"
          },
          "pickingFollowingItemsFee": {
            "$ref": "#/components/schemas/ShippingTimedValue"
          },
          "otherPerItemFee": {
            "$ref": "#/components/schemas/ShippingTimedValue"
          },
          "perOrderReturnFee": { "$ref": "#/components/schemas/ShippingAxis" },
          "perItemReturnFee": {
            "$ref": "#/components/schemas/ShippingTimedValue"
          }
        },
        "required": [
          "perOrderShipping",
          "packagingFee",
          "pickingFirstItemFee",
          "pickingFollowingItemsFee",
          "otherPerItemFee",
          "perOrderReturnFee",
          "perItemReturnFee"
        ],
        "description": "All scalar fees and axes, including each fee/bucket cost history"
      },
      "ShippingProfile": {
        "allOf": [
          { "$ref": "#/components/schemas/ShippingProfileSummary" },
          {
            "type": "object",
            "properties": {
              "current": { "$ref": "#/components/schemas/ShippingFees" }
            },
            "required": ["current"]
          }
        ]
      },
      "ShippingProfileUpsertResult": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Created or updated profile id; GET the profile for full state"
          }
        },
        "required": ["id"]
      },
      "ShippingTiersPlan": {
        "type": "object",
        "properties": {
          "dry_run": { "type": "boolean", "enum": [true] },
          "applied": { "type": "boolean", "enum": [false] },
          "currency": {
            "type": "string",
            "description": "Profile currency for the planned amounts; may differ from the shop currency"
          },
          "note": {
            "type": "string",
            "description": "Planned effect; a dry run does not reserve state or guarantee a later write succeeds"
          },
          "profile_id": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "description": "Target shipping profile id."
          },
          "axis": {
            "type": "string",
            "enum": ["per_order", "per_order_return"],
            "default": "per_order",
            "description": "Which axis: outbound shipping (per_order) or returns (per_order_return)."
          },
          "type": {
            "type": "string",
            "enum": ["weight", "item"],
            "description": "Tier basis: weight or item count."
          },
          "tiers": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ShippingTier" },
            "minItems": 1,
            "maxItems": 50,
            "description": "Graduated tiers, ascending. Exactly one may be open-ended (up_to:null) and it must be last."
          }
        },
        "required": [
          "dry_run",
          "applied",
          "currency",
          "note",
          "profile_id",
          "type",
          "tiers"
        ]
      },
      "ShippingFeeHistoryPlan": {
        "type": "object",
        "properties": {
          "dry_run": { "type": "boolean", "enum": [true] },
          "applied": { "type": "boolean", "enum": [false] },
          "currency": {
            "type": "string",
            "description": "Profile currency for the planned amounts; may differ from the shop currency"
          },
          "note": {
            "type": "string",
            "description": "Planned effect; a dry run does not reserve state or guarantee a later write succeeds"
          },
          "periods": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/ShippingFeeHistoryPeriod" }
          }
        },
        "required": ["dry_run", "applied", "currency", "note", "periods"]
      },
      "ShippingBucketHistoryPlan": {
        "type": "object",
        "properties": {
          "dry_run": { "type": "boolean", "enum": [true] },
          "applied": { "type": "boolean", "enum": [false] },
          "currency": {
            "type": "string",
            "description": "Profile currency for the planned amounts; may differ from the shop currency"
          },
          "note": {
            "type": "string",
            "description": "Planned effect; a dry run does not reserve state or guarantee a later write succeeds"
          },
          "periods": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ShippingBucketHistoryPeriod"
            }
          }
        },
        "required": ["dry_run", "applied", "currency", "note", "periods"]
      },
      "ShippingCostUpdateResult": {
        "type": "object",
        "properties": {
          "profile_id": { "type": "integer", "exclusiveMinimum": 0 },
          "currency": { "type": "string" },
          "effective_from": { "type": "string", "format": "date" },
          "dry_run": { "type": "boolean" },
          "applied": { "type": "boolean" },
          "revision": {
            "type": "string",
            "description": "Profile revision at preview, or after the committed change."
          },
          "bucket_costs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "bucket_id": { "type": "integer", "exclusiveMinimum": 0 },
                "previous_cost": { "type": "number" },
                "cost": { "type": "number" },
                "effective_until": {
                  "type": ["string", "null"],
                  "format": "date",
                  "description": "Exclusive end: next existing period boundary, or null when open-ended."
                },
                "changed": { "type": "boolean" }
              },
              "required": [
                "bucket_id",
                "previous_cost",
                "cost",
                "effective_until",
                "changed"
              ]
            }
          }
        },
        "required": [
          "profile_id",
          "currency",
          "effective_from",
          "dry_run",
          "applied",
          "revision",
          "bucket_costs"
        ]
      },
      "ShippingCostUpdateBody": {
        "type": "object",
        "properties": {
          "effective_from": {
            "type": "string",
            "format": "date",
            "description": "Inclusive shop-local date (YYYY-MM-DD). Earlier costs and later scheduled periods are preserved."
          },
          "bucket_costs": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "bucket_id": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991,
                  "description": "Existing bucket id from get_shipping_profile; never a history-row id."
                },
                "cost": {
                  "type": "number",
                  "minimum": 0,
                  "description": "New shipping cost in the profile currency."
                }
              },
              "required": ["bucket_id", "cost"],
              "additionalProperties": false
            },
            "minItems": 1,
            "maxItems": 50,
            "description": "Up to 50 distinct existing buckets from this profile. Omitted buckets are unchanged."
          },
          "expected_revision": {
            "type": "string",
            "pattern": "^[a-f0-9]{64}$",
            "description": "Revision returned by a dry run. Required when applying; stale revisions return 409."
          },
          "dry_run": {
            "type": "boolean",
            "default": false,
            "description": "Preview without writing. Returns the revision required to apply the change."
          }
        },
        "required": ["effective_from", "bucket_costs"],
        "additionalProperties": false
      }
    },
    "parameters": {}
  },
  "paths": {
    "/v1/health": {
      "get": {
        "summary": "Health check",
        "description": "Returns the health status of the Public API.\n\n**Authentication:** Not required\n\nThis endpoint can be used for monitoring and uptime checks.\n\nA successful health check confirms this API route responds; it does not validate your API key, connected integrations, or the freshness of analytics data.",
        "tags": ["System"],
        "responses": {
          "200": {
            "description": "Service is healthy",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/HealthResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                },
                "example": {
                  "success": true,
                  "data": {
                    "status": "ok",
                    "version": "v1",
                    "service": "venon-public-api"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/ad-sets": {
      "get": {
        "summary": "Get ad set performance metrics",
        "description": "Returns performance metrics for ad sets within a date range.\n\n**Two modes:**\n- **By-ID** — supply `ad_set_ids` (and `channel`) to get metrics for specific ad sets.\n- **List** — omit `ad_set_ids` to list every ad set with spend or attributed activity in the window. Filter by `channel` (omit for all ad-spend channels), `min_spend`/`max_spend`, `active_in_range`, `status`, and `q`; sort by `sort_by`/`order`; paginate with `page`/`per_page`. List items additionally carry the parent `campaign_id`, `active`, and `budget`; the response includes a `pagination` block and `totals` over the full filtered set.\n\n**Note:** list mode is join-driven over the window — it returns every ad set with **either** ad spend **or** attributed activity (orders/revenue) in the window. Because attribution is keyed on order date and spend on spend date, an ad set can appear with `ad_spend = 0` when it converted in-window from spend that landed outside it; pass `active_in_range=true` to keep only ad sets with spend > 0. Google Ads has no ad-set level, so `/ad-sets` is empty for `google-ads`.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Keep attribution_model and attribution_window identical when comparing channels or drilling down into campaigns, orders and products; changing them changes the credited results. List-mode status is the stored lifecycle state, not historical delivery; active_in_range filters for spend in the requested window. Use pagination to fetch further pages; totals cover the full filtered set, so do not add them again for each page.\n\nfilter_mode applies saved data filters to this report: none (default) applies none, enabled applies the filters currently enabled in the dashboard, selected applies exactly filter_ids (enabled or not) without changing their saved state. filter_ids is required with selected and rejected otherwise; an unknown id fails the request (404), and so does a selected filter whose saved rules are no longer valid (409). Enabled mode skips such a filter and still answers, with a warning (metadata.warnings over REST, warnings over MCP). Shopify filters narrow store orders. An ad channel filter removes the excluded spend and attributed credit of that channel only; the credit is not re-attributed and store orders stay unchanged. Several filters all apply (AND). Response metadata.data_filters names the applied filters.",
        "tags": ["Analytics"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated platform ad set IDs (max 100). Omit for list mode.",
              "example": "123456789,987654321"
            },
            "required": false,
            "description": "Comma-separated platform ad set IDs (max 100). Omit for list mode.",
            "name": "ad_set_ids",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "meta-ads",
                "google-ads",
                "taboola",
                "tiktok-ads",
                "outbrain",
                "microsoft-ads",
                "pinterest-ads"
              ],
              "description": "Ad channel identifier. Omit to span all ad-spend channels.",
              "example": "meta-ads"
            },
            "required": false,
            "description": "Ad channel identifier. Omit to span all ad-spend channels.",
            "name": "channel",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "linear_paid",
                "linear_all",
                "first_click",
                "last_click",
                "last_paid_click",
                "all_clicks"
              ],
              "default": "last_paid_click",
              "description": "Attribution model",
              "example": "linear_paid"
            },
            "required": false,
            "description": "Attribution model",
            "name": "attribution_model",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "1_day",
                "7_day",
                "14_day",
                "28_day",
                "90_day",
                "lifetime"
              ],
              "default": "lifetime",
              "description": "Attribution window",
              "example": "28_day"
            },
            "required": false,
            "description": "Attribution window",
            "name": "attribution_window",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["none", "enabled", "selected"],
              "description": "Saved data filters to apply: none (default), enabled or selected",
              "example": "selected"
            },
            "required": false,
            "description": "Saved data filters to apply: none (default), enabled or selected",
            "name": "filter_mode",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": false,
            "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
            "name": "filter_ids",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["creative_metrics"],
              "description": "creative_metrics adds Meta creative metrics to meta-ads items."
            },
            "required": false,
            "description": "creative_metrics adds Meta creative metrics to meta-ads items.",
            "name": "include",
            "in": "query"
          },
          {
            "schema": {
              "type": ["number", "null"],
              "minimum": 0,
              "description": "Filter: minimum ad_spend in the window (inclusive)",
              "example": 100
            },
            "required": false,
            "description": "Filter: minimum ad_spend in the window (inclusive)",
            "name": "min_spend",
            "in": "query"
          },
          {
            "schema": {
              "type": ["number", "null"],
              "minimum": 0,
              "description": "Filter: maximum ad_spend in the window (inclusive)",
              "example": 5000
            },
            "required": false,
            "description": "Filter: maximum ad_spend in the window (inclusive)",
            "name": "max_spend",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["true", "false"],
              "description": "Filter: keep only entities with ad_spend > 0 in the window (\"active in time range\")"
            },
            "required": false,
            "description": "Filter: keep only entities with ad_spend > 0 in the window (\"active in time range\")",
            "name": "active_in_range",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["active", "paused", "all"],
              "default": "all",
              "description": "Filter on the platform lifecycle flag (time-independent). Default `all`."
            },
            "required": false,
            "description": "Filter on the platform lifecycle flag (time-independent). Default `all`.",
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Case-insensitive substring match on the entity name"
            },
            "required": false,
            "description": "Case-insensitive substring match on the entity name",
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "ad_spend",
                "name",
                "attributed_revenue",
                "roas",
                "attributed_orders"
              ],
              "default": "ad_spend",
              "description": "List-mode sort field. Default `ad_spend`."
            },
            "required": false,
            "description": "List-mode sort field. Default `ad_spend`.",
            "name": "sort_by",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc",
              "description": "List-mode sort order. Default `desc`."
            },
            "required": false,
            "description": "List-mode sort order. Default `desc`.",
            "name": "order",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "default": 1,
              "description": "List-mode page number. Default 1."
            },
            "required": false,
            "description": "List-mode page number. Default 1.",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50,
              "description": "List-mode items per page (max 100). Default 50."
            },
            "required": false,
            "description": "List-mode items per page (max 100). Default 50.",
            "name": "per_page",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Ad set performance data retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/AdSetPerformanceResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Invalid or missing API key"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks required scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "API key does not have required scope: analytics:read"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found - a filter_ids entry is not a saved data filter of this shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "Conflict - a filter_ids entry has saved rules that are no longer valid",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              },
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "description": "Number of seconds to wait before making another request",
                  "example": 45
                },
                "required": true
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer",
                  "description": "Maximum requests allowed per window",
                  "example": 60
                },
                "required": true
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer",
                  "description": "Requests remaining in current window",
                  "example": 0
                },
                "required": true
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer",
                  "description": "Unix timestamp when the rate limit window resets",
                  "example": 1713182400
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Please wait before making more requests."
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/ads": {
      "get": {
        "summary": "Get ad performance metrics",
        "description": "Returns performance metrics for ads (creative-level) within a date range.\n\n**Two modes:**\n- **By-ID** — supply `ad_ids` (and `channel`) to get metrics for specific ads.\n- **List** — omit `ad_ids` to list every ad with spend or attributed activity in the window. Filter by `channel` (omit for all ad-spend channels), `min_spend`/`max_spend`, `active_in_range`, `status`, and `q`; sort by `sort_by`/`order`; paginate with `page`/`per_page`. List items additionally carry the parent `campaign_id` and `ad_set_id` plus `active`; the response includes a `pagination` block and `totals` over the full filtered set.\n\n**Note:** list mode is join-driven over the window — it returns every ad with **either** ad spend **or** attributed activity (orders/revenue) in the window. Because attribution is keyed on order date and spend on spend date, an ad can appear with `ad_spend = 0` when it converted in-window from spend that landed outside it; pass `active_in_range=true` to keep only ads with spend > 0.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Keep attribution_model and attribution_window identical when comparing channels or drilling down into campaigns, orders and products; changing them changes the credited results. List-mode status is the stored lifecycle state, not historical delivery; active_in_range filters for spend in the requested window. Use pagination to fetch further pages; totals cover the full filtered set, so do not add them again for each page.\n\nfilter_mode applies saved data filters to this report: none (default) applies none, enabled applies the filters currently enabled in the dashboard, selected applies exactly filter_ids (enabled or not) without changing their saved state. filter_ids is required with selected and rejected otherwise; an unknown id fails the request (404), and so does a selected filter whose saved rules are no longer valid (409). Enabled mode skips such a filter and still answers, with a warning (metadata.warnings over REST, warnings over MCP). Shopify filters narrow store orders. An ad channel filter removes the excluded spend and attributed credit of that channel only; the credit is not re-attributed and store orders stay unchanged. Several filters all apply (AND). Response metadata.data_filters names the applied filters.",
        "tags": ["Analytics"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated platform ad IDs (max 100). Omit for list mode.",
              "example": "23849574938,23849574939"
            },
            "required": false,
            "description": "Comma-separated platform ad IDs (max 100). Omit for list mode.",
            "name": "ad_ids",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "meta-ads",
                "google-ads",
                "taboola",
                "tiktok-ads",
                "outbrain",
                "microsoft-ads",
                "pinterest-ads"
              ],
              "description": "Ad channel identifier. Omit to span all ad-spend channels.",
              "example": "google-ads"
            },
            "required": false,
            "description": "Ad channel identifier. Omit to span all ad-spend channels.",
            "name": "channel",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "linear_paid",
                "linear_all",
                "first_click",
                "last_click",
                "last_paid_click",
                "all_clicks"
              ],
              "default": "last_paid_click",
              "description": "Attribution model",
              "example": "linear_paid"
            },
            "required": false,
            "description": "Attribution model",
            "name": "attribution_model",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "1_day",
                "7_day",
                "14_day",
                "28_day",
                "90_day",
                "lifetime"
              ],
              "default": "lifetime",
              "description": "Attribution window",
              "example": "28_day"
            },
            "required": false,
            "description": "Attribution window",
            "name": "attribution_window",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["none", "enabled", "selected"],
              "description": "Saved data filters to apply: none (default), enabled or selected",
              "example": "selected"
            },
            "required": false,
            "description": "Saved data filters to apply: none (default), enabled or selected",
            "name": "filter_mode",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": false,
            "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
            "name": "filter_ids",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["creative_metrics"],
              "description": "creative_metrics adds Meta creative metrics to meta-ads items."
            },
            "required": false,
            "description": "creative_metrics adds Meta creative metrics to meta-ads items.",
            "name": "include",
            "in": "query"
          },
          {
            "schema": {
              "type": ["number", "null"],
              "minimum": 0,
              "description": "Filter: minimum ad_spend in the window (inclusive)",
              "example": 100
            },
            "required": false,
            "description": "Filter: minimum ad_spend in the window (inclusive)",
            "name": "min_spend",
            "in": "query"
          },
          {
            "schema": {
              "type": ["number", "null"],
              "minimum": 0,
              "description": "Filter: maximum ad_spend in the window (inclusive)",
              "example": 5000
            },
            "required": false,
            "description": "Filter: maximum ad_spend in the window (inclusive)",
            "name": "max_spend",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["true", "false"],
              "description": "Filter: keep only entities with ad_spend > 0 in the window (\"active in time range\")"
            },
            "required": false,
            "description": "Filter: keep only entities with ad_spend > 0 in the window (\"active in time range\")",
            "name": "active_in_range",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["active", "paused", "all"],
              "default": "all",
              "description": "Filter on the platform lifecycle flag (time-independent). Default `all`."
            },
            "required": false,
            "description": "Filter on the platform lifecycle flag (time-independent). Default `all`.",
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Case-insensitive substring match on the entity name"
            },
            "required": false,
            "description": "Case-insensitive substring match on the entity name",
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "ad_spend",
                "name",
                "attributed_revenue",
                "roas",
                "attributed_orders"
              ],
              "default": "ad_spend",
              "description": "List-mode sort field. Default `ad_spend`."
            },
            "required": false,
            "description": "List-mode sort field. Default `ad_spend`.",
            "name": "sort_by",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc",
              "description": "List-mode sort order. Default `desc`."
            },
            "required": false,
            "description": "List-mode sort order. Default `desc`.",
            "name": "order",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "default": 1,
              "description": "List-mode page number. Default 1."
            },
            "required": false,
            "description": "List-mode page number. Default 1.",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50,
              "description": "List-mode items per page (max 100). Default 50."
            },
            "required": false,
            "description": "List-mode items per page (max 100). Default 50.",
            "name": "per_page",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Ad performance data retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/AdPerformanceResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Invalid or missing API key"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks required scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "API key does not have required scope: analytics:read"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found - a filter_ids entry is not a saved data filter of this shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "Conflict - a filter_ids entry has saved rules that are no longer valid",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              },
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "description": "Number of seconds to wait before making another request",
                  "example": 45
                },
                "required": true
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer",
                  "description": "Maximum requests allowed per window",
                  "example": 60
                },
                "required": true
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer",
                  "description": "Requests remaining in current window",
                  "example": 0
                },
                "required": true
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer",
                  "description": "Unix timestamp when the rate limit window resets",
                  "example": 1713182400
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Please wait before making more requests."
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/campaigns": {
      "get": {
        "summary": "Get campaign performance metrics",
        "description": "Returns performance metrics for campaigns within a date range.\n\n**Two modes:**\n- **By-ID** — supply `campaign_ids` (and `channel`) to get metrics for specific campaigns.\n- **List** — omit `campaign_ids` to list every campaign with spend or attributed activity in the window. Filter by `channel` (omit for all ad-spend channels), `min_spend`/`max_spend`, `active_in_range`, `status`, and `q`; sort by `sort_by`/`order`; paginate with `page`/`per_page`. List items additionally carry `active` and `budget`; the response includes a `pagination` block and `totals` over the full filtered set.\n\n**Note:** list mode is join-driven over the window — it returns every campaign with **either** ad spend **or** attributed activity (orders/revenue) in the window. Because attribution is keyed on order date and spend on spend date, a campaign can appear with `ad_spend = 0` when it converted in-window from spend that landed outside it; pass `active_in_range=true` to keep only campaigns with spend > 0.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Keep attribution_model and attribution_window identical when comparing channels or drilling down into campaigns, orders and products; changing them changes the credited results. List-mode status is the stored lifecycle state, not historical delivery; active_in_range filters for spend in the requested window. Use pagination to fetch further pages; totals cover the full filtered set, so do not add them again for each page.\n\nfilter_mode applies saved data filters to this report: none (default) applies none, enabled applies the filters currently enabled in the dashboard, selected applies exactly filter_ids (enabled or not) without changing their saved state. filter_ids is required with selected and rejected otherwise; an unknown id fails the request (404), and so does a selected filter whose saved rules are no longer valid (409). Enabled mode skips such a filter and still answers, with a warning (metadata.warnings over REST, warnings over MCP). Shopify filters narrow store orders. An ad channel filter removes the excluded spend and attributed credit of that channel only; the credit is not re-attributed and store orders stay unchanged. Several filters all apply (AND). Response metadata.data_filters names the applied filters.",
        "tags": ["Analytics"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated platform ad campaign IDs (max 100). Omit for list mode.",
              "example": "120201234567890,120201234567891"
            },
            "required": false,
            "description": "Comma-separated platform ad campaign IDs (max 100). Omit for list mode.",
            "name": "campaign_ids",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "meta-ads",
                "google-ads",
                "taboola",
                "tiktok-ads",
                "outbrain",
                "microsoft-ads",
                "pinterest-ads"
              ],
              "description": "Ad channel identifier. Omit to span all ad-spend channels.",
              "example": "meta-ads"
            },
            "required": false,
            "description": "Ad channel identifier. Omit to span all ad-spend channels.",
            "name": "channel",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "linear_paid",
                "linear_all",
                "first_click",
                "last_click",
                "last_paid_click",
                "all_clicks"
              ],
              "default": "last_paid_click",
              "description": "Attribution model",
              "example": "linear_paid"
            },
            "required": false,
            "description": "Attribution model",
            "name": "attribution_model",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "1_day",
                "7_day",
                "14_day",
                "28_day",
                "90_day",
                "lifetime"
              ],
              "default": "lifetime",
              "description": "Attribution window",
              "example": "28_day"
            },
            "required": false,
            "description": "Attribution window",
            "name": "attribution_window",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["none", "enabled", "selected"],
              "description": "Saved data filters to apply: none (default), enabled or selected",
              "example": "selected"
            },
            "required": false,
            "description": "Saved data filters to apply: none (default), enabled or selected",
            "name": "filter_mode",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": false,
            "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
            "name": "filter_ids",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["creative_metrics"],
              "description": "creative_metrics adds Meta creative metrics to meta-ads items."
            },
            "required": false,
            "description": "creative_metrics adds Meta creative metrics to meta-ads items.",
            "name": "include",
            "in": "query"
          },
          {
            "schema": {
              "type": ["number", "null"],
              "minimum": 0,
              "description": "Filter: minimum ad_spend in the window (inclusive)",
              "example": 100
            },
            "required": false,
            "description": "Filter: minimum ad_spend in the window (inclusive)",
            "name": "min_spend",
            "in": "query"
          },
          {
            "schema": {
              "type": ["number", "null"],
              "minimum": 0,
              "description": "Filter: maximum ad_spend in the window (inclusive)",
              "example": 5000
            },
            "required": false,
            "description": "Filter: maximum ad_spend in the window (inclusive)",
            "name": "max_spend",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["true", "false"],
              "description": "Filter: keep only entities with ad_spend > 0 in the window (\"active in time range\")"
            },
            "required": false,
            "description": "Filter: keep only entities with ad_spend > 0 in the window (\"active in time range\")",
            "name": "active_in_range",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["active", "paused", "all"],
              "default": "all",
              "description": "Filter on the platform lifecycle flag (time-independent). Default `all`."
            },
            "required": false,
            "description": "Filter on the platform lifecycle flag (time-independent). Default `all`.",
            "name": "status",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Case-insensitive substring match on the entity name"
            },
            "required": false,
            "description": "Case-insensitive substring match on the entity name",
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "ad_spend",
                "name",
                "attributed_revenue",
                "roas",
                "attributed_orders"
              ],
              "default": "ad_spend",
              "description": "List-mode sort field. Default `ad_spend`."
            },
            "required": false,
            "description": "List-mode sort field. Default `ad_spend`.",
            "name": "sort_by",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc",
              "description": "List-mode sort order. Default `desc`."
            },
            "required": false,
            "description": "List-mode sort order. Default `desc`.",
            "name": "order",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "default": 1,
              "description": "List-mode page number. Default 1."
            },
            "required": false,
            "description": "List-mode page number. Default 1.",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50,
              "description": "List-mode items per page (max 100). Default 50."
            },
            "required": false,
            "description": "List-mode items per page (max 100). Default 50.",
            "name": "per_page",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Campaign performance data retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/CampaignPerformanceResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Invalid or missing API key"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks required scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "API key does not have required scope: analytics:read"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found - a filter_ids entry is not a saved data filter of this shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "Conflict - a filter_ids entry has saved rules that are no longer valid",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              },
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "description": "Number of seconds to wait before making another request",
                  "example": 45
                },
                "required": true
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer",
                  "description": "Maximum requests allowed per window",
                  "example": 60
                },
                "required": true
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer",
                  "description": "Requests remaining in current window",
                  "example": 0
                },
                "required": true
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer",
                  "description": "Unix timestamp when the rate limit window resets",
                  "example": 1713182400
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Please wait before making more requests."
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/channels": {
      "get": {
        "summary": "Get channel performance metrics",
        "description": "Returns performance metrics for all or specified channels within a date range.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Keep attribution_model and attribution_window identical when comparing channels or drilling down into campaigns, orders and products; changing them changes the credited results. Use this report for attributed channel comparisons and the shop summary for blended shop-wide performance. Channel totals depend on the chosen attribution model. Channels include paid ad channels (meta-ads, google-ads, …) and non-paid ones: organic (dashboard \"Search / Social Media\"), direct (\"Direct Traffic\"), email such as klaviyo, and others; non-paid channels report ad_spend 0 and ROAS 0.\n\nfilter_mode applies saved data filters to this report: none (default) applies none, enabled applies the filters currently enabled in the dashboard, selected applies exactly filter_ids (enabled or not) without changing their saved state. filter_ids is required with selected and rejected otherwise; an unknown id fails the request (404), and so does a selected filter whose saved rules are no longer valid (409). Enabled mode skips such a filter and still answers, with a warning (metadata.warnings over REST, warnings over MCP). Shopify filters narrow store orders. An ad channel filter removes the excluded spend and attributed credit of that channel only; the credit is not re-attributed and store orders stay unchanged. Several filters all apply (AND). Response metadata.data_filters names the applied filters.",
        "tags": ["Analytics"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated channel identifiers — paid (meta-ads, google-ads, …) or non-paid (organic, direct, klaviyo, …). Omit for all channels.",
              "example": "meta-ads,google-ads,organic,direct"
            },
            "required": false,
            "description": "Comma-separated channel identifiers — paid (meta-ads, google-ads, …) or non-paid (organic, direct, klaviyo, …). Omit for all channels.",
            "name": "channels",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "linear_paid",
                "linear_all",
                "first_click",
                "last_click",
                "last_paid_click",
                "all_clicks"
              ],
              "default": "last_paid_click",
              "description": "Attribution model",
              "example": "linear_paid"
            },
            "required": false,
            "description": "Attribution model",
            "name": "attribution_model",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "1_day",
                "7_day",
                "14_day",
                "28_day",
                "90_day",
                "lifetime"
              ],
              "default": "lifetime",
              "description": "Attribution window",
              "example": "28_day"
            },
            "required": false,
            "description": "Attribution window",
            "name": "attribution_window",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["none", "enabled", "selected"],
              "description": "Saved data filters to apply: none (default), enabled or selected",
              "example": "selected"
            },
            "required": false,
            "description": "Saved data filters to apply: none (default), enabled or selected",
            "name": "filter_mode",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": false,
            "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
            "name": "filter_ids",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Channel performance data retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/ChannelPerformanceResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "Invalid or missing API key"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks required scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "FORBIDDEN",
                    "message": "API key does not have required scope: analytics:read"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found - a filter_ids entry is not a saved data filter of this shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "Conflict - a filter_ids entry has saved rules that are no longer valid",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              },
              "Retry-After": {
                "schema": {
                  "type": "integer",
                  "description": "Number of seconds to wait before making another request",
                  "example": 45
                },
                "required": true
              },
              "RateLimit-Limit": {
                "schema": {
                  "type": "integer",
                  "description": "Maximum requests allowed per window",
                  "example": 60
                },
                "required": true
              },
              "RateLimit-Remaining": {
                "schema": {
                  "type": "integer",
                  "description": "Requests remaining in current window",
                  "example": 0
                },
                "required": true
              },
              "RateLimit-Reset": {
                "schema": {
                  "type": "integer",
                  "description": "Unix timestamp when the rate limit window resets",
                  "example": 1713182400
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "RATE_LIMITED",
                    "message": "Rate limit exceeded. Please wait before making more requests."
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "INTERNAL_ERROR",
                    "message": "An unexpected error occurred"
                  },
                  "metadata": {
                    "request_id": "req_abc123",
                    "timestamp": "2025-04-15T12:00:00.000Z"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/summary": {
      "get": {
        "summary": "Get shop P&L summary",
        "description": "Shop-wide P&L summary for a date window: orders, gross/net revenue, refunds, tax, COGS, payment fees, shipping fees, ad spend, the contribution-margin ladder (CM1 = net revenue − COGS; CM2 = CM1 − payment − shipping; CM3 = CM2 − ad spend), blended ROAS/MER (gross revenue ÷ ad spend), POAS (CM2 ÷ ad spend), AOV, new customers, new-customer revenue, and CAC. Figures are shop-wide absolutes — no attribution model applies.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Use this single aggregate for a headline shop report. Null ratios mean the denominator does not support a value; preserve null instead of displaying zero performance.\n\nfilter_mode applies saved data filters to this report: none (default) applies none, enabled applies the filters currently enabled in the dashboard, selected applies exactly filter_ids (enabled or not) without changing their saved state. filter_ids is required with selected and rejected otherwise; an unknown id fails the request (404), and so does a selected filter whose saved rules are no longer valid (409). Enabled mode skips such a filter and still answers, with a warning (metadata.warnings over REST, warnings over MCP). Shopify filters narrow store orders. An ad channel filter removes the excluded spend and attributed credit of that channel only; the credit is not re-attributed and store orders stay unchanged. Several filters all apply (AND). Response metadata.data_filters names the applied filters.",
        "tags": ["Analytics"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD, shop-local)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD, shop-local)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["none", "enabled", "selected"],
              "description": "Saved data filters to apply: none (default), enabled or selected",
              "example": "selected"
            },
            "required": false,
            "description": "Saved data filters to apply: none (default), enabled or selected",
            "name": "filter_mode",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": false,
            "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
            "name": "filter_ids",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Summary retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/AnalyticsSummaryData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "A filter_ids entry is not a saved data filter of this shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "A filter_ids entry has saved rules that are no longer valid",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/timeseries": {
      "get": {
        "summary": "Get core-metric timeseries",
        "description": "Timeseries of core shop metrics per bucket: orders, gross revenue, refunds, COGS, ad spend, payment/shipping fees, tax, net revenue, CM1/CM2/profit (CM3), blended ROAS, new customers, new-customer revenue/ROAS, and CAC. `granularity=auto` (default) returns hourly buckets for very short ranges and daily otherwise; `daily` forces day buckets; `weekly` re-buckets to ISO weeks (bucket timestamp = Monday).\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Choose a fixed granularity when comparing periods. Ratios such as ROAS and CAC are per-bucket values; recompute whole-period ratios from their totals instead of summing or taking an unweighted average of bucket ratios.\n\nfilter_mode applies saved data filters to this report: none (default) applies none, enabled applies the filters currently enabled in the dashboard, selected applies exactly filter_ids (enabled or not) without changing their saved state. filter_ids is required with selected and rejected otherwise; an unknown id fails the request (404), and so does a selected filter whose saved rules are no longer valid (409). Enabled mode skips such a filter and still answers, with a warning (metadata.warnings over REST, warnings over MCP). Shopify filters narrow store orders. An ad channel filter removes the excluded spend and attributed credit of that channel only; the credit is not re-attributed and store orders stay unchanged. Several filters all apply (AND). Response metadata.data_filters names the applied filters.",
        "tags": ["Analytics"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD, shop-local)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD, shop-local)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["none", "enabled", "selected"],
              "description": "Saved data filters to apply: none (default), enabled or selected",
              "example": "selected"
            },
            "required": false,
            "description": "Saved data filters to apply: none (default), enabled or selected",
            "name": "filter_mode",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": false,
            "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
            "name": "filter_ids",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["auto", "daily", "weekly"],
              "default": "auto",
              "description": "Bucket size. `auto` (default) = hourly for very short ranges, daily otherwise; `daily` forces day buckets; `weekly` re-buckets to ISO weeks (bucket timestamp = Monday)."
            },
            "required": false,
            "description": "Bucket size. `auto` (default) = hourly for very short ranges, daily otherwise; `daily` forces day buckets; `weekly` re-buckets to ISO weeks (bucket timestamp = Monday).",
            "name": "granularity",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Timeseries retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/MetricsTimeseriesResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "A filter_ids entry is not a saved data filter of this shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "A filter_ids entry has saved rules that are no longer valid",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/profit-loss": {
      "get": {
        "summary": "Get profit & loss statement",
        "description": "Profit & loss statement for a date window as ordered rows (gross revenue, deductions, and subtotals down to net profit — each with its value and share of gross revenue) plus waterfall-chart steps. This is the same P&L statement the merchant sees on the dashboard.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Use the ordered rows for a statement or waterfall. Subtotal rows already include earlier components; summing every row would count the same amounts more than once.",
        "tags": ["Analytics"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD, shop-local)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD, shop-local)",
            "name": "end_date",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Profit & loss retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/ProfitLossResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/cohorts": {
      "get": {
        "summary": "Get cohort analysis",
        "description": "Cohort retention matrix: customers grouped by acquisition week/month/quarter/year, with per-period incremental and cumulative metrics — active customers, retention %, orders, net revenue, CM1/CM3, AOV, LTV-to-date, LTV:CAC ratios, and payback flag — plus cohort size, ad spend, and CAC per cohort. Optionally filter to customers whose first order contained a specific product/variant.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nThe date window selects acquisition cohorts. max_periods controls follow-up depth, not pagination. Compare cohorts at the same elapsed period; a recent cohort has less observed history. Cumulative metrics already include earlier periods and must not be summed.",
        "tags": ["Analytics"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "First cohort start date (YYYY-MM-DD)",
              "example": "2025-01-01"
            },
            "required": true,
            "description": "First cohort start date (YYYY-MM-DD)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Last cohort end date (YYYY-MM-DD). Defaults to today.",
              "example": "2025-06-30"
            },
            "required": false,
            "description": "Last cohort end date (YYYY-MM-DD). Defaults to today.",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["week", "month", "quarter", "year"],
              "description": "Cohort bucketing period"
            },
            "required": true,
            "description": "Cohort bucketing period",
            "name": "cohort_type",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 60,
              "description": "Retention periods per cohort (defaults per cohort_type)"
            },
            "required": false,
            "description": "Retention periods per cohort (defaults per cohort_type)",
            "name": "max_periods",
            "in": "query"
          },
          {
            "schema": {
              "type": ["integer", "null"],
              "description": "Only cohorts whose first order contained this product"
            },
            "required": false,
            "description": "Only cohorts whose first order contained this product",
            "name": "filter_product_id",
            "in": "query"
          },
          {
            "schema": {
              "type": ["integer", "null"],
              "description": "Only cohorts whose first order contained this variant"
            },
            "required": false,
            "description": "Only cohorts whose first order contained this variant",
            "name": "filter_variant_id",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Cohorts retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/CohortsResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/retention": {
      "get": {
        "summary": "Get retention report",
        "description": "Retention report for customers acquired in the window: CLV, repeat-purchase rate, days to second purchase, CLV:CAC, new vs returning AOV, order-gap distribution, expected-next-order timing (winback / at-risk / lost thresholds), channel-level retention, repurchase windows, LTV by first product, and period LTV (90/180/365 days). `metadata.availability` flags sections with insufficient data.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nCheck the report metadata.availability, including reasons and sample sizes, before drawing conclusions. Missing or null metrics are not evidence of zero retention. Keep refund_attribution consistent across comparisons; product_limit and channel_limit cap breakdown sizes, not pages.",
        "tags": ["Analytics"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD, shop-local)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD, shop-local)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["refund_date", "order_date", "ignore_refunds"],
              "default": "refund_date",
              "description": "How refunds are assigned to periods"
            },
            "required": false,
            "description": "How refunds are assigned to periods",
            "name": "refund_attribution",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50,
              "description": "Max products in the LTV-by-first-product section"
            },
            "required": false,
            "description": "Max products in the LTV-by-first-product section",
            "name": "product_limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 50,
              "default": 20,
              "description": "Max channels in the channel breakdown"
            },
            "required": false,
            "description": "Max channels in the channel breakdown",
            "name": "channel_limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Retention report retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/RetentionResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/analytics/product-relationships": {
      "get": {
        "summary": "Get product relationships",
        "description": "Cross-sell and repurchase relationships between products: which products are bought together in one order, what customers buy next, and per-product stats (customers, orders, units, repurchase rate, first-order vs repeat-order share) with related-product breakdowns. The underlying data is rebuilt daily — see `data_updated_at`.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nproduct_limit, related_limit and top_limit cap different result lists; these are not page sizes for traversing the complete catalog. Check data_updated_at for freshness. These relationships describe observed purchases and do not establish that one product caused another sale.",
        "tags": ["Analytics"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD, shop-local)",
              "example": "2025-01-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD, shop-local)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD). Defaults to today.",
              "example": "2025-06-30"
            },
            "required": false,
            "description": "End date (YYYY-MM-DD). Defaults to today.",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 500,
              "description": "Anchor products returned, highest customer count first"
            },
            "required": false,
            "description": "Anchor products returned, highest customer count first",
            "name": "product_limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 200,
              "description": "Related products per anchor"
            },
            "required": false,
            "description": "Related products per anchor",
            "name": "related_limit",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 50,
              "description": "Rows in the top-bought-together / top-buy-next lists"
            },
            "required": false,
            "description": "Rows in the top-bought-together / top-buy-next lists",
            "name": "top_limit",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Product relationships retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/ProductRelationshipsResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/orders": {
      "get": {
        "summary": "List orders",
        "description": "Lists Shopify orders in a shop-local date window with per-order financials: gross total, tax, refunds (plus a derived `refund_status`), net revenue, CM1/CM2 contribution margins, first-order flag, customer name, payment gateway, and shipping country. Searchable by order number or customer name, sortable, and paginated. Monetary values are in the shop currency.\n\nVenon does not mirror Shopify's `financial_status`; use `refund_status` (none | partial | full, derived from refunded amounts) instead.\n\n**Required scope:** `orders:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Use the returned id for an order-detail request; the displayed name/number (for example #1001) is not that ID. Page through results using page/per_page (default 50, maximum 100).",
        "tags": ["Orders"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD, shop-local)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD, shop-local)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Case-insensitive substring match on order number or customer name"
            },
            "required": false,
            "description": "Case-insensitive substring match on order number or customer name",
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["date", "total_price", "order_number"],
              "default": "date",
              "description": "Sort field. Default `date` (order timestamp)."
            },
            "required": false,
            "description": "Sort field. Default `date` (order timestamp).",
            "name": "sort_by",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc",
              "description": "Sort order. Default `desc`."
            },
            "required": false,
            "description": "Sort order. Default `desc`.",
            "name": "order",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "default": 1,
              "description": "Page number. Default 1."
            },
            "required": false,
            "description": "Page number. Default 1.",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50,
              "description": "Items per page (max 100). Default 50."
            },
            "required": false,
            "description": "Items per page (max 100). Default 50.",
            "name": "per_page",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Orders retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/OrdersListResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the orders:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/orders/{id}": {
      "get": {
        "summary": "Get an order cost breakdown",
        "description": "Returns the full cost breakdown of a single order: every line item with its resolved per-unit COGS (variant rule > product rule > Shopify variant cost > global fallback, effective at the order's timestamp) and per-unit profit, plus an order-level summary — gross/net revenue, effective tax, COGS, payment fees, shipping fee with the resolved shipping profile, refunds, recovered COGS/VAT, CM1, CM2, net margin, and break-even ROAS.\n\n**Required scope:** `orders:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nResolve the order ID from the order list. has_cost_data means at least one cost component resolved, not that every component is complete. Inspect unavailable_metrics and preserve nulls. Line costs are per unit; use quantity when comparing them with the order-level summary.",
        "tags": ["Orders"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "description": "Shopify order ID (numeric)",
              "example": 6389555200136
            },
            "required": true,
            "description": "Shopify order ID (numeric)",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Order cost breakdown retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/OrderCostBreakdownResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the orders:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Order not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/products": {
      "get": {
        "summary": "Get product performance",
        "description": "Sales performance per product — or per variant with `level=variant` — over a shop-local date window: units sold, distinct orders, gross line-item revenue (unit price × quantity, before order-level discounts/tax/refunds), resolved COGS, margin, and margin %. Variant rows carry the merchant `sku`, and `q` matches SKUs too — this endpoint doubles as the SKU ↔ variant-ID lookup for integrations. COGS uses the same per-line resolution as order cost breakdowns (variant rule > product rule > Shopify variant cost > global fallback, effective at each order's timestamp); lines without a resolvable cost contribute 0 to `cogs`. Filterable by name, sortable, and paginated; `totals` aggregates the full filtered set.\n\nProduct status (including ACTIVE/UNLISTED) is not exposed or filterable here. Do not infer status from catalog presence, sales, or soft-deletion filtering. If a task requires status-based selection, obtain an explicit product/variant selection from the user or another authorized source.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Use product-level rows to compare products and variant-level rows for SKU-level analysis. Sales in this window do not establish current catalog availability. totals cover the full filtered result, not just the current page.",
        "tags": ["Products"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD, shop-local)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD, shop-local)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD, shop-local)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["product", "variant"],
              "default": "product",
              "description": "Aggregation level: one row per product (default) or per variant."
            },
            "required": false,
            "description": "Aggregation level: one row per product (default) or per variant.",
            "name": "level",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Case-insensitive substring match on product/variant name or SKU"
            },
            "required": false,
            "description": "Case-insensitive substring match on product/variant name or SKU",
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "gross_revenue",
                "units",
                "orders",
                "cogs",
                "margin",
                "name"
              ],
              "default": "gross_revenue",
              "description": "Sort field. Default `gross_revenue`."
            },
            "required": false,
            "description": "Sort field. Default `gross_revenue`.",
            "name": "sort_by",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["asc", "desc"],
              "default": "desc",
              "description": "Sort order. Default `desc`."
            },
            "required": false,
            "description": "Sort order. Default `desc`.",
            "name": "order",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "default": 1,
              "description": "Page number. Default 1."
            },
            "required": false,
            "description": "Page number. Default 1.",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50,
              "description": "Items per page (max 100). Default 50."
            },
            "required": false,
            "description": "Items per page (max 100). Default 50.",
            "name": "per_page",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Product performance retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/ProductPerformanceResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/products/catalog": {
      "get": {
        "summary": "Look up the product catalog",
        "description": "Lists every product and variant in the shop — regardless of sales — with variant IDs, titles, merchant SKUs, and prices. This is the resolution surface for turning a SKU or product name into the `product_id` / `variant_id` the other endpoints accept (e.g. before writing a COGS rule): `sku` filters to an exact SKU match, `q` does a fuzzy search over product names, variant titles, and SKUs. Soft-deleted variants are excluded. For sales metrics use `GET /v1/products` instead.\n\nProduct status (including ACTIVE/UNLISTED) is not exposed or filterable here. Do not infer status from catalog presence, sales, or soft-deletion filtering. If a task requires status-based selection, obtain an explicit product/variant selection from the user or another authorized source.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nPagination counts products, each with a nested variants array; a page is not a flat list of variants. Follow pagination metadata to inspect all matches. A SKU can identify multiple variants: resolve the intended product/variant ID before making cost changes.",
        "tags": ["Products"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Case-insensitive substring match on product name, variant title, or SKU"
            },
            "required": false,
            "description": "Case-insensitive substring match on product name, variant title, or SKU",
            "name": "q",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Exact SKU match (returns every variant carrying this SKU)"
            },
            "required": false,
            "description": "Exact SKU match (returns every variant carrying this SKU)",
            "name": "sku",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "default": 1,
              "description": "Page number. Default 1."
            },
            "required": false,
            "description": "Page number. Default 1.",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50,
              "description": "Products per page (max 100). Default 50."
            },
            "required": false,
            "description": "Products per page (max 100). Default 50.",
            "name": "per_page",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Product catalog retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/ProductCatalogResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/attribution/orders": {
      "get": {
        "summary": "List attributed orders",
        "description": "Lists the individual orders attributed to a channel — optionally narrowed to one campaign / ad set / ad. Answers \"which orders did this campaign actually drive?\". Paginated (`page`/`per_page`, max 100 per page) with a stable newest-first ordering; `pagination.total_items` carries the full count.\n\n**Scoping:** `channel` alone returns the whole channel. On paid ad channels, narrow with the platform IDs `campaign_id` / `ad_set_id` / `ad_id` (the same IDs the /v1/analytics endpoints return); on non-ad channels (organic, email, direct, referral, …) narrow with `campaign` (the campaign name from tracking parameters). Orders are selected by order date using click/window-based attribution — the same selection the dashboard drill-downs use.\n\n**Required scopes:** `analytics:read` **and** `orders:read` — this endpoint returns individual order records, so an analytics-only key cannot use it.\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Keep attribution_model and attribution_window identical when comparing channels or drilling down into campaigns, orders and products; changing them changes the credited results. total_price is the gross total of each matched order, not fractional attribution credit. Summing these order totals is not a substitute for the analytics attributed_revenue metric.\n\nfilter_mode applies saved data filters to this report: none (default) applies none, enabled applies the filters currently enabled in the dashboard, selected applies exactly filter_ids (enabled or not) without changing their saved state. filter_ids is required with selected and rejected otherwise; an unknown id fails the request (404), and so does a selected filter whose saved rules are no longer valid (409). Enabled mode skips such a filter and still answers, with a warning (metadata.warnings over REST, warnings over MCP). Shopify filters narrow store orders. An ad channel filter removes the excluded spend and attributed credit of that channel only; the credit is not re-attributed and store orders stay unchanged. Several filters all apply (AND). Response metadata.data_filters names the applied filters.",
        "tags": ["Attribution"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Channel identifier — a paid ad channel (e.g. meta-ads, google-ads) or a non-ad channel (e.g. organic, email, direct). Use GET /v1/analytics/channels to discover the channels active in your shop.",
              "example": "meta-ads"
            },
            "required": true,
            "description": "Channel identifier — a paid ad channel (e.g. meta-ads, google-ads) or a non-ad channel (e.g. organic, email, direct). Use GET /v1/analytics/channels to discover the channels active in your shop.",
            "name": "channel",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD; orders are selected by order date)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD; orders are selected by order date)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "linear_paid",
                "linear_all",
                "first_click",
                "last_click",
                "last_paid_click",
                "all_clicks"
              ],
              "default": "last_paid_click",
              "description": "Attribution model",
              "example": "linear_paid"
            },
            "required": false,
            "description": "Attribution model",
            "name": "attribution_model",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "1_day",
                "7_day",
                "14_day",
                "28_day",
                "90_day",
                "lifetime"
              ],
              "default": "lifetime",
              "description": "Attribution window",
              "example": "28_day"
            },
            "required": false,
            "description": "Attribution window",
            "name": "attribution_window",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Campaign name filter for NON-ad channels (e.g. an email campaign). Ignored for paid ad channels — use campaign_id there."
            },
            "required": false,
            "description": "Campaign name filter for NON-ad channels (e.g. an email campaign). Ignored for paid ad channels — use campaign_id there.",
            "name": "campaign",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Platform campaign ID filter (paid ad channels only)"
            },
            "required": false,
            "description": "Platform campaign ID filter (paid ad channels only)",
            "name": "campaign_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Platform ad-set ID filter (paid ad channels only)"
            },
            "required": false,
            "description": "Platform ad-set ID filter (paid ad channels only)",
            "name": "ad_set_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Platform ad ID filter (paid ad channels only)"
            },
            "required": false,
            "description": "Platform ad ID filter (paid ad channels only)",
            "name": "ad_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["true", "false"],
              "description": "Keep only first-time customer orders"
            },
            "required": false,
            "description": "Keep only first-time customer orders",
            "name": "first_time_customers_only",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "default": 1,
              "description": "Page number. Default 1."
            },
            "required": false,
            "description": "Page number. Default 1.",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50,
              "description": "Items per page (max 100). Default 50."
            },
            "required": false,
            "description": "Items per page (max 100). Default 50.",
            "name": "per_page",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["none", "enabled", "selected"],
              "description": "Saved data filters to apply: none (default), enabled or selected",
              "example": "selected"
            },
            "required": false,
            "description": "Saved data filters to apply: none (default), enabled or selected",
            "name": "filter_mode",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": false,
            "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
            "name": "filter_ids",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Attributed orders retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/AttributedOrdersResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "No campaign/ad-set/ad matches the supplied IDs for this shop, or a filter_ids entry is not a saved data filter of this shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "A filter_ids entry has saved rules that are no longer valid",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/attribution/products": {
      "get": {
        "summary": "List attributed products",
        "description": "Lists the products bought in the orders attributed to a channel — optionally narrowed to one campaign / ad set / ad — aggregated per product+variant with quantity and revenue. Answers \"which products does this channel/campaign sell?\". Paginated (`page`/`per_page`, max 100 per page), ordered by revenue descending; `pagination.total_items` carries the full count.\n\n**Scoping:** `channel` alone returns the whole channel. On paid ad channels, narrow with the platform IDs `campaign_id` / `ad_set_id` / `ad_id` (the same IDs the /v1/analytics endpoints return); on non-ad channels (organic, email, direct, referral, …) narrow with `campaign` (the campaign name from tracking parameters). Orders are selected by order date using click/window-based attribution — the same selection the dashboard drill-downs use.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Keep attribution_model and attribution_window identical when comparing channels or drilling down into campaigns, orders and products; changing them changes the credited results. Rows group purchased product/variant combinations; they are not catalog records or individual orders. Use the attributed-orders report when the question needs order identities.\n\nfilter_mode applies saved data filters to this report: none (default) applies none, enabled applies the filters currently enabled in the dashboard, selected applies exactly filter_ids (enabled or not) without changing their saved state. filter_ids is required with selected and rejected otherwise; an unknown id fails the request (404), and so does a selected filter whose saved rules are no longer valid (409). Enabled mode skips such a filter and still answers, with a warning (metadata.warnings over REST, warnings over MCP). Shopify filters narrow store orders. An ad channel filter removes the excluded spend and attributed credit of that channel only; the credit is not re-attributed and store orders stay unchanged. Several filters all apply (AND). Response metadata.data_filters names the applied filters.",
        "tags": ["Attribution"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Channel identifier — a paid ad channel (e.g. meta-ads, google-ads) or a non-ad channel (e.g. organic, email, direct). Use GET /v1/analytics/channels to discover the channels active in your shop.",
              "example": "meta-ads"
            },
            "required": true,
            "description": "Channel identifier — a paid ad channel (e.g. meta-ads, google-ads) or a non-ad channel (e.g. organic, email, direct). Use GET /v1/analytics/channels to discover the channels active in your shop.",
            "name": "channel",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD; orders are selected by order date)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD; orders are selected by order date)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "linear_paid",
                "linear_all",
                "first_click",
                "last_click",
                "last_paid_click",
                "all_clicks"
              ],
              "default": "last_paid_click",
              "description": "Attribution model",
              "example": "linear_paid"
            },
            "required": false,
            "description": "Attribution model",
            "name": "attribution_model",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "1_day",
                "7_day",
                "14_day",
                "28_day",
                "90_day",
                "lifetime"
              ],
              "default": "lifetime",
              "description": "Attribution window",
              "example": "28_day"
            },
            "required": false,
            "description": "Attribution window",
            "name": "attribution_window",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Campaign name filter for NON-ad channels (e.g. an email campaign). Ignored for paid ad channels — use campaign_id there."
            },
            "required": false,
            "description": "Campaign name filter for NON-ad channels (e.g. an email campaign). Ignored for paid ad channels — use campaign_id there.",
            "name": "campaign",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Platform campaign ID filter (paid ad channels only)"
            },
            "required": false,
            "description": "Platform campaign ID filter (paid ad channels only)",
            "name": "campaign_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Platform ad-set ID filter (paid ad channels only)"
            },
            "required": false,
            "description": "Platform ad-set ID filter (paid ad channels only)",
            "name": "ad_set_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Platform ad ID filter (paid ad channels only)"
            },
            "required": false,
            "description": "Platform ad ID filter (paid ad channels only)",
            "name": "ad_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["true", "false"],
              "description": "Keep only first-time customer orders"
            },
            "required": false,
            "description": "Keep only first-time customer orders",
            "name": "first_time_customers_only",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "default": 1,
              "description": "Page number. Default 1."
            },
            "required": false,
            "description": "Page number. Default 1.",
            "name": "page",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "maximum": 100,
              "default": 50,
              "description": "Items per page (max 100). Default 50."
            },
            "required": false,
            "description": "Items per page (max 100). Default 50.",
            "name": "per_page",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["none", "enabled", "selected"],
              "description": "Saved data filters to apply: none (default), enabled or selected",
              "example": "selected"
            },
            "required": false,
            "description": "Saved data filters to apply: none (default), enabled or selected",
            "name": "filter_mode",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": false,
            "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
            "name": "filter_ids",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Attributed products retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/AttributedProductsResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "No campaign/ad-set/ad matches the supplied IDs for this shop, or a filter_ids entry is not a saved data filter of this shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "A filter_ids entry has saved rules that are no longer valid",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/attribution/campaigns": {
      "get": {
        "summary": "Get non-ad channel campaign performance",
        "description": "Campaign-level attributed performance for a NON-ad channel (email, organic, direct, referral, …): attributed orders and revenue, COGS, payment fees, tax, net profit, profit margin %, AOV, and first-time-customer metrics per campaign (campaign names come from tracking parameters). For paid ad channels use `GET /v1/analytics/campaigns` instead — this endpoint rejects them with 400.\n\n**Required scope:** `analytics:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nDates are inclusive shop-local calendar days (YYYY-MM-DD), with start_date <= end_date and at most 366 days per request. Keep the same date range when comparing reports. Keep attribution_model and attribution_window identical when comparing channels or drilling down into campaigns, orders and products; changing them changes the credited results. A campaign here is a tracking campaign name, not an ad-platform campaign ID. Discover the channel from channel performance and keep its exact identifier when requesting this breakdown.\n\nfilter_mode applies saved data filters to this report: none (default) applies none, enabled applies the filters currently enabled in the dashboard, selected applies exactly filter_ids (enabled or not) without changing their saved state. filter_ids is required with selected and rejected otherwise; an unknown id fails the request (404), and so does a selected filter whose saved rules are no longer valid (409). Enabled mode skips such a filter and still answers, with a warning (metadata.warnings over REST, warnings over MCP). Shopify filters narrow store orders. An ad channel filter removes the excluded spend and attributed credit of that channel only; the credit is not re-attributed and store orders stay unchanged. Several filters all apply (AND). Response metadata.data_filters names the applied filters.",
        "tags": ["Attribution"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Non-ad channel identifier (e.g. organic, email, direct, referral). For paid ad channels use GET /v1/analytics/campaigns instead.",
              "example": "email"
            },
            "required": true,
            "description": "Non-ad channel identifier (e.g. organic, email, direct, referral). For paid ad channels use GET /v1/analytics/campaigns instead.",
            "name": "channel",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "Start date (YYYY-MM-DD; orders are selected by order date)",
              "example": "2025-04-01"
            },
            "required": true,
            "description": "Start date (YYYY-MM-DD; orders are selected by order date)",
            "name": "start_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
              "description": "End date (YYYY-MM-DD)",
              "example": "2025-04-15"
            },
            "required": true,
            "description": "End date (YYYY-MM-DD)",
            "name": "end_date",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "linear_paid",
                "linear_all",
                "first_click",
                "last_click",
                "last_paid_click",
                "all_clicks"
              ],
              "default": "last_paid_click",
              "description": "Attribution model",
              "example": "linear_paid"
            },
            "required": false,
            "description": "Attribution model",
            "name": "attribution_model",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": [
                "1_day",
                "7_day",
                "14_day",
                "28_day",
                "90_day",
                "lifetime"
              ],
              "default": "lifetime",
              "description": "Attribution window",
              "example": "28_day"
            },
            "required": false,
            "description": "Attribution window",
            "name": "attribution_window",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "enum": ["none", "enabled", "selected"],
              "description": "Saved data filters to apply: none (default), enabled or selected",
              "example": "selected"
            },
            "required": false,
            "description": "Saved data filters to apply: none (default), enabled or selected",
            "name": "filter_mode",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": false,
            "description": "Comma-separated saved data filter ids (max 20); only with filter_mode=selected",
            "name": "filter_ids",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Campaign performance retrieved successfully",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/NonAdCampaignsResponseData"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the analytics:read scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "A filter_ids entry is not a saved data filter of this shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "A filter_ids entry has saved rules that are no longer valid",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/ads/{channel}/campaigns/{campaign_id}/status": {
      "patch": {
        "summary": "Activate or pause a campaign",
        "description": "Activates or pauses a Meta / Google Ads campaign.\n\nThe change is applied on the ad platform immediately and mirrored into Venon. Ids are platform ids as returned by the analytics endpoints.\n\n**Required scope:** `ads:write`\n\n**Rate limit:** 10 requests per minute per API key\n\nenabled sets the requested state; it is not a toggle. These operations have no dry_run. A successful activation does not guarantee ad delivery, which also depends on parent state and platform eligibility. Google Performance Max child ad sets/ads cannot be edited individually; use their campaign instead.",
        "tags": ["Ads"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": ["meta-ads", "google-ads"],
              "description": "Ad channel — only Meta and Google Ads support writes."
            },
            "required": true,
            "description": "Ad channel — only Meta and Google Ads support writes.",
            "name": "channel",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 30,
              "pattern": "^\\d+$",
              "description": "Platform campaign id — as returned by the analytics endpoints/tools."
            },
            "required": true,
            "description": "Platform campaign id — as returned by the analytics endpoints/tools.",
            "name": "campaign_id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true → activate (status ACTIVE/ENABLED), false → pause."
                  }
                },
                "required": ["enabled"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated campaign",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/AdsCampaignResult"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required ads write scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found - no such entity on this channel for your account",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/ads/{channel}/campaigns/{campaign_id}/budget": {
      "patch": {
        "summary": "Update a campaign daily budget",
        "description": "Updates the daily budget of a Meta / Google Ads campaign.\n\nThe budget is the DAILY budget in the ad account currency (e.g. `50` = 50.00). The change is applied on the ad platform immediately and mirrored into Venon. Ids are platform ids as returned by the analytics endpoints.\n\n**Required scope:** `ads:write`\n\n**Rate limit:** 10 requests per minute per API key\n\nbudget replaces the daily amount; it is not a delta or a lifetime budget. Send currency units with at most two decimal places, not cents or micros. These operations have no dry_run. The ad account currency may differ from the shop currency used in shop reports.",
        "tags": ["Ads"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": ["meta-ads", "google-ads"],
              "description": "Ad channel — only Meta and Google Ads support writes."
            },
            "required": true,
            "description": "Ad channel — only Meta and Google Ads support writes.",
            "name": "channel",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 30,
              "pattern": "^\\d+$",
              "description": "Platform campaign id — as returned by the analytics endpoints/tools."
            },
            "required": true,
            "description": "Platform campaign id — as returned by the analytics endpoints/tools.",
            "name": "campaign_id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "budget": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 1000000000,
                    "description": "New daily budget in the ad account currency (e.g. 50 = 50.00 EUR/USD), max 2 decimal places. Converted to platform units (cents / micros) server-side."
                  }
                },
                "required": ["budget"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated campaign",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/AdsCampaignResult"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required ads write scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found - no such entity on this channel for your account",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/ads/{channel}/ad-sets/{ad_set_id}/status": {
      "patch": {
        "summary": "Activate or pause an ad set",
        "description": "Activates or pauses a Meta ad set / Google Ads ad group.\n\nThe change is applied on the ad platform immediately and mirrored into Venon. Ids are platform ids as returned by the analytics endpoints.\n\n**Required scope:** `ads:write`\n\n**Rate limit:** 10 requests per minute per API key\n\nenabled sets the requested state; it is not a toggle. These operations have no dry_run. A successful activation does not guarantee ad delivery, which also depends on parent state and platform eligibility. Google Performance Max child ad sets/ads cannot be edited individually; use their campaign instead.",
        "tags": ["Ads"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": ["meta-ads", "google-ads"],
              "description": "Ad channel — only Meta and Google Ads support writes."
            },
            "required": true,
            "description": "Ad channel — only Meta and Google Ads support writes.",
            "name": "channel",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 30,
              "pattern": "^\\d+$",
              "description": "Platform ad set id — as returned by the analytics endpoints/tools."
            },
            "required": true,
            "description": "Platform ad set id — as returned by the analytics endpoints/tools.",
            "name": "ad_set_id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true → activate (status ACTIVE/ENABLED), false → pause."
                  }
                },
                "required": ["enabled"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated ad set",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": { "$ref": "#/components/schemas/AdsAdSetResult" },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required ads write scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found - no such entity on this channel for your account",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/ads/{channel}/ad-sets/{ad_set_id}/budget": {
      "patch": {
        "summary": "Update an ad set daily budget (meta-ads only)",
        "description": "Updates the daily budget of a Meta ad set. `meta-ads` only — Google Ads ad groups have no own budget (returns 400); update the campaign budget instead.\n\nThe budget is the DAILY budget in the ad account currency (e.g. `50` = 50.00). The change is applied on the ad platform immediately and mirrored into Venon. Ids are platform ids as returned by the analytics endpoints.\n\n**Required scope:** `ads:write`\n\n**Rate limit:** 10 requests per minute per API key\n\nbudget replaces the daily amount; it is not a delta or a lifetime budget. Send currency units with at most two decimal places, not cents or micros. These operations have no dry_run. The ad account currency may differ from the shop currency used in shop reports.",
        "tags": ["Ads"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": ["meta-ads", "google-ads"],
              "description": "Ad channel — only Meta and Google Ads support writes."
            },
            "required": true,
            "description": "Ad channel — only Meta and Google Ads support writes.",
            "name": "channel",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 30,
              "pattern": "^\\d+$",
              "description": "Platform ad set id — as returned by the analytics endpoints/tools."
            },
            "required": true,
            "description": "Platform ad set id — as returned by the analytics endpoints/tools.",
            "name": "ad_set_id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "budget": {
                    "type": "number",
                    "exclusiveMinimum": 0,
                    "maximum": 1000000000,
                    "description": "New daily budget in the ad account currency (e.g. 50 = 50.00 EUR/USD), max 2 decimal places. Converted to platform units (cents / micros) server-side."
                  }
                },
                "required": ["budget"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated ad set",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": { "$ref": "#/components/schemas/AdsAdSetResult" },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required ads write scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found - no such entity on this channel for your account",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/ads/{channel}/ads/{ad_id}/status": {
      "patch": {
        "summary": "Activate or pause an ad",
        "description": "Activates or pauses a single Meta / Google ad.\n\nThe change is applied on the ad platform immediately and mirrored into Venon. Ids are platform ids as returned by the analytics endpoints.\n\n**Required scope:** `ads:write`\n\n**Rate limit:** 10 requests per minute per API key\n\nenabled sets the requested state; it is not a toggle. These operations have no dry_run. A successful activation does not guarantee ad delivery, which also depends on parent state and platform eligibility. Google Performance Max child ad sets/ads cannot be edited individually; use their campaign instead.",
        "tags": ["Ads"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "enum": ["meta-ads", "google-ads"],
              "description": "Ad channel — only Meta and Google Ads support writes."
            },
            "required": true,
            "description": "Ad channel — only Meta and Google Ads support writes.",
            "name": "channel",
            "in": "path"
          },
          {
            "schema": {
              "type": "string",
              "maxLength": 30,
              "pattern": "^\\d+$",
              "description": "Platform ad id — as returned by the analytics endpoints/tools."
            },
            "required": true,
            "description": "Platform ad id — as returned by the analytics endpoints/tools.",
            "name": "ad_id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean",
                    "description": "true → activate (status ACTIVE/ENABLED), false → pause."
                  }
                },
                "required": ["enabled"]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated ad",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": { "$ref": "#/components/schemas/AdsAdResult" },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required ads write scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found - no such entity on this channel for your account",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/data-filters": {
      "get": {
        "summary": "List saved data filters",
        "description": "Lists the shop's saved data filters (dashboard Settings > Data Filters) with their conditions and enabled state. Pass their ids to a report endpoint with `filter_mode=selected` to apply them.\n\n**Required scope:** `filters:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nA saved data filter belongs to one source: shopify or an ad channel. Conditions in a group must all match and at least one group must match: (A AND B) OR (C AND D). Shopify fields: order_name (contains, does_not_contain, starts_with, is_any_of, is_none_of), shipping_country (ISO 3166-1 alpha-2 code) and payment_gateway (is_any_of, is_none_of). Ad fields: campaign_name, ad_set_name, ad_name (all operators) and campaign_id, ad_set_id, ad_id (platform ids; is_any_of, is_none_of). Matching ignores case; a missing value fails is_any_of, contains and starts_with and passes is_none_of and does_not_contain. At most 10 groups and 10 conditions in total, 100 values of up to 256 characters per condition, 5,000 bytes of values per filter and 20 saved filters per shop. An update replaces the whole filter. A stored filter that no longer passes these rules or limits is left out of lists and reports, and the response warns about it (warnings: how many filters are stored and which were skipped, by id and reason) instead of failing.",
        "tags": ["Data Filters"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "responses": {
          "200": {
            "description": "Saved data filters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": { "$ref": "#/components/schemas/DataFilterList" },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required data filter scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a saved data filter",
        "description": "Creates a saved data filter. An enabled filter immediately narrows the dashboard and Pixel reports of every user of this shop.\n\n**Required scope:** `filters:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nA saved data filter belongs to one source: shopify or an ad channel. Conditions in a group must all match and at least one group must match: (A AND B) OR (C AND D). Shopify fields: order_name (contains, does_not_contain, starts_with, is_any_of, is_none_of), shipping_country (ISO 3166-1 alpha-2 code) and payment_gateway (is_any_of, is_none_of). Ad fields: campaign_name, ad_set_name, ad_name (all operators) and campaign_id, ad_set_id, ad_id (platform ids; is_any_of, is_none_of). Matching ignores case; a missing value fails is_any_of, contains and starts_with and passes is_none_of and does_not_contain. At most 10 groups and 10 conditions in total, 100 values of up to 256 characters per condition, 5,000 bytes of values per filter and 20 saved filters per shop. An update replaces the whole filter. A stored filter that no longer passes these rules or limits is left out of lists and reports, and the response warns about it (warnings: how many filters are stored and which were skipped, by id and reason) instead of failing.",
        "tags": ["Data Filters"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/DataFilterInput" }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created data filter",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": { "$ref": "#/components/schemas/DataFilter" },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required data filter scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "Conflict - the shop already has the maximum of 20 saved data filters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/data-filters/{id}": {
      "put": {
        "summary": "Replace a saved data filter",
        "description": "Replaces a saved data filter (title, description, enabled, source and all groups). Set `enabled` to switch it on or off for the dashboard.\n\n**Required scope:** `filters:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nA saved data filter belongs to one source: shopify or an ad channel. Conditions in a group must all match and at least one group must match: (A AND B) OR (C AND D). Shopify fields: order_name (contains, does_not_contain, starts_with, is_any_of, is_none_of), shipping_country (ISO 3166-1 alpha-2 code) and payment_gateway (is_any_of, is_none_of). Ad fields: campaign_name, ad_set_name, ad_name (all operators) and campaign_id, ad_set_id, ad_id (platform ids; is_any_of, is_none_of). Matching ignores case; a missing value fails is_any_of, contains and starts_with and passes is_none_of and does_not_contain. At most 10 groups and 10 conditions in total, 100 values of up to 256 characters per condition, 5,000 bytes of values per filter and 20 saved filters per shop. An update replaces the whole filter. A stored filter that no longer passes these rules or limits is left out of lists and reports, and the response warns about it (warnings: how many filters are stored and which were skipped, by id and reason) instead of failing.",
        "tags": ["Data Filters"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Saved data filter id",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": true,
            "description": "Saved data filter id",
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/DataFilterInput" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated data filter",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": { "$ref": "#/components/schemas/DataFilter" },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required data filter scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found - no saved data filter with this id for your shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a saved data filter",
        "description": "Deletes a saved data filter; the dashboard and Pixel reports stop applying it.\n\n**Required scope:** `filters:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nA saved data filter belongs to one source: shopify or an ad channel. Conditions in a group must all match and at least one group must match: (A AND B) OR (C AND D). Shopify fields: order_name (contains, does_not_contain, starts_with, is_any_of, is_none_of), shipping_country (ISO 3166-1 alpha-2 code) and payment_gateway (is_any_of, is_none_of). Ad fields: campaign_name, ad_set_name, ad_name (all operators) and campaign_id, ad_set_id, ad_id (platform ids; is_any_of, is_none_of). Matching ignores case; a missing value fails is_any_of, contains and starts_with and passes is_none_of and does_not_contain. At most 10 groups and 10 conditions in total, 100 values of up to 256 characters per condition, 5,000 bytes of values per filter and 20 saved filters per shop. An update replaces the whole filter. A stored filter that no longer passes these rules or limits is left out of lists and reports, and the response warns about it (warnings: how many filters are stored and which were skipped, by id and reason) instead of failing.",
        "tags": ["Data Filters"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "Saved data filter id",
              "example": "7d3c2f0e-1a2b-4c5d-8e9f-0a1b2c3d4e5f"
            },
            "required": true,
            "description": "Saved data filter id",
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Deleted",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": { "type": "boolean", "enum": [true] }
                      },
                      "required": ["deleted"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required data filter scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found - no saved data filter with this id for your shop",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/cogs/global": {
      "get": {
        "summary": "Get global COGS settings",
        "description": "Returns the shop’s global COGS fallback settings.\n\n**COGS model:** each product or variant is a *scope* with a day-grain timeline of rule periods (SCD). At calculation time a line item resolves its per-unit cost with this precedence: **variant rule → product rule → Shopify variant cost (`mode: \"shopify\"`) → global fallback percent**. A variant-level rule coexists with a product-level rule on the same product and simply wins for that variant — there is **no separate \"inherit from product\" toggle**, and none is needed: to give variants of one product different constant costs, create one rule per variant (`{\"mode\":\"constant\",\"value\":4.2,\"variant_id\":…}`) while the product-level rule keeps covering the remaining variants. Exactly one of `product_id`/`variant_id` is set per rule; the create and list endpoints additionally accept `sku` as the scope (resolved to one variant — an ambiguous SKU is rejected with the candidate variant ids, since Shopify does not enforce unique SKUs; resolve names/SKUs to ids via `GET /v1/products/catalog`). Responses expose `mode` as `shopify | constant | percent` (the database stores these as from_shopify | absolute | percent_of_price).\n\n**Required scope:** `cost:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nThese are Venon profit-calculation settings. They do not change Shopify product prices or the product/variant rule timelines. Percentages use percentage points: 30 means 30%, not 0.30.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "responses": {
          "200": {
            "description": "Global COGS settings",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/CogsGlobalSettingsResponse"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      },
      "put": {
        "summary": "Update global COGS settings",
        "description": "Upserts the shop’s global COGS fallback settings.\n\n**Parameter naming:** request parameters are snake_case (e.g. `variant_id`, `as_of`, `effective_to`). The former camelCase spellings are still accepted as **deprecated aliases**; sending both spellings with different values is rejected with a 400. Unknown query parameters are rejected with a 400 listing the accepted names. Response bodies keep their documented camelCase fields.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nThese are Venon profit-calculation settings. They do not change Shopify product prices or the product/variant rule timelines. Percentages use percentage points: 30 means 30%, not 0.30.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CostCogsGlobalPutBody"
              },
              "example": {
                "fallback_percent": 30,
                "fallback_basis": "selling",
                "charge_cogs_on_returns": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated global COGS settings",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/CogsGlobalSettingsResponse"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/cogs/rules": {
      "get": {
        "summary": "List COGS rules",
        "description": "Lists per-product/variant COGS rules grouped by scope. Every scope carries the rule effective at `as_of`, the currently active rule, and the full history — each with its `mode`. Filter to one scope with `product_id`, `variant_id`, or `sku` (at most one; e.g. `?variant_id=52778432299272`).\n\n**COGS model:** each product or variant is a *scope* with a day-grain timeline of rule periods (SCD). At calculation time a line item resolves its per-unit cost with this precedence: **variant rule → product rule → Shopify variant cost (`mode: \"shopify\"`) → global fallback percent**. A variant-level rule coexists with a product-level rule on the same product and simply wins for that variant — there is **no separate \"inherit from product\" toggle**, and none is needed: to give variants of one product different constant costs, create one rule per variant (`{\"mode\":\"constant\",\"value\":4.2,\"variant_id\":…}`) while the product-level rule keeps covering the remaining variants. Exactly one of `product_id`/`variant_id` is set per rule; the create and list endpoints additionally accept `sku` as the scope (resolved to one variant — an ambiguous SKU is rejected with the candidate variant ids, since Shopify does not enforce unique SKUs; resolve names/SKUs to ids via `GET /v1/products/catalog`). Responses expose `mode` as `shopify | constant | percent` (the database stores these as from_shopify | absolute | percent_of_price).\n\n**Parameter naming:** request parameters are snake_case (e.g. `variant_id`, `as_of`, `effective_to`). The former camelCase spellings are still accepted as **deprecated aliases**; sending both spellings with different values is rejected with a 400. Unknown query parameters are rejected with a 400 listing the accepted names. Response bodies keep their documented camelCase fields.\n\n**Required scope:** `cost:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nPagination uses limit/offset (limit defaults to 50, maximum 100) over scopes, not page/per_page or individual history rows. as_of selects the effective period; it does not remove other history from the response. An absent explicit rule does not mean the resolved COGS is zero.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "description": "Filter to one product scope (at most one of product_id / variant_id)",
              "example": 10592895992072
            },
            "required": false,
            "description": "Filter to one product scope (at most one of product_id / variant_id)",
            "name": "product_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "exclusiveMinimum": 0,
              "description": "Filter to one variant scope (at most one of product_id / variant_id)",
              "example": 52778432299272
            },
            "required": false,
            "description": "Filter to one variant scope (at most one of product_id / variant_id)",
            "name": "variant_id",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Filter by merchant SKU (at most one of product_id / variant_id / sku) — resolved to one variant; an ambiguous SKU is rejected with the candidate variant ids"
            },
            "required": false,
            "description": "Filter by merchant SKU (at most one of product_id / variant_id / sku) — resolved to one variant; an ambiguous SKU is rejected with the candidate variant ids",
            "name": "sku",
            "in": "query"
          },
          {
            "schema": {
              "anyOf": [
                { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
                { "type": "string", "format": "date-time" }
              ],
              "description": "Resolve the effective rule at this historical point",
              "example": "2026-01-01"
            },
            "required": false,
            "description": "Resolve the effective rule at this historical point",
            "name": "as_of",
            "in": "query"
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50,
              "description": "Page size. Default 50."
            },
            "required": false,
            "description": "Page size. Default 50.",
            "name": "limit",
            "in": "query"
          },
          {
            "schema": {
              "type": ["integer", "null"],
              "minimum": 0,
              "default": 0,
              "description": "Page offset. Default 0."
            },
            "required": false,
            "description": "Page offset. Default 0.",
            "name": "offset",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "COGS rules",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/CogsRulesListResponse"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create a COGS rule",
        "description": "Sets the current COGS rule for one product or variant. Same-mode writes update the active value and preserve history; mode changes reset the entire scope history; an absent active rule is seeded on the shop-local day. For a constant per-unit cost send `{\"mode\":\"constant\",\"value\":5.5,\"variant_id\":…}` (or `\"product_id\"`, or `\"sku\"`).\n\n**Scope:** exactly one of `product_id` / `variant_id` / `sku`. A variant-level rule coexists with a product-level rule on the same product and **wins for that variant** at calculation time.\n\n**COGS model:** each product or variant is a *scope* with a day-grain timeline of rule periods (SCD). At calculation time a line item resolves its per-unit cost with this precedence: **variant rule → product rule → Shopify variant cost (`mode: \"shopify\"`) → global fallback percent**. A variant-level rule coexists with a product-level rule on the same product and simply wins for that variant — there is **no separate \"inherit from product\" toggle**, and none is needed: to give variants of one product different constant costs, create one rule per variant (`{\"mode\":\"constant\",\"value\":4.2,\"variant_id\":…}`) while the product-level rule keeps covering the remaining variants. Exactly one of `product_id`/`variant_id` is set per rule; the create and list endpoints additionally accept `sku` as the scope (resolved to one variant — an ambiguous SKU is rejected with the candidate variant ids, since Shopify does not enforce unique SKUs; resolve names/SKUs to ids via `GET /v1/products/catalog`). Responses expose `mode` as `shopify | constant | percent` (the database stores these as from_shopify | absolute | percent_of_price).\n\n**Parameter naming:** request parameters are snake_case (e.g. `variant_id`, `as_of`, `effective_to`). The former camelCase spellings are still accepted as **deprecated aliases**; sending both spellings with different values is rejected with a 400. Unknown query parameters are rejected with a 400 listing the accepted names. Response bodies keep their documented camelCase fields.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nSame-mode writes update the active value and preserve history. Mode changes reset the entire scope history; missing active rows are seeded on the shop-local day. After an uncertain response, read the scope before retrying. A constant value is a per-unit cost; percent values use percentage points (30 means 30%).",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CostCogsRuleCreateBody"
              },
              "example": {
                "mode": "constant",
                "value": 5.5,
                "variant_id": 52778432299272
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created COGS rule scope view",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/CogsRuleScopeView"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/cogs/rules/{id}": {
      "get": {
        "summary": "Get a COGS rule",
        "description": "Gets a single COGS rule (SCD row) by id.\n\n**Required scope:** `cost:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nThe id is a COGS history-row ID returned by the rules list, not a product or variant ID. Use the scope list to inspect the complete timeline before updating or deleting individual rows.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": { "type": "integer", "exclusiveMinimum": 0 },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "COGS rule",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": { "$ref": "#/components/schemas/CogsRuleRow" },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/cogs/rules/bulk-read": {
      "post": {
        "summary": "Read selected COGS rule histories in bulk",
        "description": "Accepts 1–100 unique targets, each with exactly one safe positive integer product_id or variant_id. Only canonical snake_case request fields are accepted; unknown body or query fields are rejected. Results remain in request order and include index and target. Missing and other-shop targets are indistinguishable. One HTTP request replaces up to 100 single-target requests; database writes remain sequential. This POST is a read and does not require cost:write. Owned targets without explicit rules return an empty scope view (current/effective null, history empty); this is not resolved zero cost, and variant/global fallbacks can still apply. as_of accepts a YYYY-MM-DD shop-local day or an ISO instant converted to the shop timezone; omitted means shop-local today. Complete selected histories are returned up to 10,000 total rows, including the active rows. Above that ceiling the whole read fails with 422: use smaller target chunks; histories are never silently truncated.\n\n**Required scope:** `cost:read`\n\n**Rate limit:** 60 requests per minute per API key",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CogsBulkReadBody" },
              "example": {
                "targets": [{ "product_id": 100 }, { "variant_id": 200 }],
                "as_of": "2026-09-30"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ordered selected scope results",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/CogsBulkReadResult"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "422": {
            "description": "Selected histories exceed 10,000 rows; use smaller target chunks",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/cogs/rules/bulk": {
      "post": {
        "summary": "Set different COGS rules in one batch",
        "description": "Accepts 1–100 unique targets, each with exactly one safe positive integer product_id or variant_id. Only canonical snake_case request fields are accepted; unknown body or query fields are rejected. Results remain in request order and include index and target. Missing and other-shop targets are indistinguishable. One HTTP request replaces up to 100 single-target requests; database writes remain sequential. Same-mode writes update the current value in place and preserve history. A mode change resets ALL history for that scope. An absent active row is seeded on the shop-local calendar day. Dates are day-grain. Dry runs make no rule mutations, return every target validity outcome and history_reset for valid entries, and can become stale before execution. Ownership is checked again by each real write. Entries are independent, without cross-target atomicity. Always inspect every result: a failed sibling does not roll back successful entries. Never automatically replay the batch. WRITE_UNCERTAIN can mean a write committed but readback failed; re-read that target using bulk-read before deciding whether to retry. CONFLICT and INVALID_RULE also require a re-read before retry. applied counts confirmed successes only; uncertain outcomes may have persisted. Read targets first with POST /v1/cost/cogs/rules/bulk-read, preview with dry_run: true, inspect history_reset, then submit dry_run: false. Malformed entries reject the whole request before any writes. Dry-run selected histories have the same 10,000-row ceiling as bulk-read. cost:write is required even for dry_run. The existing shared-value /cogs/bulk endpoint remains available.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CogsBulkWriteBody" },
              "example": {
                "dry_run": true,
                "entries": [
                  { "product_id": 100, "mode": "constant", "value": 4.2 },
                  {
                    "variant_id": 200,
                    "mode": "constant",
                    "value": 7.5,
                    "recover_on_return": false
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Ordered independent write or preview outcomes",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/CogsBulkWriteResult"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "422": {
            "description": "Dry-run selected histories exceed 10,000 rows; use smaller target chunks",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/cogs/rules/ops": {
      "post": {
        "summary": "Apply COGS history operations",
        "description": "Applies a batch of add/update/delete operations against one scope’s COGS history in one transaction. Each op’s `effective_to` marks when that row’s period ends; the chain is re-stitched afterwards so periods stay contiguous.\n\n**Note:** a batch whose deletes remove the scope’s last remaining row currently returns the empty scope view (`current`/`effective` null, empty history) rather than an error.\n\n**Scope:** exactly one of `product_id` / `variant_id` / `sku`. A variant-level rule coexists with a product-level rule on the same product and **wins for that variant** at calculation time.\n\n**Parameter naming:** request parameters are snake_case (e.g. `variant_id`, `as_of`, `effective_to`). The former camelCase spellings are still accepted as **deprecated aliases**; sending both spellings with different values is rejected with a 400. Unknown query parameters are rejected with a 400 listing the accepted names. Response bodies keep their documented camelCase fields.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nUse history-row IDs from the selected scope for update/delete operations. The transaction covers this scope only; a sequence of requests for different scopes is not one atomic change.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/CostCogsRulesOpsBody" },
              "example": {
                "variant_id": 52778432299272,
                "ops": [
                  {
                    "kind": "add",
                    "effective_to": "2026-01-01",
                    "mode": "constant",
                    "value": 4.2
                  },
                  { "kind": "delete", "id": 17 }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated COGS rule scope view",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/CogsRuleScopeView"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/cogs/rules/history": {
      "post": {
        "summary": "Set the full COGS history timeline",
        "description": "Declaratively REPLACES one product/variant scope’s entire COGS chain with the supplied ordered periods (ascending by `until`; the final period has until=null = the active row). One `mode` for the whole timeline. Pass dry_run=true to preview without writing.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nRead the existing timeline first and include every period that should survive; omitted periods are removed. until is an exclusive END date, not a start date. A dry run does not reserve state or guarantee a later write succeeds.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SetCogsHistoryBody" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Refreshed COGS rule scope view (or a non-applied plan when dry_run)",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {},
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/payment-gateways": {
      "get": {
        "summary": "List payment gateways",
        "description": "Lists payment gateways and their cost/fee settings (e.g. `?history=1&name=shopify_payments` for one gateway’s full timeline).\n\n**Parameter naming:** request parameters are snake_case (e.g. `variant_id`, `as_of`, `effective_to`). The former camelCase spellings are still accepted as **deprecated aliases**; sending both spellings with different values is rejected with a 400. Unknown query parameters are rejected with a 400 listing the accepted names. Response bodies keep their documented camelCase fields.\n\n**Required scope:** `cost:read`\n\n**Rate limit:** 60 requests per minute per API key\n\nBy default only active rows are returned; use history=1 in REST or history=true in MCP for historical rows. Use a returned row id to update that gateway. These settings model costs in Venon; they do not change the fees charged by the payment provider.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": {
              "anyOf": [
                { "type": "string", "enum": ["1"] },
                { "type": "string", "enum": ["true"] }
              ],
              "description": "Return the full fee history instead of only the active rows"
            },
            "required": false,
            "description": "Return the full fee history instead of only the active rows",
            "name": "history",
            "in": "query"
          },
          {
            "schema": {
              "type": "string",
              "minLength": 1,
              "description": "Filter to one gateway by name"
            },
            "required": false,
            "description": "Filter to one gateway by name",
            "name": "name",
            "in": "query"
          }
        ],
        "responses": {
          "200": {
            "description": "Payment gateways",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {},
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Upsert a payment gateway",
        "description": "Updates a payment gateway’s cost/fee (SCD upsert). Omit `effective_at` to supersede the active row now; supply it to period-split at that date.\n\n**Parameter naming:** request parameters are snake_case (e.g. `variant_id`, `as_of`, `effective_to`). The former camelCase spellings are still accepted as **deprecated aliases**; sending both spellings with different values is rejected with a 400. Unknown query parameters are rejected with a 400 listing the accepted names. Response bodies keep their documented camelCase fields.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nid is a required existing gateway-row ID that identifies the gateway timeline; this does not create a gateway from a new name. Supply both cost (fixed amount per transaction) and fee (percentage points, so 2.9 means 2.9%). Read back the timeline after changing an effective date.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CostPaymentGatewayUpsertBody"
              },
              "example": {
                "id": 12,
                "cost": 0.3,
                "fee": 2.9,
                "effective_at": "2026-01-01"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upserted payment gateway",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {},
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/payment-gateways/ops": {
      "post": {
        "summary": "Apply payment gateway history operations",
        "description": "Applies a batch of add/update/delete operations against one gateway’s fee history in one transaction. Each op’s `effective_to` marks when that row’s period ends; the literal `'infinity'` marks the active row.\n\n**Parameter naming:** request parameters are snake_case (e.g. `variant_id`, `as_of`, `effective_to`). The former camelCase spellings are still accepted as **deprecated aliases**; sending both spellings with different values is rejected with a 400. Unknown query parameters are rejected with a 400 listing the accepted names. Response bodies keep their documented camelCase fields.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nUse the exact gateway name and row IDs from its history. The batch is atomic for that gateway; reread its timeline after a validation failure before rebuilding the operations.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CostPaymentGatewayOpsBody"
              },
              "example": {
                "name": "shopify_payments",
                "ops": [
                  {
                    "kind": "update",
                    "id": 3,
                    "effective_to": "infinity",
                    "cost": 0.25,
                    "fee": 1.9
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated payment gateway chain",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {},
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/payment-gateways/history": {
      "post": {
        "summary": "Set the full payment gateway fee timeline",
        "description": "Declaratively REPLACES one gateway’s entire fee chain (by name) with the supplied ordered periods (ascending by `until`; the final period has until=null = the active row). Each period carries cost + fee. Pass dry_run=true to preview without writing.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nRead the existing timeline first and include every period that should survive; omitted periods are removed. until is an exclusive END date, not a start date. A dry run does not reserve state or guarantee a later write succeeds.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetPaymentFeeHistoryBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Refreshed payment gateway chain (or a non-applied plan when dry_run)",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {},
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/shipping-methods": {
      "get": {
        "summary": "List shipping methods",
        "description": "Lists shipping-method titles observed on real orders. Use this endpoint only when pricing intentionally differs by method, then copy a returned title byte-for-byte into `shipping_methods`.\n\n**Required scope:** `cost:read`\n\n**Rate limit:** 60 requests per minute per API key",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "responses": {
          "200": {
            "description": "Shipping methods",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "type": "array",
                      "items": { "type": "string" },
                      "description": "Observed shipping-method titles; copy each title byte-for-byte"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/shipping-profiles": {
      "get": {
        "summary": "List shipping profiles",
        "description": "Lists ALL shipping profiles (identity + scope, no fees or pagination). Accepts no query parameters. Use GET /v1/cost/shipping-profiles/{id} for costs and history. Shipping-profile scope uniqueness is independent of the profile name. Two non-default profiles conflict when their countries, shipping methods AND products/variants all overlap. An empty array matches every value on that dimension. Any intersecting combination is enough; the complete lists do not need to be equal. A product includes all its variants, so a product profile and one of its variant profiles conflict when country and method scopes also overlap. Distinct variants of the same product can coexist. The catch-all default is excluded from this overlap check; other profiles must narrow at least one dimension.\n\n**Required scope:** `cost:read`\n\n**Rate limit:** 60 requests per minute per API key",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "responses": {
          "200": {
            "description": "Shipping profiles",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/ShippingProfileSummary"
                      },
                      "description": "All profiles in the authenticated shop, without fees or pagination"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Upsert a shipping profile",
        "description": "Creates or updates a shipping profile’s identity and scope, optionally with its full fee setup via the nested `fees` block — one atomic request creates a fully configured profile (scalar fees plus flat or weight/item bucket axes; omitted values seed 0). On update, `fees` scalars overwrite the current value in place (history kept) and a provided axis REPLACES that axis, resetting its fee history (same semantics as /tiers). This is the single canonical call for creating or editing a profile; /tiers, /fee-history and /bucket-history are narrower cost-timeline utilities on top of it.\n\n**Shipping-method scope:** `shipping_methods: []` is the recommended default whenever fees do not intentionally vary by shipping method. An empty array means the profile applies to all current and future shipping methods; it does not disable the profile. Never invent generic values such as `Standard`. For differentiated pricing, first call `GET /v1/cost/shipping-methods` and copy returned titles byte-for-byte. Unknown, whitespace-changed, or case-changed titles receive a 422 response. Methods already saved on an existing profile remain grandfathered until that profile is re-scoped.\n\nShipping-profile scope uniqueness is independent of the profile name. Two non-default profiles conflict when their countries, shipping methods AND products/variants all overlap. An empty array matches every value on that dimension. Any intersecting combination is enough; the complete lists do not need to be equal. A product includes all its variants, so a product profile and one of its variant profiles conflict when country and method scopes also overlap. Distinct variants of the same product can coexist. The catch-all default is excluded from this overlap check; other profiles must narrow at least one dimension.\n\nProvide the existing profile id to update; omit it to create. The server never finds an update target by name or matching scope. Updates exclude their own id from conflict detection but still check every other non-default profile in the shop. Names must be unique within the shop and there can be only one default; is_default cannot be changed on an existing profile. Upsert requires the complete identity/scope fields. Omit fees to preserve all costs and history. Provided scalar fees overwrite current values while preserving history; a provided per_order or per_order_return axis REPLACES that axis and resets its history, including for flat axes.\n\nRead each conflicting profile by id and inspect its complete scope and costs. Update by id only when it is the intended target; a profile may cover additional countries or products. Otherwise narrow the proposed scope or resolve the ambiguity with the user. Changing the name or retrying unchanged cannot fix a scope conflict. Do not delete or overwrite another profile merely because it conflicts. Read back the final profile after an authorized update.\n\nIdentity, scope and nested fees commit in one transaction; a conflict rolls back all changes. Profile-scope writes are serialized within the shop, so concurrent overlapping creates cannot both commit. Preflight reads do not reserve a scope. No idempotency key or revision precondition is supported; after an uncertain timeout, re-read before retrying a create. [Worked examples and workflow guide](https://developerdocs.venon.io/shipping-profiles.md).\n\n**Parameter naming:** request parameters are snake_case (e.g. `variant_id`, `as_of`, `effective_to`). The former camelCase spellings are still accepted as **deprecated aliases**; sending both spellings with different values is rejected with a 400. Unknown query parameters are rejected with a 400 listing the accepted names. Response bodies keep their documented camelCase fields.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CostShippingProfileUpsertBody"
              },
              "examples": {
                "createWithFees": {
                  "summary": "Create a product/country profile with fees",
                  "value": {
                    "profile": {
                      "name": "Germany product 101",
                      "is_default": false,
                      "country_codes": ["DE"],
                      "shipping_methods": [],
                      "products": [{ "kind": "product", "id": 101 }],
                      "currency": "EUR",
                      "fees": {
                        "packaging_fee": 0.5,
                        "per_order": { "type": "flat", "value": 5.9 }
                      }
                    }
                  }
                },
                "updateScalar": {
                  "summary": "Update by id, preserving shipping axes and history",
                  "value": {
                    "profile": {
                      "name": "Germany product 101",
                      "is_default": false,
                      "country_codes": ["DE"],
                      "shipping_methods": [],
                      "products": [{ "kind": "product", "id": 101 }],
                      "currency": "EUR",
                      "fees": { "packaging_fee": 0.75 },
                      "id": "41"
                    }
                  }
                },
                "allShippingMethods": {
                  "summary": "Country-specific profile for all shipping methods",
                  "description": "Recommended when fees do not vary by shipping method. shipping_methods: [] covers current and future methods and keeps the profile active.",
                  "value": {
                    "profile": {
                      "name": "Germany — all shipping methods",
                      "is_default": false,
                      "country_codes": ["DE"],
                      "shipping_methods": [],
                      "products": [],
                      "currency": "EUR",
                      "fees": { "per_order": { "type": "flat", "value": 5.9 } }
                    }
                  }
                },
                "methodSpecific": {
                  "summary": "Profile for one observed shipping-method title",
                  "description": "Assumes the preceding GET /v1/cost/shipping-methods response contained \"Versand mit Sendungsverfolgung\"; copy the actual returned title byte-for-byte.",
                  "value": {
                    "profile": {
                      "name": "Tracked shipping",
                      "is_default": false,
                      "country_codes": [],
                      "shipping_methods": ["Versand mit Sendungsverfolgung"],
                      "products": [],
                      "currency": "EUR",
                      "fees": { "per_order": { "type": "flat", "value": 12.9 } }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Upserted shipping profile id",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/ShippingProfileUpsertResult"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "Name/default uniqueness conflict: SHIPPING_PROFILE_IDENTITY_CONFLICT. List profiles and inspect the intended identity before updating by id.",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "example": {
                  "success": false,
                  "error": {
                    "code": "SHIPPING_PROFILE_IDENTITY_CONFLICT",
                    "message": "A profile with this name or default flag already exists"
                  }
                }
              }
            }
          },
          "422": {
            "description": "Scope overlap (SHIPPING_PROFILE_SCOPE_CONFLICT) or semantic validation (VALIDATION_ERROR), including unknown, whitespace-changed or case-changed shipping-method titles. No changes are committed.",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" },
                "examples": {
                  "scopeConflict": {
                    "summary": "Existing product/country scope under a different name",
                    "value": {
                      "success": false,
                      "error": {
                        "code": "SHIPPING_PROFILE_SCOPE_CONFLICT",
                        "message": "This profile's scope overlaps with \"Germany product 101\" (id 41). Each combination of country, shipping method, and product can belong to only one profile",
                        "conflicting_profiles": [
                          { "id": 41, "name": "Germany product 101" }
                        ],
                        "recovery": "Read each conflicting profile by id and inspect its complete scope and costs. Update by id only when it is the intended target; a profile may cover additional countries or products. Otherwise narrow the proposed scope or resolve the ambiguity with the user. Changing the name or retrying unchanged cannot fix a scope conflict. Do not delete or overwrite another profile merely because it conflicts. Read back the final profile after an authorized update."
                      },
                      "metadata": {
                        "request_id": "req_example",
                        "timestamp": "2026-09-14T00:00:00.000Z"
                      }
                    }
                  },
                  "unknownMethod": {
                    "summary": "Unobserved method title",
                    "value": {
                      "success": false,
                      "error": {
                        "code": "VALIDATION_ERROR",
                        "message": "Unknown shipping method(s): versand mit sendungsverfolgung. Profiles can only be scoped to shipping methods observed on this shop's orders (empty = all methods). Observed methods: Versand mit Sendungsverfolgung."
                      },
                      "metadata": {
                        "request_id": "req_abc123xyz",
                        "timestamp": "2026-08-05T12:00:00.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/shipping-profiles/{id}": {
      "get": {
        "summary": "Get a shipping profile",
        "description": "Gets one shipping profile with its complete scope, current fees, buckets and each fee/bucket cost history. Response fields remain camelCase. history[].effectiveFrom is the exclusive END of a historical value, when the next value took over. Read each conflicting profile by id and inspect its complete scope and costs. Update by id only when it is the intended target; a profile may cover additional countries or products. Otherwise narrow the proposed scope or resolve the ambiguity with the user. Changing the name or retrying unchanged cannot fix a scope conflict. Do not delete or overwrite another profile merely because it conflicts. Read back the final profile after an authorized update.\n\n**Required scope:** `cost:read`\n\n**Rate limit:** 60 requests per minute per API key",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": { "type": "integer", "exclusiveMinimum": 0 },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Shipping profile",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": { "$ref": "#/components/schemas/ShippingProfile" },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a shipping profile",
        "description": "Deletes a non-default shipping profile and its fee history.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": { "type": "integer", "exclusiveMinimum": 0 },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Deletion acknowledged",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "type": "object",
                      "properties": {
                        "deleted": { "type": "boolean", "enum": [true] }
                      },
                      "required": ["deleted"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/shipping-profiles/tiers": {
      "post": {
        "summary": "Set weight/item shipping tiers",
        "description": "Sets graduated weight/item tiers (with costs) on a profile axis in ONE call — e.g. up to 1kg 4.50, up to 5kg 7.00, 5kg+ 12.00 (open-ended top tier = up_to:null). Replaces the axis, which resets its existing fee history; pass dry_run=true to preview without writing.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SetShippingTiersBody" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Refreshed shipping profile (or a non-applied plan when dry_run)",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "anyOf": [
                        { "$ref": "#/components/schemas/ShippingProfile" },
                        { "$ref": "#/components/schemas/ShippingTiersPlan" }
                      ]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "422": {
            "description": "Semantic validation failed; no changes committed (VALIDATION_ERROR).",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/shipping-profiles/fee-history": {
      "post": {
        "summary": "Set the full timeline for one scalar shipping fee",
        "description": "Declaratively REPLACES one scalar fee chain on a profile (by value_name, e.g. packaging_fee) with the supplied ordered periods (ascending by `until`; the final period has until=null = the active row). For graduated weight/item tiers use /tiers or /bucket-history. Pass dry_run=true to preview without writing.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetShippingFeeHistoryBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Refreshed shipping profile (or a non-applied plan when dry_run)",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "anyOf": [
                        { "$ref": "#/components/schemas/ShippingProfile" },
                        {
                          "$ref": "#/components/schemas/ShippingFeeHistoryPlan"
                        }
                      ]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "422": {
            "description": "Semantic validation failed; no changes committed (VALIDATION_ERROR).",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/shipping-profiles/bucket-history": {
      "post": {
        "summary": "Set the full cost timeline for one shipping bucket",
        "description": "Declaratively REPLACES one existing bucket’s entire cost chain (by bucket_id) with the supplied ordered periods (ascending by `until`; the final period has until=null = the active row). Create buckets first with /tiers. Pass dry_run=true to preview without writing.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetShippingBucketHistoryBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Refreshed shipping profile (or a non-applied plan when dry_run)",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "anyOf": [
                        { "$ref": "#/components/schemas/ShippingProfile" },
                        {
                          "$ref": "#/components/schemas/ShippingBucketHistoryPlan"
                        }
                      ]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "422": {
            "description": "Semantic validation failed; no changes committed (VALIDATION_ERROR).",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/cogs/bulk": {
      "post": {
        "summary": "Bulk-set product COGS",
        "description": "Applies one COGS rule to many products/variants. Pass dry_run=true to preview without writing.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nAt most 100 product/variant targets per call. Each target is applied independently: a successful response can still contain failed entries. Inspect applied and failed before reporting success, and retry only intended failed targets after checking their current state. Dry-run plans report planned, valid, invalid and a sample; the sample is not the complete target list and applied remains 0.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/BulkSetCogsBody" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk result (plan when dry_run, else { applied, failed[] })",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {},
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/payment-gateways/bulk": {
      "post": {
        "summary": "Bulk-set payment fees",
        "description": "Upserts many payment gateways in one call. Pass dry_run=true to preview without writing.\n\n**Parameter naming:** request parameters are snake_case (e.g. `variant_id`, `as_of`, `effective_to`). The former camelCase spellings are still accepted as **deprecated aliases**; sending both spellings with different values is rejected with a 400. Unknown query parameters are rejected with a 400 listing the accepted names. Response bodies keep their documented camelCase fields.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key\n\nAt most 50 gateways per call. Each target is applied independently: a successful response can still contain failed entries. Inspect applied and failed before reporting success, and retry only intended failed targets after checking their current state. Dry-run plans report planned, valid, invalid and a sample; the sample is not the complete target list and applied remains 0.",
        "tags": ["Cost"],
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CostBulkSetPaymentFeesBody"
              },
              "example": {
                "gateways": [{ "id": 12, "cost": 0.3, "fee": 2.9 }],
                "dry_run": true
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bulk result (plan when dry_run, else { applied, failed[] })",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {},
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Validation error - invalid parameters",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [false] },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "enum": ["VALIDATION_ERROR"]
                        },
                        "message": { "type": "string" },
                        "details": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "field": { "type": "string" },
                              "message": { "type": "string" }
                            },
                            "required": ["field", "message"]
                          }
                        }
                      },
                      "required": ["code", "message"]
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "error", "metadata"]
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    },
    "/v1/cost/shipping-profiles/{id}/cost-updates": {
      "post": {
        "operationId": "updateShippingCosts",
        "tags": ["Cost"],
        "summary": "Update multiple tier costs from an effective date, preserving history",
        "description": "Update up to 50 existing shipping buckets in one atomic request, in the profile currency. First preview with dry_run=true, then apply with its revision as expected_revision. effective_from is an inclusive shop-local YYYY-MM-DD date; backdated and future changes are supported. Each new cost lasts until the next existing period boundary (effective_until in the result), or indefinitely if null. Earlier history, later scheduled costs, bucket boundaries and omitted buckets are preserved. At an existing start boundary only that period is updated. Equal costs are no-ops. A missing/cross-profile bucket fails the whole request with 404 and a field-level error. A changed profile returns SHIPPING_PROFILE_REVISION_CONFLICT (409); preview again before applying. Preview does not reserve the profile. There are no idempotency keys or saved responses. After an uncertain timeout, fetch the current profile and reconcile the requested costs. Repeating a committed change with its original revision returns 409; unchanged no-op requests may succeed again. Do not automatically refresh the revision and overwrite newer edits. Preview and review any remaining change before applying. The revision covers identity, scope, tiers and all fee histories. Use /tiers only to replace tier structure and /bucket-history only to explicitly replace a complete timeline.\n\n**Required scope:** `cost:write`\n\n**Rate limit:** 60 requests per minute per API key",
        "security": [{ "BearerAuth": [] }, { "ApiKeyHeader": [] }],
        "parameters": [
          {
            "schema": { "type": "integer", "exclusiveMinimum": 0 },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ShippingCostUpdateBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Preview or committed result",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": { "type": "boolean", "enum": [true] },
                    "data": {
                      "$ref": "#/components/schemas/ShippingCostUpdateResult"
                    },
                    "metadata": {
                      "$ref": "#/components/schemas/ResponseMetadata"
                    }
                  },
                  "required": ["success", "data", "metadata"]
                }
              }
            }
          },
          "400": {
            "description": "Invalid payload or missing revision",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "401": {
            "description": "Unauthorized - Invalid or missing API key",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "403": {
            "description": "Forbidden - API key lacks the required cost scope",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "404": {
            "description": "Not found",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "409": {
            "description": "SHIPPING_PROFILE_REVISION_CONFLICT; fetch the current profile and preview again before applying",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "422": {
            "description": "A requested bucket has no cost period at the effective date",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "headers": {
              "X-Request-Id": {
                "schema": {
                  "type": "string",
                  "description": "Unique request identifier for tracing and debugging",
                  "example": "req_abc123xyz"
                },
                "required": true
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/ErrorResponse" }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {}
}
