{
  "openapi": "3.1.0",
  "info": {
    "title": "Rewalto API",
    "version": "0.101.0",
    "summary": "India's data layer for AI agents and people",
    "description": "One front door for people and agents: the site, the dashboards, the CLI and MCP all call this API. Every route is under `/v1`. Errors always have the same envelope (`ErrorEnvelope`); decide what to do from `error.retry`. Using the tools is free: credits are charged only for data actually delivered (C-012). Requests are rate limited per credential (or, without one, per IP) in one-minute windows: every answer carries `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset`, and over the limit the answer is 429 `rate_limited` with `Retry-After`. A change that removes or alters something ships behind `/v2`."
  },
  "servers": [
    {
      "url": "https://api-dev.rewalto.com",
      "description": "Staging, on the shared database (D-1360). API keys and Clerk sessions from the frontend dev issuer (D-1346); /v1/data is not served here until D-1391."
    },
    {
      "url": "https://api.rewalto.com",
      "description": "Production. API keys and Clerk sessions from the production issuer."
    }
  ],
  "tags": [
    {
      "name": "API keys"
    },
    {
      "name": "Billing"
    },
    {
      "name": "Catalogue"
    },
    {
      "name": "Categories"
    },
    {
      "name": "Coverage"
    },
    {
      "name": "Credits"
    },
    {
      "name": "Data"
    },
    {
      "name": "Data requests"
    },
    {
      "name": "Exports"
    },
    {
      "name": "Figures"
    },
    {
      "name": "Free tools"
    },
    {
      "name": "Identity"
    },
    {
      "name": "Onboarding and notifications"
    },
    {
      "name": "Plans"
    },
    {
      "name": "Problem reports"
    },
    {
      "name": "Quick commerce"
    },
    {
      "name": "Quotes"
    },
    {
      "name": "Report data"
    },
    {
      "name": "Report schedules"
    },
    {
      "name": "Report uploads"
    },
    {
      "name": "Reports"
    },
    {
      "name": "Runs"
    },
    {
      "name": "Saved searches"
    },
    {
      "name": "Search"
    },
    {
      "name": "Service"
    },
    {
      "name": "Service (server to server)"
    },
    {
      "name": "Snapshots"
    },
    {
      "name": "Staff: adoption"
    },
    {
      "name": "Staff: audit"
    },
    {
      "name": "Staff: data requests"
    },
    {
      "name": "Staff: order requests"
    },
    {
      "name": "Staff: problem reports"
    },
    {
      "name": "Staff: recipe publishing"
    },
    {
      "name": "Staff: reports"
    },
    {
      "name": "Staff: snapshots"
    },
    {
      "name": "Walt"
    }
  ],
  "paths": {
    "/v1/billing/basket": {
      "post": {
        "operationId": "createBasketCheckout",
        "summary": "Pay for a basket",
        "description": "Prices the basket from the price list in force (as POST /v1/billing/basket/quote) and refuses a different expectedTotalPaise with price_changed (the details give the fresh total), creating nothing. A basket with a monthly line is paid by one Razorpay subscription (12 monthly cycles; the one-off lines ride on the first invoice), any other by one Razorpay payment link: the answer carries kind, the url to pay at and the quote, with GST as the order is priced (the buyer's billing profile decides CGST and SGST or IGST). The same basket on the same IST day answers the same order and payment page. Every brand plan, pack and report in the basket is recorded as an order request. Nothing is granted until Razorpay confirms the payment: then, once, API credits and credit plans are added, a brand plan entitles the organisation for the paid month or year (GET /v1/plan-entitlement), and the order requests are marked paid; packs and reports are delivered by hand. While Rewalto is not GST-registered, or online payment is off on this host, a correctly priced basket is answered checkout_unavailable (503): send it as an order request (POST /v1/order-requests) instead. Organisation admins only, with a session and a saved billing profile.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "url",
                        "quote"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "payment_link",
                            "subscription"
                          ]
                        },
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "quote": {
                          "type": "object",
                          "title": "Basket quote",
                          "additionalProperties": false,
                          "required": [
                            "lines",
                            "subtotalPaise",
                            "gstPaise",
                            "totalPaise",
                            "period",
                            "monthlyPaise",
                            "monthlyTotalPaise",
                            "gstRateBp"
                          ],
                          "properties": {
                            "lines": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                  "label",
                                  "amountPaise",
                                  "period"
                                ],
                                "properties": {
                                  "label": {
                                    "type": "string"
                                  },
                                  "amountPaise": {
                                    "type": "integer",
                                    "minimum": 0
                                  },
                                  "period": {
                                    "type": "string",
                                    "enum": [
                                      "once",
                                      "month",
                                      "year"
                                    ]
                                  }
                                }
                              }
                            },
                            "subtotalPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "description": "Paid today, before GST."
                            },
                            "gstPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "description": "GST on the subtotal at gstRateBp."
                            },
                            "totalPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "description": "Paid today, with GST: compare expectedTotalPaise to it."
                            },
                            "period": {
                              "type": "string",
                              "enum": [
                                "month",
                                "once"
                              ],
                              "description": "month: any monthly line, so one subscription. once: one payment link."
                            },
                            "monthlyPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "description": "What repeats each month, before GST."
                            },
                            "monthlyTotalPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "description": "What repeats each month, with GST."
                            },
                            "gstRateBp": {
                              "type": "integer",
                              "minimum": 0,
                              "description": "The GST rate of the supplier version in force, in basis points (0 while not GST-registered)."
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `billing_profile_missing`: retry advice `never`\n- `export_not_available`: retry advice `never`\n- `idempotency_conflict`: retry advice `never`\n- `invoicing_unavailable`: retry advice `never`\n- `price_changed`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `checkout_unavailable`: retry advice `bounded`\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Basket",
                "additionalProperties": false,
                "required": [
                  "items",
                  "expectedTotalPaise"
                ],
                "properties": {
                  "items": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "product",
                        "billing"
                      ],
                      "properties": {
                        "product": {
                          "type": "string",
                          "pattern": "^[a-z][a-z0-9_]{1,40}$",
                          "description": "A price-list offer key (brand plans, packs, reports) or a credit plan: api_starter, api_growth, api_scale, api_top_up."
                        },
                        "billing": {
                          "type": "string",
                          "enum": [
                            "monthly",
                            "yearly",
                            "once"
                          ],
                          "description": "monthly or yearly (10 × monthly) for a brand plan; packs and reports are paid once."
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 1000,
                          "description": "Packs: how many apps or cities. Top-ups: how many thousand credits. Default 1."
                        },
                        "addOns": {
                          "type": "object",
                          "additionalProperties": false,
                          "description": "Steps of each add-on (cities: 3 is 3 more cities, products: 2 is 100 more), or true for a flag.",
                          "properties": {
                            "products": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "cities": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "pincodes": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "darkStores": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "apps": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "competitors": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "keywords": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "categories": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "marketplaces": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "national": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            }
                          }
                        },
                        "twiceDaily": {
                          "type": "boolean",
                          "description": "A brand plan read twice a day: +50% of the plan price."
                        },
                        "refresh": {
                          "type": "boolean",
                          "description": "A pack kept fresh daily: its monthly refresh price."
                        },
                        "repeatMonthly": {
                          "type": "boolean",
                          "description": "A report repeated each month: 60% of its one-off price, plus its add-ons, every month after."
                        }
                      }
                    }
                  },
                  "expectedTotalPaise": {
                    "type": "integer",
                    "minimum": 0,
                    "description": "The total paid today, with GST, that the buyer was shown. Core prices the basket itself; a different total is refused (price_changed) and nothing is created."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/basket/quote": {
      "post": {
        "operationId": "quoteBasket",
        "summary": "Price a basket",
        "description": "Prices a basket of brand plans (monthly or yearly, with add-on steps and twice-daily reads), dataset packs (with daily refresh), reports (with add-ons, repeated monthly) and credit plans from the price list in force, exactly as POST /v1/billing/basket will: the lines, what is paid today before and with GST, and what repeats each month. GST is the rate of the supplier version in force (0 while Rewalto is not GST-registered, D-1879). Public and free; nothing is created.",
        "tags": [
          "Plans"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Basket quote",
                      "additionalProperties": false,
                      "required": [
                        "lines",
                        "subtotalPaise",
                        "gstPaise",
                        "totalPaise",
                        "period",
                        "monthlyPaise",
                        "monthlyTotalPaise",
                        "gstRateBp"
                      ],
                      "properties": {
                        "lines": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "label",
                              "amountPaise",
                              "period"
                            ],
                            "properties": {
                              "label": {
                                "type": "string"
                              },
                              "amountPaise": {
                                "type": "integer",
                                "minimum": 0
                              },
                              "period": {
                                "type": "string",
                                "enum": [
                                  "once",
                                  "month",
                                  "year"
                                ]
                              }
                            }
                          }
                        },
                        "subtotalPaise": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "Paid today, before GST."
                        },
                        "gstPaise": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "GST on the subtotal at gstRateBp."
                        },
                        "totalPaise": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "Paid today, with GST: compare expectedTotalPaise to it."
                        },
                        "period": {
                          "type": "string",
                          "enum": [
                            "month",
                            "once"
                          ],
                          "description": "month: any monthly line, so one subscription. once: one payment link."
                        },
                        "monthlyPaise": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "What repeats each month, before GST."
                        },
                        "monthlyTotalPaise": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "What repeats each month, with GST."
                        },
                        "gstRateBp": {
                          "type": "integer",
                          "minimum": 0,
                          "description": "The GST rate of the supplier version in force, in basis points (0 while not GST-registered)."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Basket",
                "additionalProperties": false,
                "required": [
                  "items"
                ],
                "properties": {
                  "items": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 20,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "product",
                        "billing"
                      ],
                      "properties": {
                        "product": {
                          "type": "string",
                          "pattern": "^[a-z][a-z0-9_]{1,40}$",
                          "description": "A price-list offer key (brand plans, packs, reports) or a credit plan: api_starter, api_growth, api_scale, api_top_up."
                        },
                        "billing": {
                          "type": "string",
                          "enum": [
                            "monthly",
                            "yearly",
                            "once"
                          ],
                          "description": "monthly or yearly (10 × monthly) for a brand plan; packs and reports are paid once."
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 1000,
                          "description": "Packs: how many apps or cities. Top-ups: how many thousand credits. Default 1."
                        },
                        "addOns": {
                          "type": "object",
                          "additionalProperties": false,
                          "description": "Steps of each add-on (cities: 3 is 3 more cities, products: 2 is 100 more), or true for a flag.",
                          "properties": {
                            "products": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "cities": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "pincodes": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "darkStores": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "apps": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "competitors": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "keywords": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "categories": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "marketplaces": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            },
                            "national": {
                              "description": "A whole number of steps (0 to 1000), or true or false for a flag.",
                              "oneOf": [
                                {
                                  "type": "integer",
                                  "minimum": 0,
                                  "maximum": 1000
                                },
                                {
                                  "type": "boolean"
                                }
                              ]
                            }
                          }
                        },
                        "twiceDaily": {
                          "type": "boolean",
                          "description": "A brand plan read twice a day: +50% of the plan price."
                        },
                        "refresh": {
                          "type": "boolean",
                          "description": "A pack kept fresh daily: its monthly refresh price."
                        },
                        "repeatMonthly": {
                          "type": "boolean",
                          "description": "A report repeated each month: 60% of its one-off price, plus its add-ons, every month after."
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/cashfree/subscriptions-webhook": {
      "post": {
        "operationId": "cashfreeSubscriptionsWebhook",
        "summary": "Cashfree Subscriptions webhook",
        "description": "For Cashfree only: the webhook of Cashfree Subscriptions (registered separately from the payment webhook). The same signature check and 5-minute limit as the payment webhook; every verified event is recorded once (its hash, type, ids, status and amount; never the body) and nothing else is done with it. Answers 200 once recorded, also for repeats, so Cashfree stops retrying.",
        "tags": [
          "Billing"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Webhook received",
                  "description": "Cashfree may stop retrying.",
                  "additionalProperties": false,
                  "required": [
                    "received"
                  ],
                  "properties": {
                    "received": {
                      "type": "boolean",
                      "title": "Received",
                      "description": "Always true once the signature checks.",
                      "examples": [
                        true
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Cashfree webhook",
                "description": "A Cashfree payment gateway webhook (API version 2023-08-01), signed. Sent by Cashfree only.",
                "additionalProperties": true
              }
            }
          }
        }
      }
    },
    "/v1/billing/cashfree/webhook": {
      "post": {
        "operationId": "cashfreeWebhook",
        "summary": "Cashfree payment webhook",
        "description": "For Cashfree only. The signature (x-webhook-signature over x-webhook-timestamp and the raw body, with Rewalto’s Cashfree secret key) is checked before anything else, and a timestamp older than 5 minutes is refused. Every verified event is recorded once (its hash, type, ids, status and amount; never the body). A payment success for a Core order is then re-checked with Cashfree’s own API and recorded once (the credits or the plan month); other events, and events for orders the old site made, are only recorded. Answers 200 once handled, also for repeats, so Cashfree stops retrying.",
        "tags": [
          "Billing"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Webhook received",
                  "description": "Cashfree may stop retrying.",
                  "additionalProperties": false,
                  "required": [
                    "received"
                  ],
                  "properties": {
                    "received": {
                      "type": "boolean",
                      "title": "Received",
                      "description": "Always true once the signature checks.",
                      "examples": [
                        true
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Cashfree webhook",
                "description": "A Cashfree payment gateway webhook (API version 2023-08-01), signed. Sent by Cashfree only.",
                "additionalProperties": true
              }
            }
          }
        }
      }
    },
    "/v1/billing/invoices/{id}": {
      "get": {
        "operationId": "getInvoice",
        "summary": "Get an invoice",
        "description": "The document of a paid order (its `invoiceId`), built only from the stored order, payment and tax rows. `documentKind` says which: a **receipt** while Rewalto is not registered for GST (D-1879): the number, the supplier (Rewalto: legal name and address, no GSTIN), the buyer, the line without a SAC code, no taxes, the total paid (exactly the listed price) and `gstNote` (Rewalto is not registered for GST; this is a receipt, not a GST invoice). A **tax invoice** once registered: the supplier’s GSTIN, the line with its SAC code, CGST + SGST (buyer in Rewalto’s state) or IGST (another state), or the LUT wording on an export. Numbers are RW/<financial year>/<6 digits>, consecutive, never skipped or reused. Sandbox payments carry TEST documents, marked as test money (and, while Rewalto’s details are placeholders, saying so). JSON; a PDF comes later. Organisation admins only, with a session.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Invoice",
                  "description": "One invoice.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Invoice",
                      "description": "The document of a paid order, from the stored order, payment and tax rows (never priced again): a tax invoice while Rewalto is GST-registered, a receipt while it is not (D-1879: no supplier GSTIN, no SAC, no taxes, the amount paid is the listed price).",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "number",
                        "series",
                        "financialYear",
                        "issuedAt",
                        "environment",
                        "documentKind",
                        "title",
                        "supplierPlaceholder",
                        "supplier",
                        "buyer",
                        "placeOfSupply",
                        "orderId",
                        "payment",
                        "lines",
                        "taxes",
                        "totals",
                        "exportNote",
                        "placeholderNote",
                        "gstNote"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The invoice id.",
                          "examples": [
                            "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                          ],
                          "format": "uuid"
                        },
                        "number": {
                          "type": "string",
                          "title": "Number",
                          "description": "Consecutive per series and financial year, never skipped or reused: RW/<FY>/<6 digits> in production, TEST/... for sandbox.",
                          "examples": [
                            "RW/2627/000001"
                          ],
                          "maxLength": 16
                        },
                        "series": {
                          "type": "string",
                          "enum": [
                            "RW",
                            "TEST"
                          ],
                          "title": "Series",
                          "description": "RW for production; TEST for sandbox (test money).",
                          "examples": [
                            "RW"
                          ]
                        },
                        "financialYear": {
                          "type": "string",
                          "title": "Financial year",
                          "description": "April to March, IST: 2627 is 2026-27.",
                          "examples": [
                            "2627"
                          ],
                          "pattern": "^[0-9]{4}$"
                        },
                        "issuedAt": {
                          "type": "string",
                          "title": "Issued at",
                          "description": "When the payment was recorded and the number issued.",
                          "examples": [
                            "2026-10-19T10:02:01.000Z"
                          ],
                          "format": "date-time"
                        },
                        "environment": {
                          "type": "string",
                          "enum": [
                            "sandbox",
                            "production"
                          ],
                          "title": "Environment",
                          "description": "sandbox or production.",
                          "examples": [
                            "sandbox"
                          ]
                        },
                        "documentKind": {
                          "type": "string",
                          "enum": [
                            "tax_invoice",
                            "receipt"
                          ],
                          "title": "Document kind",
                          "description": "tax_invoice while Rewalto is registered for GST; receipt while it is not (D-1879). Sent from contract 0.47.0.",
                          "examples": [
                            "tax_invoice"
                          ]
                        },
                        "title": {
                          "type": "string",
                          "title": "Title",
                          "description": "What to print at the top: Tax invoice or Receipt (sandbox: Test invoice (sandbox): not a tax invoice, or Test receipt (sandbox)).",
                          "examples": [
                            "Receipt"
                          ]
                        },
                        "supplierPlaceholder": {
                          "type": "boolean",
                          "title": "Placeholder supplier",
                          "description": "True while Rewalto’s supplier details are placeholders (D-1825): only TEST invoices can carry them; production invoices are refused until the real details are recorded.",
                          "examples": [
                            false
                          ]
                        },
                        "supplier": {
                          "type": "object",
                          "title": "Supplier",
                          "description": "Rewalto, at the tax setting version the document names.",
                          "additionalProperties": false,
                          "required": [
                            "legalName",
                            "address",
                            "gstin",
                            "stateCode"
                          ],
                          "properties": {
                            "legalName": {
                              "type": "string",
                              "title": "Legal name",
                              "description": "Rewalto’s legal name.",
                              "examples": [
                                "Rewalto Private Limited"
                              ]
                            },
                            "address": {
                              "type": "string",
                              "title": "Address",
                              "description": "Rewalto’s registered address.",
                              "examples": [
                                "Bengaluru, Karnataka"
                              ]
                            },
                            "gstin": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "GSTIN",
                              "description": "Rewalto’s GSTIN on a tax invoice; null on a receipt (not registered for GST, from contract 0.47.0).",
                              "examples": [
                                "29ABCDE1234F1Z5"
                              ]
                            },
                            "stateCode": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "State",
                              "description": "The GST state code of Rewalto’s registration on a tax invoice; null on a receipt (from contract 0.47.0).",
                              "examples": [
                                "29"
                              ]
                            }
                          }
                        },
                        "buyer": {
                          "type": "object",
                          "title": "Buyer",
                          "description": "The buyer, as the order was made.",
                          "additionalProperties": false,
                          "required": [
                            "legalName",
                            "address",
                            "country",
                            "stateCode",
                            "gstin"
                          ],
                          "properties": {
                            "legalName": {
                              "type": "string",
                              "title": "Legal name",
                              "description": "The buyer’s legal name, as the tax invoice shows it.",
                              "examples": [
                                "Acme Retail Pvt Ltd"
                              ],
                              "minLength": 1,
                              "maxLength": 200
                            },
                            "address": {
                              "type": "string",
                              "title": "Address",
                              "description": "The buyer’s registered address.",
                              "examples": [
                                "1 MG Road, Bengaluru 560001"
                              ],
                              "minLength": 1,
                              "maxLength": 500
                            },
                            "country": {
                              "type": "string",
                              "title": "Country",
                              "description": "ISO 3166-1 alpha-2 country code.",
                              "examples": [
                                "IN"
                              ],
                              "pattern": "^[A-Z]{2}$"
                            },
                            "stateCode": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "State",
                              "description": "The two-digit GST state code of the buyer, required in India (it decides CGST + SGST or IGST); null outside India.",
                              "examples": [
                                "29"
                              ],
                              "pattern": "^[0-9]{2}$"
                            },
                            "gstin": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "GSTIN",
                              "description": "The buyer’s GSTIN, if registered (for input tax credit); its first two digits must be the state code.",
                              "examples": [
                                "29ABCDE1234F1Z5"
                              ],
                              "pattern": "^[0-9]{2}[0-9A-Z]{13}$"
                            }
                          }
                        },
                        "placeOfSupply": {
                          "type": "string",
                          "title": "Place of supply",
                          "description": "The buyer’s GST state code, or `export`.",
                          "examples": [
                            "29"
                          ]
                        },
                        "orderId": {
                          "type": "string",
                          "title": "Order",
                          "description": "The order this invoice is for.",
                          "examples": [
                            "3f1a9c2e-7b4d-4e8a-9c1f-0a2b3c4d5e6f"
                          ],
                          "format": "uuid"
                        },
                        "payment": {
                          "type": "object",
                          "title": "Payment",
                          "description": "The Cashfree payment.",
                          "additionalProperties": false,
                          "required": [
                            "provider",
                            "cfPaymentId",
                            "method",
                            "paidAt"
                          ],
                          "properties": {
                            "provider": {
                              "type": "string",
                              "enum": [
                                "cashfree",
                                "razorpay"
                              ],
                              "title": "Provider",
                              "description": "The provider that captured this historical payment.",
                              "examples": [
                                "cashfree"
                              ]
                            },
                            "cfPaymentId": {
                              "type": "string",
                              "title": "Cashfree payment",
                              "description": "Provider payment id; legacy field name retained for compatibility.",
                              "examples": [
                                "5114915226"
                              ]
                            },
                            "method": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Method",
                              "description": "How it was paid, as Cashfree reports it.",
                              "examples": [
                                "upi"
                              ]
                            },
                            "paidAt": {
                              "type": "string",
                              "title": "Paid at",
                              "description": "When Cashfree took the payment.",
                              "examples": [
                                "2026-10-19T10:02:00.000Z"
                              ],
                              "format": "date-time"
                            }
                          }
                        },
                        "lines": {
                          "type": "array",
                          "title": "Lines",
                          "description": "What was supplied (one line today).",
                          "items": {
                            "type": "object",
                            "title": "Line",
                            "description": "One supply.",
                            "additionalProperties": false,
                            "required": [
                              "description",
                              "sac",
                              "quantity",
                              "unit",
                              "amountPaise"
                            ],
                            "properties": {
                              "description": {
                                "type": "string",
                                "title": "Description",
                                "description": "What was bought.",
                                "examples": [
                                  "Rewalto data credits (top-up)"
                                ]
                              },
                              "sac": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "SAC",
                                "description": "The service accounting code on a tax invoice; null on a receipt (from contract 0.47.0).",
                                "examples": [
                                  "998431"
                                ]
                              },
                              "quantity": {
                                "type": "integer",
                                "minimum": 1,
                                "title": "Quantity",
                                "description": "Credits supplied, or 1 for a basket line.",
                                "examples": [
                                  1500
                                ]
                              },
                              "unit": {
                                "type": "string",
                                "enum": [
                                  "credits",
                                  "items"
                                ],
                                "title": "Unit",
                                "description": "credits for a credit order; items for a line of a basket order (brand plans, packs, reports, contract 0.100.0).",
                                "examples": [
                                  "credits"
                                ]
                              },
                              "amountPaise": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Amount",
                                "description": "The taxable value. In integer paise.",
                                "examples": [
                                  150000
                                ]
                              }
                            }
                          }
                        },
                        "taxes": {
                          "type": "array",
                          "title": "Taxes",
                          "description": "CGST and SGST (buyer in Rewalto’s state), IGST (another state), or none (export under the LUT, or a receipt: not registered for GST).",
                          "items": {
                            "type": "object",
                            "title": "Tax",
                            "description": "One tax.",
                            "additionalProperties": false,
                            "required": [
                              "kind",
                              "ratePercent",
                              "amountPaise"
                            ],
                            "properties": {
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "CGST",
                                  "SGST",
                                  "IGST"
                                ],
                                "title": "Kind",
                                "description": "Which GST.",
                                "examples": [
                                  "CGST"
                                ]
                              },
                              "ratePercent": {
                                "type": "number",
                                "minimum": 0,
                                "title": "Rate",
                                "description": "Percent.",
                                "examples": [
                                  9
                                ]
                              },
                              "amountPaise": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Amount",
                                "description": "The tax. In integer paise.",
                                "examples": [
                                  13500
                                ]
                              }
                            }
                          }
                        },
                        "totals": {
                          "type": "object",
                          "title": "Totals",
                          "description": "The sums.",
                          "additionalProperties": false,
                          "required": [
                            "taxablePaise",
                            "taxPaise",
                            "totalPaise",
                            "currency"
                          ],
                          "properties": {
                            "taxablePaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "Taxable value",
                              "description": "Before GST. In integer paise.",
                              "examples": [
                                150000
                              ]
                            },
                            "taxPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "Tax",
                              "description": "All GST. In integer paise.",
                              "examples": [
                                27000
                              ]
                            },
                            "totalPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "Total",
                              "description": "What was paid. In integer paise.",
                              "examples": [
                                177000
                              ]
                            },
                            "currency": {
                              "type": "string",
                              "enum": [
                                "INR"
                              ],
                              "title": "Currency",
                              "description": "Always INR.",
                              "examples": [
                                "INR"
                              ]
                            }
                          }
                        },
                        "exportNote": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Export note",
                          "description": "On an export: supply meant for export under the LUT without payment of IGST, with the LUT reference.",
                          "examples": [
                            "Supply meant for export under LUT without payment of integrated tax (IGST). LUT AD290000000000X dated 2026-10-01."
                          ]
                        },
                        "placeholderNote": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Placeholder note",
                          "description": "On a sandbox invoice: why it is not a tax invoice.",
                          "examples": [
                            "Sandbox test invoice with placeholder supplier details (D-1825): not a tax invoice."
                          ]
                        },
                        "gstNote": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "GST note",
                          "description": "On a receipt: that Rewalto is not registered for GST and this is not a GST invoice (D-1879); null on a tax invoice. Sent from contract 0.47.0.",
                          "examples": [
                            "Rewalto is not registered for GST; this is a receipt, not a GST invoice."
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The invoice id (an order’s invoiceId).",
              "examples": [
                "7c9e6679-7425-40de-944b-e07fc1f90ae7"
              ],
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/billing/orders": {
      "post": {
        "operationId": "createOrder",
        "summary": "Make an order and get Razorpay checkout",
        "description": "Makes an order for a top-up of `credits` (at least the top-up’s minCredits on /v1/plans, today 1,000; at most 1,000,000; any organisation, Free tier included, D-1824) or one month of the plan `tierKey`. The database prices it from the tier in force and the billing profile: while Rewalto is not registered for GST (D-1879) the total is exactly the listed price, with no GST; once registered, price before GST plus CGST + SGST or IGST, or no GST for an export under the LUT. Answers with the order and `checkout` (Razorpay Standard Checkout parameters for new purchases) to pay it. Nothing is charged here: the credits come only when Cashfree confirms the payment (watch getOrder). Always 200: the same request with the same idempotency-key returns the same order, never a second one. Sent with Cache-Control: no-store. Organisation admins only, with a session.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Order made",
                  "description": "The order and how to pay it.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Order and checkout",
                      "description": "The order, and Cashfree’s checkout while it can be paid.",
                      "additionalProperties": false,
                      "required": [
                        "order",
                        "checkout"
                      ],
                      "properties": {
                        "order": {
                          "type": "object",
                          "title": "Order",
                          "description": "A Cashfree order and what it buys.",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "kind",
                            "tierKey",
                            "tierVersion",
                            "credits",
                            "environment",
                            "buyer",
                            "placeOfSupply",
                            "amounts",
                            "status",
                            "createdAt",
                            "expiresAt",
                            "paidAt",
                            "invoiceNumber",
                            "invoiceId"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "title": "Id",
                              "description": "The order id (also Cashfree’s order_id).",
                              "examples": [
                                "3f1a9c2e-7b4d-4e8a-9c1f-0a2b3c4d5e6f"
                              ],
                              "format": "uuid"
                            },
                            "kind": {
                              "type": "string",
                              "enum": [
                                "top_up",
                                "plan"
                              ],
                              "title": "Kind",
                              "description": "top_up or plan.",
                              "examples": [
                                "top_up"
                              ]
                            },
                            "tierKey": {
                              "type": "string",
                              "title": "Tier",
                              "description": "The tier bought: top_up or the plan’s key.",
                              "examples": [
                                "top_up"
                              ]
                            },
                            "tierVersion": {
                              "type": "integer",
                              "minimum": 1,
                              "title": "Tier version",
                              "description": "The tier price version the order was priced on.",
                              "examples": [
                                2
                              ]
                            },
                            "credits": {
                              "type": "integer",
                              "minimum": 1,
                              "title": "Credits",
                              "description": "Credits it gives once paid (paid credits, 12 months, C-012).",
                              "examples": [
                                5000
                              ]
                            },
                            "environment": {
                              "type": "string",
                              "enum": [
                                "sandbox",
                                "production"
                              ],
                              "title": "Environment",
                              "description": "sandbox (staging, test money) or production.",
                              "examples": [
                                "sandbox"
                              ]
                            },
                            "buyer": {
                              "type": "object",
                              "title": "Buyer",
                              "description": "The buyer details the order was made with.",
                              "additionalProperties": false,
                              "required": [
                                "legalName",
                                "country",
                                "stateCode",
                                "gstin"
                              ],
                              "properties": {
                                "legalName": {
                                  "type": "string",
                                  "title": "Legal name",
                                  "description": "The buyer’s legal name, as the tax invoice shows it.",
                                  "examples": [
                                    "Acme Retail Pvt Ltd"
                                  ],
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                "country": {
                                  "type": "string",
                                  "title": "Country",
                                  "description": "ISO 3166-1 alpha-2 country code.",
                                  "examples": [
                                    "IN"
                                  ],
                                  "pattern": "^[A-Z]{2}$"
                                },
                                "stateCode": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "State",
                                  "description": "The two-digit GST state code of the buyer, required in India (it decides CGST + SGST or IGST); null outside India.",
                                  "examples": [
                                    "29"
                                  ],
                                  "pattern": "^[0-9]{2}$"
                                },
                                "gstin": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "GSTIN",
                                  "description": "The buyer’s GSTIN, if registered (for input tax credit); its first two digits must be the state code.",
                                  "examples": [
                                    "29ABCDE1234F1Z5"
                                  ],
                                  "pattern": "^[0-9]{2}[0-9A-Z]{13}$"
                                }
                              }
                            },
                            "placeOfSupply": {
                              "type": "string",
                              "title": "Place of supply",
                              "description": "The buyer’s GST state code, or `export`.",
                              "examples": [
                                "29"
                              ]
                            },
                            "amounts": {
                              "type": "object",
                              "title": "Amounts",
                              "description": "In integer paise. While Rewalto is not registered for GST (D-1879) there is no GST: every GST field is 0 and the total is the price. Once registered: CGST + SGST when the buyer is in Rewalto’s state, IGST in another state, none for an export under the LUT.",
                              "additionalProperties": false,
                              "required": [
                                "basePaise",
                                "cgstPaise",
                                "sgstPaise",
                                "igstPaise",
                                "totalPaise",
                                "currency"
                              ],
                              "properties": {
                                "basePaise": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "Price",
                                  "description": "The listed price, from the tier in force.",
                                  "examples": [
                                    149900
                                  ]
                                },
                                "cgstPaise": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "CGST",
                                  "description": "Central GST; 0 while Rewalto is not GST-registered.",
                                  "examples": [
                                    0
                                  ]
                                },
                                "sgstPaise": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "SGST",
                                  "description": "State GST; 0 while Rewalto is not GST-registered.",
                                  "examples": [
                                    0
                                  ]
                                },
                                "igstPaise": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "IGST",
                                  "description": "Integrated GST; 0 while Rewalto is not GST-registered.",
                                  "examples": [
                                    0
                                  ]
                                },
                                "totalPaise": {
                                  "type": "integer",
                                  "minimum": 1,
                                  "title": "Total",
                                  "description": "What the buyer pays: the price plus any GST (exactly the price while Rewalto is not GST-registered).",
                                  "examples": [
                                    149900
                                  ]
                                },
                                "currency": {
                                  "type": "string",
                                  "enum": [
                                    "INR"
                                  ],
                                  "title": "Currency",
                                  "description": "Always INR.",
                                  "examples": [
                                    "INR"
                                  ]
                                }
                              }
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "created",
                                "paid",
                                "expired"
                              ],
                              "title": "Status",
                              "description": "created: not paid yet. paid: Cashfree confirmed the payment and the credits (or plan) were given. expired: not paid within a day; make a new order.",
                              "examples": [
                                "created"
                              ]
                            },
                            "createdAt": {
                              "type": "string",
                              "title": "Created at",
                              "description": "When the order was made.",
                              "examples": [
                                "2026-10-19T10:00:00.000Z"
                              ],
                              "format": "date-time"
                            },
                            "expiresAt": {
                              "type": "string",
                              "title": "Expires at",
                              "description": "Pay before this.",
                              "examples": [
                                "2026-10-20T10:00:00.000Z"
                              ],
                              "format": "date-time"
                            },
                            "paidAt": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Paid at",
                              "description": "When Cashfree took the payment; null until paid.",
                              "examples": [
                                "2026-10-19T10:02:00.000Z"
                              ],
                              "format": "date-time"
                            },
                            "invoiceNumber": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Invoice number",
                              "description": "The tax invoice number, once paid: RW/<financial year>/<6 digits>; TEST/... for sandbox orders.",
                              "examples": [
                                "RW/2627/000001"
                              ]
                            },
                            "invoiceId": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Invoice",
                              "description": "The invoice id once paid (GET /v1/billing/invoices/{id}); null until paid. Sent from contract 0.40.0.",
                              "examples": [
                                "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                              ],
                              "format": "uuid"
                            }
                          }
                        },
                        "checkout": {
                          "oneOf": [
                            {
                              "type": "object",
                              "title": "Cashfree checkout",
                              "description": "Historical Cashfree checkout.",
                              "additionalProperties": false,
                              "required": [
                                "provider",
                                "environment",
                                "paymentSessionId"
                              ],
                              "properties": {
                                "provider": {
                                  "type": "string",
                                  "enum": [
                                    "cashfree"
                                  ],
                                  "title": "Provider",
                                  "description": "Historical provider.",
                                  "examples": [
                                    "cashfree"
                                  ]
                                },
                                "environment": {
                                  "type": "string",
                                  "enum": [
                                    "sandbox",
                                    "production"
                                  ],
                                  "title": "Environment",
                                  "description": "Provider environment.",
                                  "examples": [
                                    "sandbox"
                                  ]
                                },
                                "paymentSessionId": {
                                  "type": "string",
                                  "title": "Payment session",
                                  "description": "Cashfree session.",
                                  "examples": [
                                    "session_abc123"
                                  ]
                                }
                              }
                            },
                            {
                              "type": "object",
                              "title": "Razorpay checkout",
                              "description": "Use Razorpay Standard Checkout; order_id or subscription_id is supplied by the server.",
                              "additionalProperties": false,
                              "required": [
                                "provider",
                                "environment",
                                "keyId",
                                "amountPaise",
                                "currency"
                              ],
                              "properties": {
                                "provider": {
                                  "type": "string",
                                  "const": "razorpay"
                                },
                                "environment": {
                                  "type": "string",
                                  "enum": [
                                    "sandbox",
                                    "production"
                                  ],
                                  "title": "Environment",
                                  "description": "Provider environment.",
                                  "examples": [
                                    "sandbox"
                                  ]
                                },
                                "keyId": {
                                  "type": "string",
                                  "title": "Key ID",
                                  "description": "Public Razorpay key ID. Never a secret.",
                                  "examples": [
                                    "rzp_test_example"
                                  ]
                                },
                                "orderId": {
                                  "type": "string",
                                  "title": "Order ID",
                                  "description": "One-time Razorpay order.",
                                  "examples": [
                                    "order_example"
                                  ]
                                },
                                "subscriptionId": {
                                  "type": "string",
                                  "title": "Subscription ID",
                                  "description": "Recurring Razorpay subscription.",
                                  "examples": [
                                    "sub_example"
                                  ]
                                },
                                "amountPaise": {
                                  "type": "integer",
                                  "minimum": 1,
                                  "title": "Amount",
                                  "description": "GST-inclusive amount in paise.",
                                  "examples": [
                                    177000
                                  ]
                                },
                                "currency": {
                                  "type": "string",
                                  "const": "INR"
                                }
                              }
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `billing_profile_missing`: retry advice `never`\n- `export_not_available`: retry advice `never`\n- `idempotency_conflict`: retry advice `never`\n- `invoicing_unavailable`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "idempotency-key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "examples": [
                "8f14e45f-ceea-467a-9f3c-2a1b5d7e6c11"
              ]
            },
            "description": "A key you choose for this purchase. Sending the same request with the same key returns the same order (no second order, no second charge); the same key with a different request is refused with idempotency_conflict."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Create order",
                "description": "What to buy: a top-up of `credits` (at least the top-up’s minCredits on /v1/plans, at most 1,000,000), or one month of the plan `tierKey`.",
                "additionalProperties": false,
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "top_up",
                      "plan"
                    ],
                    "title": "Kind",
                    "description": "top_up: credits bought on their own. plan: one month of a paid plan.",
                    "examples": [
                      "top_up"
                    ]
                  },
                  "credits": {
                    "type": "integer",
                    "minimum": 1,
                    "title": "Credits",
                    "description": "For a top-up: how many credits.",
                    "examples": [
                      5000
                    ]
                  },
                  "tierKey": {
                    "type": "string",
                    "title": "Plan",
                    "description": "For a plan: its tier key on /v1/plans.",
                    "examples": [
                      "starter"
                    ],
                    "pattern": "^[a-z][a-z0-9_]{1,30}$"
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listOrders",
        "summary": "List orders",
        "description": "The organisation’s orders, newest first (at most 50), with their status: created (not paid), paid (credits or plan given, invoice number set) or expired. Organisation admins only, with a session.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Orders",
                  "description": "The organisation’s orders, newest first (at most 50).",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Orders",
                      "description": "The orders.",
                      "items": {
                        "type": "object",
                        "title": "Order",
                        "description": "A Cashfree order and what it buys.",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "kind",
                          "tierKey",
                          "tierVersion",
                          "credits",
                          "environment",
                          "buyer",
                          "placeOfSupply",
                          "amounts",
                          "status",
                          "createdAt",
                          "expiresAt",
                          "paidAt",
                          "invoiceNumber",
                          "invoiceId"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "title": "Id",
                            "description": "The order id (also Cashfree’s order_id).",
                            "examples": [
                              "3f1a9c2e-7b4d-4e8a-9c1f-0a2b3c4d5e6f"
                            ],
                            "format": "uuid"
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "top_up",
                              "plan"
                            ],
                            "title": "Kind",
                            "description": "top_up or plan.",
                            "examples": [
                              "top_up"
                            ]
                          },
                          "tierKey": {
                            "type": "string",
                            "title": "Tier",
                            "description": "The tier bought: top_up or the plan’s key.",
                            "examples": [
                              "top_up"
                            ]
                          },
                          "tierVersion": {
                            "type": "integer",
                            "minimum": 1,
                            "title": "Tier version",
                            "description": "The tier price version the order was priced on.",
                            "examples": [
                              2
                            ]
                          },
                          "credits": {
                            "type": "integer",
                            "minimum": 1,
                            "title": "Credits",
                            "description": "Credits it gives once paid (paid credits, 12 months, C-012).",
                            "examples": [
                              5000
                            ]
                          },
                          "environment": {
                            "type": "string",
                            "enum": [
                              "sandbox",
                              "production"
                            ],
                            "title": "Environment",
                            "description": "sandbox (staging, test money) or production.",
                            "examples": [
                              "sandbox"
                            ]
                          },
                          "buyer": {
                            "type": "object",
                            "title": "Buyer",
                            "description": "The buyer details the order was made with.",
                            "additionalProperties": false,
                            "required": [
                              "legalName",
                              "country",
                              "stateCode",
                              "gstin"
                            ],
                            "properties": {
                              "legalName": {
                                "type": "string",
                                "title": "Legal name",
                                "description": "The buyer’s legal name, as the tax invoice shows it.",
                                "examples": [
                                  "Acme Retail Pvt Ltd"
                                ],
                                "minLength": 1,
                                "maxLength": 200
                              },
                              "country": {
                                "type": "string",
                                "title": "Country",
                                "description": "ISO 3166-1 alpha-2 country code.",
                                "examples": [
                                  "IN"
                                ],
                                "pattern": "^[A-Z]{2}$"
                              },
                              "stateCode": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "State",
                                "description": "The two-digit GST state code of the buyer, required in India (it decides CGST + SGST or IGST); null outside India.",
                                "examples": [
                                  "29"
                                ],
                                "pattern": "^[0-9]{2}$"
                              },
                              "gstin": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "GSTIN",
                                "description": "The buyer’s GSTIN, if registered (for input tax credit); its first two digits must be the state code.",
                                "examples": [
                                  "29ABCDE1234F1Z5"
                                ],
                                "pattern": "^[0-9]{2}[0-9A-Z]{13}$"
                              }
                            }
                          },
                          "placeOfSupply": {
                            "type": "string",
                            "title": "Place of supply",
                            "description": "The buyer’s GST state code, or `export`.",
                            "examples": [
                              "29"
                            ]
                          },
                          "amounts": {
                            "type": "object",
                            "title": "Amounts",
                            "description": "In integer paise. While Rewalto is not registered for GST (D-1879) there is no GST: every GST field is 0 and the total is the price. Once registered: CGST + SGST when the buyer is in Rewalto’s state, IGST in another state, none for an export under the LUT.",
                            "additionalProperties": false,
                            "required": [
                              "basePaise",
                              "cgstPaise",
                              "sgstPaise",
                              "igstPaise",
                              "totalPaise",
                              "currency"
                            ],
                            "properties": {
                              "basePaise": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Price",
                                "description": "The listed price, from the tier in force.",
                                "examples": [
                                  149900
                                ]
                              },
                              "cgstPaise": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "CGST",
                                "description": "Central GST; 0 while Rewalto is not GST-registered.",
                                "examples": [
                                  0
                                ]
                              },
                              "sgstPaise": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "SGST",
                                "description": "State GST; 0 while Rewalto is not GST-registered.",
                                "examples": [
                                  0
                                ]
                              },
                              "igstPaise": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "IGST",
                                "description": "Integrated GST; 0 while Rewalto is not GST-registered.",
                                "examples": [
                                  0
                                ]
                              },
                              "totalPaise": {
                                "type": "integer",
                                "minimum": 1,
                                "title": "Total",
                                "description": "What the buyer pays: the price plus any GST (exactly the price while Rewalto is not GST-registered).",
                                "examples": [
                                  149900
                                ]
                              },
                              "currency": {
                                "type": "string",
                                "enum": [
                                  "INR"
                                ],
                                "title": "Currency",
                                "description": "Always INR.",
                                "examples": [
                                  "INR"
                                ]
                              }
                            }
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "created",
                              "paid",
                              "expired"
                            ],
                            "title": "Status",
                            "description": "created: not paid yet. paid: Cashfree confirmed the payment and the credits (or plan) were given. expired: not paid within a day; make a new order.",
                            "examples": [
                              "created"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "title": "Created at",
                            "description": "When the order was made.",
                            "examples": [
                              "2026-10-19T10:00:00.000Z"
                            ],
                            "format": "date-time"
                          },
                          "expiresAt": {
                            "type": "string",
                            "title": "Expires at",
                            "description": "Pay before this.",
                            "examples": [
                              "2026-10-20T10:00:00.000Z"
                            ],
                            "format": "date-time"
                          },
                          "paidAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Paid at",
                            "description": "When Cashfree took the payment; null until paid.",
                            "examples": [
                              "2026-10-19T10:02:00.000Z"
                            ],
                            "format": "date-time"
                          },
                          "invoiceNumber": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Invoice number",
                            "description": "The tax invoice number, once paid: RW/<financial year>/<6 digits>; TEST/... for sandbox orders.",
                            "examples": [
                              "RW/2627/000001"
                            ]
                          },
                          "invoiceId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Invoice",
                            "description": "The invoice id once paid (GET /v1/billing/invoices/{id}); null until paid. Sent from contract 0.40.0.",
                            "examples": [
                              "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                            ],
                            "format": "uuid"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/orders/{id}": {
      "get": {
        "operationId": "getOrder",
        "summary": "Get an order",
        "description": "One order and its status. While it is still `created`, Cashfree is asked whether it was paid; if so the payment is recorded here (once) and the order answers `paid`, so a lost webhook never leaves a paid order waiting. Poll this after Cashfree’s checkout returns. Organisation admins only, with a session.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Order",
                  "description": "One order.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Order",
                      "description": "A Cashfree order and what it buys.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "tierKey",
                        "tierVersion",
                        "credits",
                        "environment",
                        "buyer",
                        "placeOfSupply",
                        "amounts",
                        "status",
                        "createdAt",
                        "expiresAt",
                        "paidAt",
                        "invoiceNumber",
                        "invoiceId"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The order id (also Cashfree’s order_id).",
                          "examples": [
                            "3f1a9c2e-7b4d-4e8a-9c1f-0a2b3c4d5e6f"
                          ],
                          "format": "uuid"
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "top_up",
                            "plan"
                          ],
                          "title": "Kind",
                          "description": "top_up or plan.",
                          "examples": [
                            "top_up"
                          ]
                        },
                        "tierKey": {
                          "type": "string",
                          "title": "Tier",
                          "description": "The tier bought: top_up or the plan’s key.",
                          "examples": [
                            "top_up"
                          ]
                        },
                        "tierVersion": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Tier version",
                          "description": "The tier price version the order was priced on.",
                          "examples": [
                            2
                          ]
                        },
                        "credits": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Credits",
                          "description": "Credits it gives once paid (paid credits, 12 months, C-012).",
                          "examples": [
                            5000
                          ]
                        },
                        "environment": {
                          "type": "string",
                          "enum": [
                            "sandbox",
                            "production"
                          ],
                          "title": "Environment",
                          "description": "sandbox (staging, test money) or production.",
                          "examples": [
                            "sandbox"
                          ]
                        },
                        "buyer": {
                          "type": "object",
                          "title": "Buyer",
                          "description": "The buyer details the order was made with.",
                          "additionalProperties": false,
                          "required": [
                            "legalName",
                            "country",
                            "stateCode",
                            "gstin"
                          ],
                          "properties": {
                            "legalName": {
                              "type": "string",
                              "title": "Legal name",
                              "description": "The buyer’s legal name, as the tax invoice shows it.",
                              "examples": [
                                "Acme Retail Pvt Ltd"
                              ],
                              "minLength": 1,
                              "maxLength": 200
                            },
                            "country": {
                              "type": "string",
                              "title": "Country",
                              "description": "ISO 3166-1 alpha-2 country code.",
                              "examples": [
                                "IN"
                              ],
                              "pattern": "^[A-Z]{2}$"
                            },
                            "stateCode": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "State",
                              "description": "The two-digit GST state code of the buyer, required in India (it decides CGST + SGST or IGST); null outside India.",
                              "examples": [
                                "29"
                              ],
                              "pattern": "^[0-9]{2}$"
                            },
                            "gstin": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "GSTIN",
                              "description": "The buyer’s GSTIN, if registered (for input tax credit); its first two digits must be the state code.",
                              "examples": [
                                "29ABCDE1234F1Z5"
                              ],
                              "pattern": "^[0-9]{2}[0-9A-Z]{13}$"
                            }
                          }
                        },
                        "placeOfSupply": {
                          "type": "string",
                          "title": "Place of supply",
                          "description": "The buyer’s GST state code, or `export`.",
                          "examples": [
                            "29"
                          ]
                        },
                        "amounts": {
                          "type": "object",
                          "title": "Amounts",
                          "description": "In integer paise. While Rewalto is not registered for GST (D-1879) there is no GST: every GST field is 0 and the total is the price. Once registered: CGST + SGST when the buyer is in Rewalto’s state, IGST in another state, none for an export under the LUT.",
                          "additionalProperties": false,
                          "required": [
                            "basePaise",
                            "cgstPaise",
                            "sgstPaise",
                            "igstPaise",
                            "totalPaise",
                            "currency"
                          ],
                          "properties": {
                            "basePaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "Price",
                              "description": "The listed price, from the tier in force.",
                              "examples": [
                                149900
                              ]
                            },
                            "cgstPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "CGST",
                              "description": "Central GST; 0 while Rewalto is not GST-registered.",
                              "examples": [
                                0
                              ]
                            },
                            "sgstPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "SGST",
                              "description": "State GST; 0 while Rewalto is not GST-registered.",
                              "examples": [
                                0
                              ]
                            },
                            "igstPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "IGST",
                              "description": "Integrated GST; 0 while Rewalto is not GST-registered.",
                              "examples": [
                                0
                              ]
                            },
                            "totalPaise": {
                              "type": "integer",
                              "minimum": 1,
                              "title": "Total",
                              "description": "What the buyer pays: the price plus any GST (exactly the price while Rewalto is not GST-registered).",
                              "examples": [
                                149900
                              ]
                            },
                            "currency": {
                              "type": "string",
                              "enum": [
                                "INR"
                              ],
                              "title": "Currency",
                              "description": "Always INR.",
                              "examples": [
                                "INR"
                              ]
                            }
                          }
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "created",
                            "paid",
                            "expired"
                          ],
                          "title": "Status",
                          "description": "created: not paid yet. paid: Cashfree confirmed the payment and the credits (or plan) were given. expired: not paid within a day; make a new order.",
                          "examples": [
                            "created"
                          ]
                        },
                        "createdAt": {
                          "type": "string",
                          "title": "Created at",
                          "description": "When the order was made.",
                          "examples": [
                            "2026-10-19T10:00:00.000Z"
                          ],
                          "format": "date-time"
                        },
                        "expiresAt": {
                          "type": "string",
                          "title": "Expires at",
                          "description": "Pay before this.",
                          "examples": [
                            "2026-10-20T10:00:00.000Z"
                          ],
                          "format": "date-time"
                        },
                        "paidAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Paid at",
                          "description": "When Cashfree took the payment; null until paid.",
                          "examples": [
                            "2026-10-19T10:02:00.000Z"
                          ],
                          "format": "date-time"
                        },
                        "invoiceNumber": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Invoice number",
                          "description": "The tax invoice number, once paid: RW/<financial year>/<6 digits>; TEST/... for sandbox orders.",
                          "examples": [
                            "RW/2627/000001"
                          ]
                        },
                        "invoiceId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Invoice",
                          "description": "The invoice id once paid (GET /v1/billing/invoices/{id}); null until paid. Sent from contract 0.40.0.",
                          "examples": [
                            "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                          ],
                          "format": "uuid"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The order id.",
              "examples": [
                "3f1a9c2e-7b4d-4e8a-9c1f-0a2b3c4d5e6f"
              ],
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/billing/profile": {
      "get": {
        "operationId": "getBillingProfile",
        "summary": "Get the billing profile",
        "description": "The organisation’s billing details in force (the newest saved), or `data: null` before the first save. Orders are made from them: legal name, address, country, GST state code (in India), optional GSTIN, contact email and phone. Organisation admins only, with a session.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Billing profile",
                  "description": "The billing profile in force, or null when none was saved yet.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "title": "Billing profile",
                      "description": "The buyer details orders are made from.",
                      "additionalProperties": false,
                      "required": [
                        "legalName",
                        "address",
                        "country",
                        "stateCode",
                        "gstin",
                        "email",
                        "phone",
                        "savedAt"
                      ],
                      "properties": {
                        "legalName": {
                          "type": "string",
                          "title": "Legal name",
                          "description": "The buyer’s legal name, as the tax invoice shows it.",
                          "examples": [
                            "Acme Retail Pvt Ltd"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "address": {
                          "type": "string",
                          "title": "Address",
                          "description": "The buyer’s registered address.",
                          "examples": [
                            "1 MG Road, Bengaluru 560001"
                          ],
                          "minLength": 1,
                          "maxLength": 500
                        },
                        "country": {
                          "type": "string",
                          "title": "Country",
                          "description": "ISO 3166-1 alpha-2 country code.",
                          "examples": [
                            "IN"
                          ],
                          "pattern": "^[A-Z]{2}$"
                        },
                        "stateCode": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "State",
                          "description": "The two-digit GST state code of the buyer, required in India (it decides CGST + SGST or IGST); null outside India.",
                          "examples": [
                            "29"
                          ],
                          "pattern": "^[0-9]{2}$"
                        },
                        "gstin": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "GSTIN",
                          "description": "The buyer’s GSTIN, if registered (for input tax credit); its first two digits must be the state code.",
                          "examples": [
                            "29ABCDE1234F1Z5"
                          ],
                          "pattern": "^[0-9]{2}[0-9A-Z]{13}$"
                        },
                        "email": {
                          "type": "string",
                          "title": "Email",
                          "description": "Where Cashfree and Rewalto send payment notices.",
                          "examples": [
                            "billing@acme.example"
                          ],
                          "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
                          "maxLength": 200
                        },
                        "phone": {
                          "type": "string",
                          "title": "Phone",
                          "description": "A phone number Cashfree requires on every order: 10 to 15 digits, optional +.",
                          "examples": [
                            "+919876543210"
                          ],
                          "pattern": "^\\+?[0-9]{10,15}$"
                        },
                        "savedAt": {
                          "type": "string",
                          "title": "Saved at",
                          "description": "When this version was saved.",
                          "examples": [
                            "2026-10-19T10:00:00.000Z"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "put": {
        "operationId": "saveBillingProfile",
        "summary": "Save the billing profile",
        "description": "Saves the buyer details orders are made from, as a new version (orders already made keep theirs). In India the GST state code is required: it decides CGST + SGST (Rewalto’s state) or IGST (another state); a GSTIN must start with that state code. Outside India the state and GSTIN are dropped. Organisation admins only, with a session.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Billing profile",
                  "description": "The billing profile in force, or null when none was saved yet.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "title": "Billing profile",
                      "description": "The buyer details orders are made from.",
                      "additionalProperties": false,
                      "required": [
                        "legalName",
                        "address",
                        "country",
                        "stateCode",
                        "gstin",
                        "email",
                        "phone",
                        "savedAt"
                      ],
                      "properties": {
                        "legalName": {
                          "type": "string",
                          "title": "Legal name",
                          "description": "The buyer’s legal name, as the tax invoice shows it.",
                          "examples": [
                            "Acme Retail Pvt Ltd"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "address": {
                          "type": "string",
                          "title": "Address",
                          "description": "The buyer’s registered address.",
                          "examples": [
                            "1 MG Road, Bengaluru 560001"
                          ],
                          "minLength": 1,
                          "maxLength": 500
                        },
                        "country": {
                          "type": "string",
                          "title": "Country",
                          "description": "ISO 3166-1 alpha-2 country code.",
                          "examples": [
                            "IN"
                          ],
                          "pattern": "^[A-Z]{2}$"
                        },
                        "stateCode": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "State",
                          "description": "The two-digit GST state code of the buyer, required in India (it decides CGST + SGST or IGST); null outside India.",
                          "examples": [
                            "29"
                          ],
                          "pattern": "^[0-9]{2}$"
                        },
                        "gstin": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "GSTIN",
                          "description": "The buyer’s GSTIN, if registered (for input tax credit); its first two digits must be the state code.",
                          "examples": [
                            "29ABCDE1234F1Z5"
                          ],
                          "pattern": "^[0-9]{2}[0-9A-Z]{13}$"
                        },
                        "email": {
                          "type": "string",
                          "title": "Email",
                          "description": "Where Cashfree and Rewalto send payment notices.",
                          "examples": [
                            "billing@acme.example"
                          ],
                          "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
                          "maxLength": 200
                        },
                        "phone": {
                          "type": "string",
                          "title": "Phone",
                          "description": "A phone number Cashfree requires on every order: 10 to 15 digits, optional +.",
                          "examples": [
                            "+919876543210"
                          ],
                          "pattern": "^\\+?[0-9]{10,15}$"
                        },
                        "savedAt": {
                          "type": "string",
                          "title": "Saved at",
                          "description": "When this version was saved.",
                          "examples": [
                            "2026-10-19T10:00:00.000Z"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Save billing profile",
                "description": "The buyer details. Saving adds a new version; orders already made keep the details they were made with.",
                "additionalProperties": false,
                "required": [
                  "legalName",
                  "address",
                  "country",
                  "email",
                  "phone"
                ],
                "properties": {
                  "legalName": {
                    "type": "string",
                    "title": "Legal name",
                    "description": "The buyer’s legal name, as the tax invoice shows it.",
                    "examples": [
                      "Acme Retail Pvt Ltd"
                    ],
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "address": {
                    "type": "string",
                    "title": "Address",
                    "description": "The buyer’s registered address.",
                    "examples": [
                      "1 MG Road, Bengaluru 560001"
                    ],
                    "minLength": 1,
                    "maxLength": 500
                  },
                  "country": {
                    "type": "string",
                    "title": "Country",
                    "description": "ISO 3166-1 alpha-2 country code.",
                    "examples": [
                      "IN"
                    ],
                    "pattern": "^[A-Z]{2}$"
                  },
                  "stateCode": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "title": "State",
                    "description": "The two-digit GST state code of the buyer, required in India (it decides CGST + SGST or IGST); null outside India.",
                    "examples": [
                      "29"
                    ],
                    "pattern": "^[0-9]{2}$"
                  },
                  "gstin": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "title": "GSTIN",
                    "description": "The buyer’s GSTIN, if registered (for input tax credit); its first two digits must be the state code.",
                    "examples": [
                      "29ABCDE1234F1Z5"
                    ],
                    "pattern": "^[0-9]{2}[0-9A-Z]{13}$"
                  },
                  "email": {
                    "type": "string",
                    "title": "Email",
                    "description": "Where Cashfree and Rewalto send payment notices.",
                    "examples": [
                      "billing@acme.example"
                    ],
                    "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$",
                    "maxLength": 200
                  },
                  "phone": {
                    "type": "string",
                    "title": "Phone",
                    "description": "A phone number Cashfree requires on every order: 10 to 15 digits, optional +.",
                    "examples": [
                      "+919876543210"
                    ],
                    "pattern": "^\\+?[0-9]{10,15}$"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/razorpay/webhook": {
      "post": {
        "operationId": "receiveRazorpayWebhook",
        "summary": "Razorpay signed payment and subscription events",
        "description": "",
        "tags": [
          "Billing"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "received"
                  ],
                  "properties": {
                    "received": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": true
              }
            }
          }
        }
      }
    },
    "/v1/billing/subscriptions": {
      "get": {
        "operationId": "listSubscriptions",
        "summary": "List the last 100 recurring subscriptions",
        "description": "Organisation admins only. Stored provider status from the most recent reconciliation; getSubscription refreshes it.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "subscriptionId",
                          "status",
                          "totalCount",
                          "amountPaise",
                          "currency"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "subscriptionId": {
                            "type": "string",
                            "pattern": "^sub_[A-Za-z0-9]+$"
                          },
                          "status": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "totalCount": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 120
                          },
                          "amountPaise": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "currency": {
                            "type": "string",
                            "const": "INR"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `billing_profile_missing`: retry advice `never`\n- `export_not_available`: retry advice `never`\n- `idempotency_conflict`: retry advice `never`\n- `invoicing_unavailable`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createSubscription",
        "summary": "Create a monthly Razorpay mandate checkout",
        "description": "Use quoteSubscription with the same idempotency key first. Explicitly confirm its GST-inclusive total and finite monthly cycle count. No credits until a captured paid invoice. Existing purchases are never enrolled automatically.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Order made",
                  "description": "The order and how to pay it.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Order and checkout",
                      "description": "The order, and Cashfree’s checkout while it can be paid.",
                      "additionalProperties": false,
                      "required": [
                        "order",
                        "checkout"
                      ],
                      "properties": {
                        "order": {
                          "type": "object",
                          "title": "Order",
                          "description": "A Cashfree order and what it buys.",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "kind",
                            "tierKey",
                            "tierVersion",
                            "credits",
                            "environment",
                            "buyer",
                            "placeOfSupply",
                            "amounts",
                            "status",
                            "createdAt",
                            "expiresAt",
                            "paidAt",
                            "invoiceNumber",
                            "invoiceId"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "title": "Id",
                              "description": "The order id (also Cashfree’s order_id).",
                              "examples": [
                                "3f1a9c2e-7b4d-4e8a-9c1f-0a2b3c4d5e6f"
                              ],
                              "format": "uuid"
                            },
                            "kind": {
                              "type": "string",
                              "enum": [
                                "top_up",
                                "plan"
                              ],
                              "title": "Kind",
                              "description": "top_up or plan.",
                              "examples": [
                                "top_up"
                              ]
                            },
                            "tierKey": {
                              "type": "string",
                              "title": "Tier",
                              "description": "The tier bought: top_up or the plan’s key.",
                              "examples": [
                                "top_up"
                              ]
                            },
                            "tierVersion": {
                              "type": "integer",
                              "minimum": 1,
                              "title": "Tier version",
                              "description": "The tier price version the order was priced on.",
                              "examples": [
                                2
                              ]
                            },
                            "credits": {
                              "type": "integer",
                              "minimum": 1,
                              "title": "Credits",
                              "description": "Credits it gives once paid (paid credits, 12 months, C-012).",
                              "examples": [
                                5000
                              ]
                            },
                            "environment": {
                              "type": "string",
                              "enum": [
                                "sandbox",
                                "production"
                              ],
                              "title": "Environment",
                              "description": "sandbox (staging, test money) or production.",
                              "examples": [
                                "sandbox"
                              ]
                            },
                            "buyer": {
                              "type": "object",
                              "title": "Buyer",
                              "description": "The buyer details the order was made with.",
                              "additionalProperties": false,
                              "required": [
                                "legalName",
                                "country",
                                "stateCode",
                                "gstin"
                              ],
                              "properties": {
                                "legalName": {
                                  "type": "string",
                                  "title": "Legal name",
                                  "description": "The buyer’s legal name, as the tax invoice shows it.",
                                  "examples": [
                                    "Acme Retail Pvt Ltd"
                                  ],
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                "country": {
                                  "type": "string",
                                  "title": "Country",
                                  "description": "ISO 3166-1 alpha-2 country code.",
                                  "examples": [
                                    "IN"
                                  ],
                                  "pattern": "^[A-Z]{2}$"
                                },
                                "stateCode": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "State",
                                  "description": "The two-digit GST state code of the buyer, required in India (it decides CGST + SGST or IGST); null outside India.",
                                  "examples": [
                                    "29"
                                  ],
                                  "pattern": "^[0-9]{2}$"
                                },
                                "gstin": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "GSTIN",
                                  "description": "The buyer’s GSTIN, if registered (for input tax credit); its first two digits must be the state code.",
                                  "examples": [
                                    "29ABCDE1234F1Z5"
                                  ],
                                  "pattern": "^[0-9]{2}[0-9A-Z]{13}$"
                                }
                              }
                            },
                            "placeOfSupply": {
                              "type": "string",
                              "title": "Place of supply",
                              "description": "The buyer’s GST state code, or `export`.",
                              "examples": [
                                "29"
                              ]
                            },
                            "amounts": {
                              "type": "object",
                              "title": "Amounts",
                              "description": "In integer paise. While Rewalto is not registered for GST (D-1879) there is no GST: every GST field is 0 and the total is the price. Once registered: CGST + SGST when the buyer is in Rewalto’s state, IGST in another state, none for an export under the LUT.",
                              "additionalProperties": false,
                              "required": [
                                "basePaise",
                                "cgstPaise",
                                "sgstPaise",
                                "igstPaise",
                                "totalPaise",
                                "currency"
                              ],
                              "properties": {
                                "basePaise": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "Price",
                                  "description": "The listed price, from the tier in force.",
                                  "examples": [
                                    149900
                                  ]
                                },
                                "cgstPaise": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "CGST",
                                  "description": "Central GST; 0 while Rewalto is not GST-registered.",
                                  "examples": [
                                    0
                                  ]
                                },
                                "sgstPaise": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "SGST",
                                  "description": "State GST; 0 while Rewalto is not GST-registered.",
                                  "examples": [
                                    0
                                  ]
                                },
                                "igstPaise": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "IGST",
                                  "description": "Integrated GST; 0 while Rewalto is not GST-registered.",
                                  "examples": [
                                    0
                                  ]
                                },
                                "totalPaise": {
                                  "type": "integer",
                                  "minimum": 1,
                                  "title": "Total",
                                  "description": "What the buyer pays: the price plus any GST (exactly the price while Rewalto is not GST-registered).",
                                  "examples": [
                                    149900
                                  ]
                                },
                                "currency": {
                                  "type": "string",
                                  "enum": [
                                    "INR"
                                  ],
                                  "title": "Currency",
                                  "description": "Always INR.",
                                  "examples": [
                                    "INR"
                                  ]
                                }
                              }
                            },
                            "status": {
                              "type": "string",
                              "enum": [
                                "created",
                                "paid",
                                "expired"
                              ],
                              "title": "Status",
                              "description": "created: not paid yet. paid: Cashfree confirmed the payment and the credits (or plan) were given. expired: not paid within a day; make a new order.",
                              "examples": [
                                "created"
                              ]
                            },
                            "createdAt": {
                              "type": "string",
                              "title": "Created at",
                              "description": "When the order was made.",
                              "examples": [
                                "2026-10-19T10:00:00.000Z"
                              ],
                              "format": "date-time"
                            },
                            "expiresAt": {
                              "type": "string",
                              "title": "Expires at",
                              "description": "Pay before this.",
                              "examples": [
                                "2026-10-20T10:00:00.000Z"
                              ],
                              "format": "date-time"
                            },
                            "paidAt": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Paid at",
                              "description": "When Cashfree took the payment; null until paid.",
                              "examples": [
                                "2026-10-19T10:02:00.000Z"
                              ],
                              "format": "date-time"
                            },
                            "invoiceNumber": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Invoice number",
                              "description": "The tax invoice number, once paid: RW/<financial year>/<6 digits>; TEST/... for sandbox orders.",
                              "examples": [
                                "RW/2627/000001"
                              ]
                            },
                            "invoiceId": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Invoice",
                              "description": "The invoice id once paid (GET /v1/billing/invoices/{id}); null until paid. Sent from contract 0.40.0.",
                              "examples": [
                                "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                              ],
                              "format": "uuid"
                            }
                          }
                        },
                        "checkout": {
                          "oneOf": [
                            {
                              "type": "object",
                              "title": "Cashfree checkout",
                              "description": "Historical Cashfree checkout.",
                              "additionalProperties": false,
                              "required": [
                                "provider",
                                "environment",
                                "paymentSessionId"
                              ],
                              "properties": {
                                "provider": {
                                  "type": "string",
                                  "enum": [
                                    "cashfree"
                                  ],
                                  "title": "Provider",
                                  "description": "Historical provider.",
                                  "examples": [
                                    "cashfree"
                                  ]
                                },
                                "environment": {
                                  "type": "string",
                                  "enum": [
                                    "sandbox",
                                    "production"
                                  ],
                                  "title": "Environment",
                                  "description": "Provider environment.",
                                  "examples": [
                                    "sandbox"
                                  ]
                                },
                                "paymentSessionId": {
                                  "type": "string",
                                  "title": "Payment session",
                                  "description": "Cashfree session.",
                                  "examples": [
                                    "session_abc123"
                                  ]
                                }
                              }
                            },
                            {
                              "type": "object",
                              "title": "Razorpay checkout",
                              "description": "Use Razorpay Standard Checkout; order_id or subscription_id is supplied by the server.",
                              "additionalProperties": false,
                              "required": [
                                "provider",
                                "environment",
                                "keyId",
                                "amountPaise",
                                "currency"
                              ],
                              "properties": {
                                "provider": {
                                  "type": "string",
                                  "const": "razorpay"
                                },
                                "environment": {
                                  "type": "string",
                                  "enum": [
                                    "sandbox",
                                    "production"
                                  ],
                                  "title": "Environment",
                                  "description": "Provider environment.",
                                  "examples": [
                                    "sandbox"
                                  ]
                                },
                                "keyId": {
                                  "type": "string",
                                  "title": "Key ID",
                                  "description": "Public Razorpay key ID. Never a secret.",
                                  "examples": [
                                    "rzp_test_example"
                                  ]
                                },
                                "orderId": {
                                  "type": "string",
                                  "title": "Order ID",
                                  "description": "One-time Razorpay order.",
                                  "examples": [
                                    "order_example"
                                  ]
                                },
                                "subscriptionId": {
                                  "type": "string",
                                  "title": "Subscription ID",
                                  "description": "Recurring Razorpay subscription.",
                                  "examples": [
                                    "sub_example"
                                  ]
                                },
                                "amountPaise": {
                                  "type": "integer",
                                  "minimum": 1,
                                  "title": "Amount",
                                  "description": "GST-inclusive amount in paise.",
                                  "examples": [
                                    177000
                                  ]
                                },
                                "currency": {
                                  "type": "string",
                                  "const": "INR"
                                }
                              }
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `billing_profile_missing`: retry advice `never`\n- `export_not_available`: retry advice `never`\n- `idempotency_conflict`: retry advice `never`\n- `invoicing_unavailable`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "idempotency-key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "examples": [
                "8f14e45f-ceea-467a-9f3c-2a1b5d7e6c11"
              ]
            },
            "description": "A key you choose for this purchase. Sending the same request with the same key returns the same order (no second order, no second charge); the same key with a different request is refused with idempotency_conflict."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "tierKey",
                  "totalCount",
                  "acceptedTotalPaise"
                ],
                "properties": {
                  "tierKey": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "totalCount": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 120
                  },
                  "acceptedTotalPaise": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/subscriptions/quote": {
      "post": {
        "operationId": "quoteSubscription",
        "summary": "Quote a recurring monthly plan before authorisation",
        "description": "",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Order",
                  "description": "One order.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Order",
                      "description": "A Cashfree order and what it buys.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "tierKey",
                        "tierVersion",
                        "credits",
                        "environment",
                        "buyer",
                        "placeOfSupply",
                        "amounts",
                        "status",
                        "createdAt",
                        "expiresAt",
                        "paidAt",
                        "invoiceNumber",
                        "invoiceId"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The order id (also Cashfree’s order_id).",
                          "examples": [
                            "3f1a9c2e-7b4d-4e8a-9c1f-0a2b3c4d5e6f"
                          ],
                          "format": "uuid"
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "top_up",
                            "plan"
                          ],
                          "title": "Kind",
                          "description": "top_up or plan.",
                          "examples": [
                            "top_up"
                          ]
                        },
                        "tierKey": {
                          "type": "string",
                          "title": "Tier",
                          "description": "The tier bought: top_up or the plan’s key.",
                          "examples": [
                            "top_up"
                          ]
                        },
                        "tierVersion": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Tier version",
                          "description": "The tier price version the order was priced on.",
                          "examples": [
                            2
                          ]
                        },
                        "credits": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Credits",
                          "description": "Credits it gives once paid (paid credits, 12 months, C-012).",
                          "examples": [
                            5000
                          ]
                        },
                        "environment": {
                          "type": "string",
                          "enum": [
                            "sandbox",
                            "production"
                          ],
                          "title": "Environment",
                          "description": "sandbox (staging, test money) or production.",
                          "examples": [
                            "sandbox"
                          ]
                        },
                        "buyer": {
                          "type": "object",
                          "title": "Buyer",
                          "description": "The buyer details the order was made with.",
                          "additionalProperties": false,
                          "required": [
                            "legalName",
                            "country",
                            "stateCode",
                            "gstin"
                          ],
                          "properties": {
                            "legalName": {
                              "type": "string",
                              "title": "Legal name",
                              "description": "The buyer’s legal name, as the tax invoice shows it.",
                              "examples": [
                                "Acme Retail Pvt Ltd"
                              ],
                              "minLength": 1,
                              "maxLength": 200
                            },
                            "country": {
                              "type": "string",
                              "title": "Country",
                              "description": "ISO 3166-1 alpha-2 country code.",
                              "examples": [
                                "IN"
                              ],
                              "pattern": "^[A-Z]{2}$"
                            },
                            "stateCode": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "State",
                              "description": "The two-digit GST state code of the buyer, required in India (it decides CGST + SGST or IGST); null outside India.",
                              "examples": [
                                "29"
                              ],
                              "pattern": "^[0-9]{2}$"
                            },
                            "gstin": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "GSTIN",
                              "description": "The buyer’s GSTIN, if registered (for input tax credit); its first two digits must be the state code.",
                              "examples": [
                                "29ABCDE1234F1Z5"
                              ],
                              "pattern": "^[0-9]{2}[0-9A-Z]{13}$"
                            }
                          }
                        },
                        "placeOfSupply": {
                          "type": "string",
                          "title": "Place of supply",
                          "description": "The buyer’s GST state code, or `export`.",
                          "examples": [
                            "29"
                          ]
                        },
                        "amounts": {
                          "type": "object",
                          "title": "Amounts",
                          "description": "In integer paise. While Rewalto is not registered for GST (D-1879) there is no GST: every GST field is 0 and the total is the price. Once registered: CGST + SGST when the buyer is in Rewalto’s state, IGST in another state, none for an export under the LUT.",
                          "additionalProperties": false,
                          "required": [
                            "basePaise",
                            "cgstPaise",
                            "sgstPaise",
                            "igstPaise",
                            "totalPaise",
                            "currency"
                          ],
                          "properties": {
                            "basePaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "Price",
                              "description": "The listed price, from the tier in force.",
                              "examples": [
                                149900
                              ]
                            },
                            "cgstPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "CGST",
                              "description": "Central GST; 0 while Rewalto is not GST-registered.",
                              "examples": [
                                0
                              ]
                            },
                            "sgstPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "SGST",
                              "description": "State GST; 0 while Rewalto is not GST-registered.",
                              "examples": [
                                0
                              ]
                            },
                            "igstPaise": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "IGST",
                              "description": "Integrated GST; 0 while Rewalto is not GST-registered.",
                              "examples": [
                                0
                              ]
                            },
                            "totalPaise": {
                              "type": "integer",
                              "minimum": 1,
                              "title": "Total",
                              "description": "What the buyer pays: the price plus any GST (exactly the price while Rewalto is not GST-registered).",
                              "examples": [
                                149900
                              ]
                            },
                            "currency": {
                              "type": "string",
                              "enum": [
                                "INR"
                              ],
                              "title": "Currency",
                              "description": "Always INR.",
                              "examples": [
                                "INR"
                              ]
                            }
                          }
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "created",
                            "paid",
                            "expired"
                          ],
                          "title": "Status",
                          "description": "created: not paid yet. paid: Cashfree confirmed the payment and the credits (or plan) were given. expired: not paid within a day; make a new order.",
                          "examples": [
                            "created"
                          ]
                        },
                        "createdAt": {
                          "type": "string",
                          "title": "Created at",
                          "description": "When the order was made.",
                          "examples": [
                            "2026-10-19T10:00:00.000Z"
                          ],
                          "format": "date-time"
                        },
                        "expiresAt": {
                          "type": "string",
                          "title": "Expires at",
                          "description": "Pay before this.",
                          "examples": [
                            "2026-10-20T10:00:00.000Z"
                          ],
                          "format": "date-time"
                        },
                        "paidAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Paid at",
                          "description": "When Cashfree took the payment; null until paid.",
                          "examples": [
                            "2026-10-19T10:02:00.000Z"
                          ],
                          "format": "date-time"
                        },
                        "invoiceNumber": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Invoice number",
                          "description": "The tax invoice number, once paid: RW/<financial year>/<6 digits>; TEST/... for sandbox orders.",
                          "examples": [
                            "RW/2627/000001"
                          ]
                        },
                        "invoiceId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Invoice",
                          "description": "The invoice id once paid (GET /v1/billing/invoices/{id}); null until paid. Sent from contract 0.40.0.",
                          "examples": [
                            "7c9e6679-7425-40de-944b-e07fc1f90ae7"
                          ],
                          "format": "uuid"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `billing_profile_missing`: retry advice `never`\n- `export_not_available`: retry advice `never`\n- `idempotency_conflict`: retry advice `never`\n- `invoicing_unavailable`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "idempotency-key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "examples": [
                "8f14e45f-ceea-467a-9f3c-2a1b5d7e6c11"
              ]
            },
            "description": "A key you choose for this purchase. Sending the same request with the same key returns the same order (no second order, no second charge); the same key with a different request is refused with idempotency_conflict."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "tierKey"
                ],
                "properties": {
                  "tierKey": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/billing/subscriptions/{id}": {
      "get": {
        "operationId": "getSubscription",
        "summary": "Read and reconcile a subscription",
        "description": "",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "subscriptionId",
                        "status",
                        "totalCount",
                        "amountPaise",
                        "currency"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "subscriptionId": {
                          "type": "string",
                          "pattern": "^sub_[A-Za-z0-9]+$"
                        },
                        "status": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "totalCount": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 120
                        },
                        "amountPaise": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "currency": {
                          "type": "string",
                          "const": "INR"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `billing_profile_missing`: retry advice `never`\n- `export_not_available`: retry advice `never`\n- `idempotency_conflict`: retry advice `never`\n- `invoicing_unavailable`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/billing/subscriptions/{id}/cancel": {
      "post": {
        "operationId": "cancelSubscription",
        "summary": "Stop future recurring charges",
        "description": "Cancels the Razorpay mandate immediately; already paid access periods and credits remain. No refund or proration.",
        "tags": [
          "Billing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "subscriptionId",
                        "status",
                        "totalCount",
                        "amountPaise",
                        "currency"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "subscriptionId": {
                          "type": "string",
                          "pattern": "^sub_[A-Za-z0-9]+$"
                        },
                        "status": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "totalCount": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 120
                        },
                        "amountPaise": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "currency": {
                          "type": "string",
                          "const": "INR"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `billing_profile_missing`: retry advice `never`\n- `export_not_available`: retry advice `never`\n- `idempotency_conflict`: retry advice `never`\n- `invoicing_unavailable`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `payment_provider_unavailable`: retry advice `bounded`\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {}
              }
            }
          }
        }
      }
    },
    "/v1/catalogue/categories": {
      "get": {
        "operationId": "listCatalogueCategories",
        "summary": "List catalogue categories",
        "description": "Every catalogue category in page order, with how many cards and entries it has and how many entries are live, in preview, planned or degraded. Public and free.",
        "tags": [
          "Catalogue"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogueCategories"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/catalogue/entries/{id}": {
      "get": {
        "operationId": "getCatalogueEntry",
        "summary": "Get a catalogue entry",
        "description": "One dataset, recipe, workflow or tool in full: inputs and outputs (JSON Schema), sample rows, data dictionary, coverage table with holes, freshness, rate rows, rights, versions and, for a workflow, the recipes and datasets it uses. Public and free.",
        "tags": [
          "Catalogue"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogueEntryAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The entry id.",
              "examples": [
                "qc_price_history"
              ],
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          }
        ]
      }
    },
    "/v1/catalogue/entries/{id}/coverage-grid": {
      "get": {
        "operationId": "getCatalogueCoverageGrid",
        "summary": "Get an entry's coverage grid",
        "description": "Coverage per pin code and IST day for every retailer the entry draws on, for the last `days` days (default 7, at most 31): readings per cell, holes (an expected pin with no readings) and days not computed (unknown, never shown as holes). Rows are pin codes; city is null until a pin-to-city map exists. Read from the hourly summary, never from the data itself. Public and free.",
        "tags": [
          "Catalogue"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogueCoverageGrid"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The entry id.",
              "examples": [
                "qc_price_history"
              ],
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          },
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Days",
              "examples": [
                "7"
              ],
              "pattern": "^([1-9]|[12][0-9]|3[01])$"
            },
            "description": "IST days, ending today: 1 to 31. Default 7."
          }
        ]
      }
    },
    "/v1/catalogue/intake": {
      "post": {
        "operationId": "checkIntake",
        "summary": "Do we already hold these products?",
        "description": "For up to 25 product links or retailer product ids (SKUs): whether Rewalto already collects the listing each names, how the input was linked to it (`linkMethod`), the retailer product id it declares (`declaredSku`), and, per held listing, the canonical product it is linked to (`productId`), kept apart from the declared SKU. Coverage facts only (first and last seen, readings kept), never titles or prices: read the data with /v1/data. Free text that is neither a link nor a product id is refused. Public and free.",
        "tags": [
          "Catalogue"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntakeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntakeRequest"
              }
            }
          }
        }
      }
    },
    "/v1/catalogue/products": {
      "get": {
        "operationId": "listCatalogueProducts",
        "summary": "List catalogue cards",
        "description": "Data-product cards: what you get, entry count, \"from N credits / unit\" (or quote first, free tool, not available yet), coverage, freshness, keep/live badges and status. Filter by category, text and status. Public and free.",
        "tags": [
          "Catalogue"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogueProducts"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Category",
              "examples": [
                "quick_commerce"
              ],
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            },
            "description": "Only this category."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Query",
              "examples": [
                "price"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only cards whose name, summary, data types or sources contain this text."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Status",
              "examples": [
                "live"
              ],
              "pattern": "^(live|preview|planned|degraded)$"
            },
            "description": "Only cards with this status: live, preview, planned or degraded."
          }
        ]
      }
    },
    "/v1/catalogue/requests": {
      "post": {
        "operationId": "createDataRequest",
        "summary": "Missing a data type? Ask the Finder",
        "description": "Records a request for data Rewalto does not offer yet: a catalogue search that found nothing, or a pasted product that is not held (send what found nothing as `query`). Staff read the requests and count them as demand for new datasets. No sign-in needed; a session or API key, if sent, records your organisation so the Finder can follow up there. Never charged. Leave out contact details: text with an email address or phone number is refused. At most 5 requests a minute per caller.",
        "tags": [
          "Catalogue"
        ],
        "security": [],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DataRequestAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DataRequestCreate"
              }
            }
          }
        }
      }
    },
    "/v1/catalogue/search": {
      "get": {
        "operationId": "searchCatalogue",
        "summary": "Search the catalogue",
        "description": "Search names, data types, sources and field names. A pasted product link or retailer product id also gets an intake answer: whether Rewalto already holds it, the same answer as POST /v1/catalogue/intake. Public and free.",
        "tags": [
          "Catalogue"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CatalogueSearch"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Query",
              "examples": [
                "zepto price"
              ],
              "minLength": 1,
              "maxLength": 500
            },
            "description": "What to look for."
          }
        ]
      }
    },
    "/v1/categories/{category}/cities": {
      "get": {
        "operationId": "getCategoryCities",
        "summary": "Get the city test view of a category",
        "description": "Per city, over the last 7 IST days of Rewalto's shelf readings at pin codes the India Post directory places in that city: platforms, pins and days read, products and brands seen, availability rate (listing-pin-days in stock over those with a known stock state), median unit price on the category's main basis and median discount below MRP. Ranked two ways: competitionRank (most brands, then most products) and availabilityRank. Cities under 10 products or 2 days are listed under declined; national listings with no pin count in unplacedReadings. Public and free.",
        "tags": [
          "Categories"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryCities"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "category",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Category",
              "description": "A public category slug.",
              "examples": [
                "audio-electronics"
              ],
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
              "maxLength": 60
            }
          }
        ]
      }
    },
    "/v1/categories/{category}/feature-tags": {
      "get": {
        "operationId": "getCategoryFeatureTags",
        "summary": "Get the feature tags of a category",
        "description": "Monthly, for each feature tag of a category (audio: ANC, spatial audio, open-ear, over-ear; fitness and nutrition: whey, plant protein, creatine; packaged food: instant, filter, cold brew and whole bean or ground coffee among coffee, green tea among tea): listings on the shelf in the tag's scope, how many carry the tag, the share (null under 20 scope listings) and the tagged listings' median unit price. Tags are read from listing titles by a fixed, reviewed dictionary (method names its version). The current month is cut at asOf. Categories with no tags answer not_found. Public and free.",
        "tags": [
          "Categories"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryFeatureTags"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "category",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Category",
              "description": "A public category slug.",
              "examples": [
                "audio-electronics"
              ],
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
              "maxLength": 60
            }
          }
        ]
      }
    },
    "/v1/categories/{category}/market-context": {
      "get": {
        "operationId": "getCategoryMarketContext",
        "summary": "Get market context for a category",
        "description": "One to three public figures about the Indian market for a public category (shipments, consumption, market size, exports), each with its value, unit, period, the body that published it, the source page and the day it was checked there. Reviewed by hand; an empty list means no figure could be confirmed on a primary source. Public and free.",
        "tags": [
          "Categories"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryMarketContext"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "category",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Category",
              "description": "A public category slug.",
              "examples": [
                "audio-electronics"
              ],
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
              "maxLength": 60
            }
          }
        ]
      }
    },
    "/v1/categories/{category}/price-ladder": {
      "get": {
        "operationId": "getCategoryPriceLadder",
        "summary": "Get the price ladder of a category",
        "description": "Entry, mid and premium unit-price bands for a public category over the last 7 IST days of Rewalto's shelf readings: p25, median, p75 and p90 unit price, min and max, and listings per band, for all platforms together and for each platform, one ladder per unit basis (rupees per 100 g, per 100 ml, per piece, or per item for goods sold one at a time). Each listing counts once, at its latest day. Ladders under 20 listings are listed under declined with their counts. Filter with platform ('all' or a retailer key). Public and free.",
        "tags": [
          "Categories"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CategoryPriceLadder"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "category",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Category",
              "description": "A public category slug.",
              "examples": [
                "audio-electronics"
              ],
              "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
              "maxLength": 60
            }
          },
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Platform",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this platform's ladders ('all' for every platform together, or a retailer key such as blinkit). Omit for all of them."
          }
        ]
      }
    },
    "/v1/coverage/layers": {
      "get": {
        "operationId": "getCoverageLayers",
        "summary": "Get the coverage map layers: cities, pin codes and dark stores on record",
        "description": "For the coverage map: the pin codes on record (Rewalto's pin registry and every pin code a dark store was found at, each with a centre), their cities at the centre of their pin codes, and open dark stores counted per city (placed at the city's pin-code centre, else, for a city with at least 5 open stores that have a point, at the centre of those points rounded to 0.1 degree, else not placed), with the totals beside the map: distinct cities, pin codes and open dark stores. pins (up to 100 pin codes) returns those pins' centres, so a map drawn at fixed positions can fit its projection. Counts and centres only: no store id, name or point. Read again at most every 10 minutes. Public and free.",
        "tags": [
          "Coverage"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CoverageLayers"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pins",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pins",
              "examples": [
                "110001,400001,560001"
              ],
              "pattern": "^[1-9][0-9]{5}(,[1-9][0-9]{5}){0,99}$"
            },
            "description": "Comma-separated six-digit pin codes (at most 100) whose centres to return in pinCentres; a pin with no centre on record is left out."
          }
        ]
      }
    },
    "/v1/coverage/pins": {
      "get": {
        "operationId": "getCoveragePins",
        "summary": "Get which sources read which pin codes recently",
        "description": "For the coverage map: each source (retailer or app) and pin code with Rewalto readings on the IST days from today minus days (default 3, at most 14) up to today, from the hourly coverage summary: readings, days read and the newest reading time, the pin code's city (one spelling per city), area and centre, and storePresent, whether an open dark store of that app stands at or is seen serving the pin. Sources read nationally (not per pin code) are listed apart. measuredAt is when this was read and computedAt when the summary behind it was written. No store id, name or point and no price. Read again at most every 10 minutes. Public and free.",
        "tags": [
          "Coverage"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CoveragePins"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Days",
              "examples": [
                "3"
              ],
              "pattern": "^([1-9]|1[0-4])$"
            },
            "description": "Whole IST days back from today (1-14): readings on the IST days from today minus days up to today count. Default 3."
          }
        ]
      }
    },
    "/v1/credits/balance": {
      "get": {
        "operationId": "getCreditBalance",
        "summary": "Get the credit balance",
        "description": "The caller's organisation's credits. They are spent in this order: this month's free credits, then promotional credits, then paid credits. The first call in an IST month grants that month's 1,000 free credits, so a new organisation sees them at once.",
        "tags": [
          "Credits"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "cache-control": {
                "description": "Always `no-store`: the answer must not be cached.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreditBalance"
                },
                "example": {
                  "orgId": "3f2b8c1e-7a4d-4e0b-9c55-1d2e3f4a5b6c",
                  "available": 1440,
                  "unlimited": false,
                  "held": 0,
                  "free": {
                    "month": "2026-10",
                    "granted": 1000,
                    "used": 60,
                    "remaining": 940,
                    "held": 0,
                    "expiresAt": "2026-10-31T18:30:00.000Z"
                  },
                  "promo": {
                    "available": 0,
                    "held": 0,
                    "grants": []
                  },
                  "paid": {
                    "available": 500,
                    "held": 0,
                    "lots": [
                      {
                        "id": "0b6f1c9e-2a47-4d3b-8f10-5c9a7e1d2b34",
                        "credits": 500,
                        "remaining": 500,
                        "held": 0,
                        "purchasedAt": "2026-09-02T08:00:00.000Z",
                        "expiresAt": "2027-09-01T18:30:00.000Z"
                      }
                    ]
                  },
                  "nextResetAt": "2026-10-31T18:30:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/credits/refunds": {
      "post": {
        "operationId": "refundRead",
        "summary": "Refund a charged read, or a failed run, by its receipt",
        "description": "Ask for a charge’s credits back, by its receipt (the id of a `read` or `receipt` entry in GET /v1/credits/usage). A charged Library read is refunded, for example when its response never arrived, unless the same data was read again after the receipt. A charged run is refunded only when it failed (its usage entry has outcome failed); a run that returned nothing was never charged, and a run that delivered is not refunded on request. Refunded once: asking again returns the same refund. A refusal is a 409 refund_refused whose one detail (path body/receiptId) names the reason: charged_nothing, data_reread, run_delivered, or (contract 0.28.0) unlimited_credits: the charge was made under unlimited credits, so its price is on the receipt but nothing was drawn from the balance to give back.",
        "tags": [
          "Credits"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Refund"
                },
                "example": {
                  "id": "9e1d2c3b-4a5f-4e6d-8c7b-0a1b2c3d4e5f",
                  "receiptId": "rcp_5c2e8a91-4b7d-4f36-9e10-8a2b3c4d5e6f",
                  "receiptKind": "read",
                  "refunded": true,
                  "credits": 3,
                  "expiredOnReturn": 0,
                  "createdAt": "2026-10-15T11:05:00.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `refund_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RefundRequest"
              }
            }
          }
        }
      }
    },
    "/v1/credits/usage": {
      "get": {
        "operationId": "listCreditUsage",
        "summary": "List credit usage",
        "description": "A page of the caller's organisation's ledger events and receipts, newest first. Only the caller's own organisation is ever shown.",
        "tags": [
          "Credits"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "cache-control": {
                "description": "Always `no-store`: the answer must not be cached.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsagePage"
                },
                "example": {
                  "entries": [],
                  "nextCursor": null
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{1,3}$",
              "examples": [
                "50"
              ]
            },
            "description": "Entries per page, 1 to 200 (default 50). Sent as digits in the query string."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 400
            },
            "description": "The nextCursor of the previous page. Omit for the newest entries."
          },
          {
            "name": "view",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(all|charges)$",
              "examples": [
                "charges"
              ]
            },
            "description": "all (the default): every ledger event and receipt. charges: one entry per charge. The reserve, settle and release events of a reservation that has a receipt (a run, or a charged Library read) are left out, so each charge is listed once, as its receipt (kind read or receipt, with its units and credits). Refunds, grants, top-ups, promotional grants, expiries and the holds of runs still in progress are listed as with all. Pass the same view with each page’s cursor."
          }
        ]
      }
    },
    "/v1/dark-stores/summary": {
      "get": {
        "operationId": "getDarkStoreSummary",
        "summary": "Get open dark-store counts by app, city and area",
        "description": "How many quick-commerce dark stores Rewalto holds open (Blinkit, Zepto, Instamart, BigBasket, Flipkart Minutes, JioMart, DMart), counted by app, city and area, with the newest last-seen time per app and per city and when the counts were measured. Every store not closed is counted once; cities are in one spelling (Gurugram, not Gurgaon); area is the store's own locality, else its home pin code's main delivery post office, and null where neither is known (such stores are counted, not dropped). BigBasket’s BB Now delivery areas are not stores: they are in no store count and are counted apart as deliveryAreas, per app (0 for an app with none) and in total. Counts only: no store id, name or location (per-store records are GET /v1/data/dark-stores, catalogue entry qc_dark_store_map). Counted again at most every 10 minutes. Public and free.",
        "tags": [
          "Quick commerce"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Dark-store summary",
                  "description": "Open quick-commerce dark stores counted by app, city and area. Counts only; free.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Summary",
                      "description": "The counts, with when they were measured.",
                      "additionalProperties": false,
                      "required": [
                        "measuredAt",
                        "lastSeen",
                        "stores",
                        "cities",
                        "deliveryAreas",
                        "apps",
                        "byCity",
                        "counts"
                      ],
                      "properties": {
                        "measuredAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Measured at",
                          "description": "When these counts were taken (UTC).",
                          "examples": [
                            "2026-10-23T09:30:00.000Z"
                          ]
                        },
                        "lastSeen": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Last seen",
                          "description": "The newest time any store was seen (UTC); null when no store is held.",
                          "examples": [
                            "2026-10-22T21:47:01.218Z"
                          ]
                        },
                        "stores": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Stores",
                          "description": "Open dark stores, all apps.",
                          "examples": [
                            3050
                          ]
                        },
                        "cities": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Cities",
                          "description": "Distinct known cities with an open store.",
                          "examples": [
                            96
                          ]
                        },
                        "deliveryAreas": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Delivery areas",
                          "description": "Open delivery areas, all apps: named areas an app delivers to (BigBasket’s BB Now areas), counted apart because an area is not a store. In no store count.",
                          "examples": [
                            12452
                          ]
                        },
                        "apps": {
                          "type": "array",
                          "title": "Apps",
                          "description": "One row per app, most stores first, then most delivery areas.",
                          "items": {
                            "type": "object",
                            "title": "App",
                            "description": "One app’s open stores, and its delivery areas.",
                            "additionalProperties": false,
                            "required": [
                              "platform",
                              "stores",
                              "cities",
                              "deliveryAreas",
                              "lastSeen"
                            ],
                            "properties": {
                              "platform": {
                                "type": "string",
                                "title": "Platform",
                                "description": "The quick-commerce app: blinkit, zepto, instamart, bigbasket, flipkart_minutes, jiomart or dmart.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "stores": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Stores",
                                "description": "Open stores of this app.",
                                "examples": [
                                  1309
                                ]
                              },
                              "cities": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Cities",
                                "description": "Distinct known cities it has an open store in.",
                                "examples": [
                                  85
                                ]
                              },
                              "deliveryAreas": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Delivery areas",
                                "description": "Open delivery areas of this app (BigBasket’s BB Now areas), not stores; 0 for an app with none.",
                                "examples": [
                                  0
                                ]
                              },
                              "lastSeen": {
                                "type": "string",
                                "format": "date-time",
                                "title": "Last seen",
                                "description": "The newest time any of these stores was seen (UTC).",
                                "examples": [
                                  "2026-10-22T21:47:01.218Z"
                                ]
                              }
                            }
                          }
                        },
                        "byCity": {
                          "type": "array",
                          "title": "Cities",
                          "description": "One row per city, most stores first; stores with no known city are one row with city null.",
                          "items": {
                            "type": "object",
                            "title": "City",
                            "description": "One city’s open stores.",
                            "additionalProperties": false,
                            "required": [
                              "city",
                              "stores",
                              "apps",
                              "lastSeen"
                            ],
                            "properties": {
                              "city": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "City",
                                "description": "The city, in one spelling per city (Gurugram, not Gurgaon); null for stores whose city is not known.",
                                "examples": [
                                  "Gurugram"
                                ]
                              },
                              "stores": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Stores",
                                "description": "Open stores in this city, all apps.",
                                "examples": [
                                  358
                                ]
                              },
                              "apps": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Apps",
                                "description": "Distinct apps with an open store here.",
                                "examples": [
                                  6
                                ]
                              },
                              "lastSeen": {
                                "type": "string",
                                "format": "date-time",
                                "title": "Last seen",
                                "description": "The newest time any of these stores was seen (UTC).",
                                "examples": [
                                  "2026-10-22T21:47:01.218Z"
                                ]
                              }
                            }
                          }
                        },
                        "counts": {
                          "type": "array",
                          "title": "Counts",
                          "description": "Open stores per app, city and area, ordered by app, city and area. Area is null where it is not known.",
                          "items": {
                            "type": "object",
                            "title": "Count",
                            "description": "One app, city and area.",
                            "additionalProperties": false,
                            "required": [
                              "platform",
                              "city",
                              "area",
                              "stores"
                            ],
                            "properties": {
                              "platform": {
                                "type": "string",
                                "title": "Platform",
                                "description": "The quick-commerce app: blinkit, zepto, instamart, bigbasket, flipkart_minutes, jiomart or dmart.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "city": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "City",
                                "description": "The city, in one spelling per city (Gurugram, not Gurgaon); null for stores whose city is not known.",
                                "examples": [
                                  "Gurugram"
                                ]
                              },
                              "area": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Area",
                                "description": "The area: the store’s own locality, else its home pin code’s main delivery post office; null when neither is known.",
                                "examples": [
                                  "Sohna Road"
                                ]
                              },
                              "stores": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Stores",
                                "description": "Open stores of this app here.",
                                "examples": [
                                  4
                                ]
                              }
                            }
                          }
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "The (zero) charge.",
                      "additionalProperties": false,
                      "required": [
                        "credits"
                      ],
                      "properties": {
                        "credits": {
                          "$ref": "#/components/schemas/NoCharge"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/dark-stores/summary/compact": {
      "get": {
        "operationId": "getDarkStoreSummaryCompact",
        "summary": "Get open dark-store counts by app and city, compact",
        "description": "The same counts as GET /v1/dark-stores/summary, folded by app and city: one group per app and city with its store count, newest last-seen time and its areas as two lists of the same length (areas[i] holds areaStores[i] stores), plus the per-app rows and totals, delivery areas included. About a third of the full summary's size, so a site's fetch cache can keep it. Counts only: no store id, name or location. Counted again at most every 10 minutes. Public and free.",
        "tags": [
          "Quick commerce"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Dark-store summary, compact",
                  "description": "The same open-store counts as GET /v1/dark-stores/summary, folded by app and city, with each group’s areas as two lists of the same length. Counts only; free.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Compact summary",
                      "description": "The counts, with when they were measured.",
                      "additionalProperties": false,
                      "required": [
                        "measuredAt",
                        "lastSeen",
                        "stores",
                        "cities",
                        "deliveryAreas",
                        "apps",
                        "groups"
                      ],
                      "properties": {
                        "measuredAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Measured at",
                          "description": "When these counts were taken (UTC).",
                          "examples": [
                            "2026-10-23T09:30:00.000Z"
                          ]
                        },
                        "lastSeen": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Last seen",
                          "description": "The newest time any store was seen (UTC); null when no store is held.",
                          "examples": [
                            "2026-10-22T21:47:01.218Z"
                          ]
                        },
                        "stores": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Stores",
                          "description": "Open dark stores, all apps.",
                          "examples": [
                            3050
                          ]
                        },
                        "cities": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Cities",
                          "description": "Distinct known cities with an open store.",
                          "examples": [
                            96
                          ]
                        },
                        "deliveryAreas": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Delivery areas",
                          "description": "Open delivery areas, all apps: named areas an app delivers to (BigBasket’s BB Now areas), counted apart because an area is not a store. In no store count.",
                          "examples": [
                            12452
                          ]
                        },
                        "apps": {
                          "type": "array",
                          "title": "Apps",
                          "description": "One row per app, most stores first, then most delivery areas.",
                          "items": {
                            "type": "object",
                            "title": "App",
                            "description": "One app’s open stores, and its delivery areas.",
                            "additionalProperties": false,
                            "required": [
                              "platform",
                              "stores",
                              "cities",
                              "deliveryAreas",
                              "lastSeen"
                            ],
                            "properties": {
                              "platform": {
                                "type": "string",
                                "title": "Platform",
                                "description": "The quick-commerce app: blinkit, zepto, instamart, bigbasket, flipkart_minutes, jiomart or dmart.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "stores": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Stores",
                                "description": "Open stores of this app.",
                                "examples": [
                                  1309
                                ]
                              },
                              "cities": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Cities",
                                "description": "Distinct known cities it has an open store in.",
                                "examples": [
                                  85
                                ]
                              },
                              "deliveryAreas": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Delivery areas",
                                "description": "Open delivery areas of this app (BigBasket’s BB Now areas), not stores; 0 for an app with none.",
                                "examples": [
                                  0
                                ]
                              },
                              "lastSeen": {
                                "type": "string",
                                "format": "date-time",
                                "title": "Last seen",
                                "description": "The newest time any of these stores was seen (UTC).",
                                "examples": [
                                  "2026-10-22T21:47:01.218Z"
                                ]
                              }
                            }
                          }
                        },
                        "groups": {
                          "type": "array",
                          "title": "Groups",
                          "description": "One row per app and city, ordered by app, then city (null last). Every open store is in exactly one group and one area.",
                          "items": {
                            "type": "object",
                            "title": "Group",
                            "description": "One app’s open stores in one city, by area.",
                            "additionalProperties": false,
                            "required": [
                              "platform",
                              "city",
                              "stores",
                              "lastSeen",
                              "areas",
                              "areaStores"
                            ],
                            "properties": {
                              "platform": {
                                "type": "string",
                                "title": "Platform",
                                "description": "The quick-commerce app: blinkit, zepto, instamart, bigbasket, flipkart_minutes, jiomart or dmart.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "city": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "City",
                                "description": "The city, in one spelling per city (Gurugram, not Gurgaon); null for stores whose city is not known.",
                                "examples": [
                                  "Gurugram"
                                ]
                              },
                              "stores": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Stores",
                                "description": "Open stores of this app in this city.",
                                "examples": [
                                  42
                                ]
                              },
                              "lastSeen": {
                                "type": "string",
                                "format": "date-time",
                                "title": "Last seen",
                                "description": "The newest time any of these stores was seen (UTC).",
                                "examples": [
                                  "2026-10-22T21:47:01.218Z"
                                ]
                              },
                              "areas": {
                                "type": "array",
                                "title": "Areas",
                                "description": "The areas, ordered by name (null last); areaStores[i] is the open stores in areas[i].",
                                "items": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "Area",
                                  "description": "The area: the store’s own locality, else its home pin code’s main delivery post office; null when neither is known.",
                                  "examples": [
                                    "Sohna Road"
                                  ]
                                }
                              },
                              "areaStores": {
                                "type": "array",
                                "title": "Area stores",
                                "description": "Open stores per area, the same length and order as areas.",
                                "items": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "Stores",
                                  "description": "Open stores of this app in this area.",
                                  "examples": [
                                    4
                                  ]
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "The (zero) charge.",
                      "additionalProperties": false,
                      "required": [
                        "credits"
                      ],
                      "properties": {
                        "credits": {
                          "$ref": "#/components/schemas/NoCharge"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/data-requests": {
      "post": {
        "operationId": "createTrackedDataRequest",
        "summary": "Ask for data, with a promised reply",
        "description": "Records a data request from a signed-in user whose account email is verified, and promises a first human response by `respondBy`, which the server computes from the published commitment (GET /v1/data-requests/commitment): business days in its time zone, working days and holidays. The answer carries the reference (DR-000123), the status (`received`) and where the reply goes (`replyTo`, the verified email). A signed-in session whose token does not say the email is verified is still recorded, but untracked: `tracked: false`, `request: null`, `untrackedReason: \"email_not_verified\"`, and no promise. An API key or an MCP sign-in is refused (`forbidden`); use the public POST /v1/catalogue/requests there, which promises nothing. Text with an email address or phone number is refused. At most 5 requests a minute per caller and 100 per organisation a day. Never charged. Core has no email sender yet, so nothing is emailed: `acknowledgmentEmail` and `delivery` say `not_sent` until one exists.",
        "tags": [
          "Data requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "TrackedDataRequestCreated",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "tracked",
                    "request",
                    "recorded",
                    "untrackedReason",
                    "message",
                    "acknowledgmentEmail"
                  ],
                  "properties": {
                    "tracked": {
                      "type": "boolean",
                      "description": "true: a promised reply (`request` has the reference and respondBy). false: recorded as demand only, with NO promise, because the session’s email is not verified (`untrackedReason`). Show no deadline and no reference when false."
                    },
                    "request": {
                      "title": "TrackedDataRequest",
                      "type": [
                        "null",
                        "object"
                      ],
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "reference",
                        "kind",
                        "text",
                        "query",
                        "subject",
                        "surface",
                        "status",
                        "createdAt",
                        "inReviewAt",
                        "answeredAt",
                        "closedAt",
                        "respondBy",
                        "respondByLocal",
                        "timeZone",
                        "overdue",
                        "respondedInTime",
                        "owner",
                        "replyTo",
                        "emailErasedAt",
                        "replies"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "reference": {
                          "type": "string",
                          "pattern": "^DR-[0-9]{6,}$",
                          "description": "The reference to quote, e.g. DR-000123."
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "missing_data",
                            "not_held"
                          ]
                        },
                        "text": {
                          "type": "string"
                        },
                        "query": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "subject": {
                          "type": "string"
                        },
                        "surface": {
                          "type": "string",
                          "enum": [
                            "catalogue_page",
                            "search",
                            "intake",
                            "api",
                            "cli",
                            "mcp"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "answered",
                            "closed"
                          ],
                          "description": "received: recorded, not looked at yet. in_review: staff are on it. answered: staff replied. closed: finished. Treat an unknown value as in progress."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "When it was received."
                        },
                        "inReviewAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "answeredAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "The first reply: the first human response."
                        },
                        "closedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "respondBy": {
                          "type": "string",
                          "format": "date-time",
                          "description": "The promised time of the first human response, computed by the server when the request was made from the commitment then in force (business days, working days, holidays, time zone). It never moves. Show this; never compute a deadline in the frontend."
                        },
                        "respondByLocal": {
                          "type": "string",
                          "description": "respondBy as local wall time in `timeZone` with its offset, e.g. 2026-10-20T18:00:00+05:30."
                        },
                        "timeZone": {
                          "type": "string",
                          "description": "The commitment’s time zone, e.g. Asia/Kolkata."
                        },
                        "overdue": {
                          "type": "boolean",
                          "description": "No reply yet, not closed, and respondBy has passed (at the time of this answer)."
                        },
                        "respondedInTime": {
                          "type": [
                            "null",
                            "boolean"
                          ],
                          "description": "Whether the first reply came by respondBy; null until there is a reply."
                        },
                        "owner": {
                          "type": "string",
                          "description": "Who answers for the request (a name)."
                        },
                        "replyTo": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "description": "Where the reply goes: the requester’s verified account email, as it was when asked. null once erased, 90 days after the request was closed (D-1832)."
                        },
                        "emailErasedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "When replyTo was erased (90 days after closing); null while it is kept."
                        },
                        "replies": {
                          "type": "array",
                          "description": "Rewalto’s replies, oldest first.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "body",
                              "at"
                            ],
                            "properties": {
                              "body": {
                                "type": "string"
                              },
                              "at": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      },
                      "description": "The tracked request; null when `tracked` is false."
                    },
                    "recorded": {
                      "title": "DataRequest",
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "subject",
                        "surface",
                        "createdAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "missing_data",
                            "not_held"
                          ],
                          "description": "not_held: a pasted product Rewalto does not collect. missing_data: anything else."
                        },
                        "subject": {
                          "type": "string",
                          "description": "What it is counted under: retailer:<key>, site:<host>, product:<id> or text:<words>."
                        },
                        "surface": {
                          "type": "string",
                          "enum": [
                            "catalogue_page",
                            "search",
                            "intake",
                            "api",
                            "cli",
                            "mcp"
                          ]
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "description": "The recorded request (always): its id, kind, subject, surface and time."
                    },
                    "untrackedReason": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "`email_not_verified` when `tracked` is false (verify the email and sign in again to get a promise); null when tracked. Treat an unknown value as not tracked."
                    },
                    "message": {
                      "type": "string",
                      "description": "What to show: the reference and when to expect a reply, or, when not tracked, that it was recorded with no reply promised."
                    },
                    "acknowledgmentEmail": {
                      "type": "string",
                      "enum": [
                        "sent",
                        "not_sent"
                      ],
                      "description": "Whether an acknowledgment email went to replyTo. `not_sent` today: Core has no email sender yet."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/DataRequestCreate"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listTrackedDataRequests",
        "summary": "My data requests, with their status",
        "description": "The signed-in user’s own tracked requests, newest first: reference, status, respondBy, overdue, and any replies. Only the user’s own; an API key is refused.",
        "tags": [
          "Data requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "TrackedDataRequestList",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "description": "Newest first.",
                      "items": {
                        "title": "TrackedDataRequest",
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "reference",
                          "kind",
                          "text",
                          "query",
                          "subject",
                          "surface",
                          "status",
                          "createdAt",
                          "inReviewAt",
                          "answeredAt",
                          "closedAt",
                          "respondBy",
                          "respondByLocal",
                          "timeZone",
                          "overdue",
                          "respondedInTime",
                          "owner",
                          "replyTo",
                          "emailErasedAt",
                          "replies"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reference": {
                            "type": "string",
                            "pattern": "^DR-[0-9]{6,}$",
                            "description": "The reference to quote, e.g. DR-000123."
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "missing_data",
                              "not_held"
                            ]
                          },
                          "text": {
                            "type": "string"
                          },
                          "query": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "subject": {
                            "type": "string"
                          },
                          "surface": {
                            "type": "string",
                            "enum": [
                              "catalogue_page",
                              "search",
                              "intake",
                              "api",
                              "cli",
                              "mcp"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "received",
                              "in_review",
                              "answered",
                              "closed"
                            ],
                            "description": "received: recorded, not looked at yet. in_review: staff are on it. answered: staff replied. closed: finished. Treat an unknown value as in progress."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "When it was received."
                          },
                          "inReviewAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "answeredAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "description": "The first reply: the first human response."
                          },
                          "closedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "respondBy": {
                            "type": "string",
                            "format": "date-time",
                            "description": "The promised time of the first human response, computed by the server when the request was made from the commitment then in force (business days, working days, holidays, time zone). It never moves. Show this; never compute a deadline in the frontend."
                          },
                          "respondByLocal": {
                            "type": "string",
                            "description": "respondBy as local wall time in `timeZone` with its offset, e.g. 2026-10-20T18:00:00+05:30."
                          },
                          "timeZone": {
                            "type": "string",
                            "description": "The commitment’s time zone, e.g. Asia/Kolkata."
                          },
                          "overdue": {
                            "type": "boolean",
                            "description": "No reply yet, not closed, and respondBy has passed (at the time of this answer)."
                          },
                          "respondedInTime": {
                            "type": [
                              "null",
                              "boolean"
                            ],
                            "description": "Whether the first reply came by respondBy; null until there is a reply."
                          },
                          "owner": {
                            "type": "string",
                            "description": "Who answers for the request (a name)."
                          },
                          "replyTo": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Where the reply goes: the requester’s verified account email, as it was when asked. null once erased, 90 days after the request was closed (D-1832)."
                          },
                          "emailErasedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "description": "When replyTo was erased (90 days after closing); null while it is kept."
                          },
                          "replies": {
                            "type": "array",
                            "description": "Rewalto’s replies, oldest first.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "body",
                                "at"
                              ],
                              "properties": {
                                "body": {
                                  "type": "string"
                                },
                                "at": {
                                  "type": "string",
                                  "format": "date-time"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([1-9]|[1-9][0-9]|100)$"
            },
            "description": "At most this many (1-100, default 50)."
          }
        ]
      }
    },
    "/v1/data-requests/commitment": {
      "get": {
        "operationId": "getResponseCommitment",
        "summary": "The published response commitment",
        "description": "The promise in force for tracked data requests: the first human response within `firstResponseBusinessDays` business days (`workingDays` in `timeZone`, minus `holidays`), due at `dayEndsAt` local time, owned by `owner`, and the sentence to publish. Public; never charged. Use it for the page copy instead of writing the numbers into the frontend.",
        "tags": [
          "Data requests"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "ResponseCommitmentAnswer",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "commitment"
                  ],
                  "properties": {
                    "commitment": {
                      "title": "ResponseCommitment",
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "firstResponseBusinessDays",
                        "timeZone",
                        "workingDays",
                        "dayEndsAt",
                        "receiptCutoff",
                        "owner",
                        "publishedText",
                        "effectiveFrom",
                        "holidays",
                        "signInRequired"
                      ],
                      "properties": {
                        "firstResponseBusinessDays": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "timeZone": {
                          "type": "string"
                        },
                        "workingDays": {
                          "type": "array",
                          "items": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 7
                          },
                          "description": "ISO weekdays: 1 = Monday ... 7 = Sunday."
                        },
                        "dayEndsAt": {
                          "type": "string",
                          "pattern": "^[0-9]{2}:[0-9]{2}$",
                          "description": "A promise falls due at this local time on its last business day."
                        },
                        "receiptCutoff": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "description": "HH:MM local. A request received at or after it, or on a non-business day, counts from the next business day. null: no cut-off."
                        },
                        "owner": {
                          "type": "string"
                        },
                        "publishedText": {
                          "type": "string",
                          "description": "The sentence to publish."
                        },
                        "effectiveFrom": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "holidays": {
                          "type": "array",
                          "description": "Holidays from today on (not business days). Empty when there are none.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "day",
                              "name"
                            ],
                            "properties": {
                              "day": {
                                "type": "string",
                                "format": "date"
                              },
                              "name": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "signInRequired": {
                          "type": "boolean",
                          "const": true,
                          "description": "Only a signed-in user with a verified email gets the promise."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/data-requests/{reference}": {
      "get": {
        "operationId": "getTrackedDataRequest",
        "summary": "One of my data requests",
        "description": "One of the signed-in user’s own tracked requests by its reference. Anyone else’s answers `not_found`, never confirming it exists.",
        "tags": [
          "Data requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "TrackedDataRequestAnswer",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "request"
                  ],
                  "properties": {
                    "request": {
                      "title": "TrackedDataRequest",
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "reference",
                        "kind",
                        "text",
                        "query",
                        "subject",
                        "surface",
                        "status",
                        "createdAt",
                        "inReviewAt",
                        "answeredAt",
                        "closedAt",
                        "respondBy",
                        "respondByLocal",
                        "timeZone",
                        "overdue",
                        "respondedInTime",
                        "owner",
                        "replyTo",
                        "emailErasedAt",
                        "replies"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "reference": {
                          "type": "string",
                          "pattern": "^DR-[0-9]{6,}$",
                          "description": "The reference to quote, e.g. DR-000123."
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "missing_data",
                            "not_held"
                          ]
                        },
                        "text": {
                          "type": "string"
                        },
                        "query": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "subject": {
                          "type": "string"
                        },
                        "surface": {
                          "type": "string",
                          "enum": [
                            "catalogue_page",
                            "search",
                            "intake",
                            "api",
                            "cli",
                            "mcp"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "answered",
                            "closed"
                          ],
                          "description": "received: recorded, not looked at yet. in_review: staff are on it. answered: staff replied. closed: finished. Treat an unknown value as in progress."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "When it was received."
                        },
                        "inReviewAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "answeredAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "The first reply: the first human response."
                        },
                        "closedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "respondBy": {
                          "type": "string",
                          "format": "date-time",
                          "description": "The promised time of the first human response, computed by the server when the request was made from the commitment then in force (business days, working days, holidays, time zone). It never moves. Show this; never compute a deadline in the frontend."
                        },
                        "respondByLocal": {
                          "type": "string",
                          "description": "respondBy as local wall time in `timeZone` with its offset, e.g. 2026-10-20T18:00:00+05:30."
                        },
                        "timeZone": {
                          "type": "string",
                          "description": "The commitment’s time zone, e.g. Asia/Kolkata."
                        },
                        "overdue": {
                          "type": "boolean",
                          "description": "No reply yet, not closed, and respondBy has passed (at the time of this answer)."
                        },
                        "respondedInTime": {
                          "type": [
                            "null",
                            "boolean"
                          ],
                          "description": "Whether the first reply came by respondBy; null until there is a reply."
                        },
                        "owner": {
                          "type": "string",
                          "description": "Who answers for the request (a name)."
                        },
                        "replyTo": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "description": "Where the reply goes: the requester’s verified account email, as it was when asked. null once erased, 90 days after the request was closed (D-1832)."
                        },
                        "emailErasedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "When replyTo was erased (90 days after closing); null while it is kept."
                        },
                        "replies": {
                          "type": "array",
                          "description": "Rewalto’s replies, oldest first.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "body",
                              "at"
                            ],
                            "properties": {
                              "body": {
                                "type": "string"
                              },
                              "at": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^DR-[0-9]{6,}$"
            }
          }
        ]
      }
    },
    "/v1/data/ads": {
      "get": {
        "operationId": "listAdCreatives",
        "summary": "List ad creatives from the Ads Transparency Center",
        "description": "Each ad creative a watched brand’s advertiser ran in India, as Google’s Ads Transparency Center lists it, read weekly: the advertiser and creative ids, the format (text, image or video), the first and last day shown, the weeks Rewalto read it, a SHA-256 fingerprint and the creative’s public page on the centre; never the ad’s text, image or video. readVia says whether it was read under the brand’s own advertiser account or through its website (which also finds agency-placed ads). Newest day last shown first, optionally one brand, one advertiser id and a day range. Catalogue entry lib_ad_creatives; one record is one ad creative. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AdCreativesPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Mamaearth (Honasa Consumer)"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this watched brand (exact match, case-sensitive), as in the brand field."
          },
          {
            "name": "advertiser",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Advertiser id",
              "examples": [
                "AR17979653942044262401"
              ],
              "pattern": "^AR[0-9]{20}$"
            },
            "description": "Only this advertiser id."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only creatives whose day is on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only creatives whose day is on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/availability": {
      "get": {
        "operationId": "getAvailability",
        "summary": "Is a product in stock at a pin code",
        "description": "For one six-digit pin code and one product (listingId: one retailer listing, such as a search result; or productId: the listings matched to that Rewalto product, across retailers, that were read at this pin in the last 30 days, at most 100), one row per listing: in_stock, out_of_stock, or unknown with the reason, from the listing's newest kept reading at that pin, with the reading's time and, where the reading records it, the retailer's store. Never a guess: unknown when the newest reading is older than 48 hours (stale), when there is none in 30 days (no_reading_at_pin), when the retailer does not report stock (stock_not_reported), or when the reading falls on a pin-day left out of the data (excluded_pin_day, with the reason and decision). Charged like GET /v1/data/listings, 1 credit per 10 rows whose state is known (in or out of stock), rounded up; unknown rows and an empty answer cost nothing; re-reading the same answer within 7 days is free. When the credits cannot cover it: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AvailabilityAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pincode",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110092"
              ],
              "pattern": "^[1-9][0-9]{5}$"
            },
            "description": "A six-digit pin code."
          },
          {
            "name": "listingId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Listing",
              "examples": [
                "3b8f1c2a-6d4e-4a7b-9c10-2e5f8a1d4b66"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "description": "A listing id, e.g. a search result id."
          },
          {
            "name": "productId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Product",
              "examples": [
                "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "description": "A Rewalto product id (a listing's productId)."
          }
        ]
      }
    },
    "/v1/data/availability/pin": {
      "get": {
        "operationId": "getPinAvailability",
        "summary": "Share in stock per retailer at a pin code",
        "description": "For one six-digit pin code (optionally one retailer), one row per retailer: how many of its listings read at that pin are in stock and out of stock, by each listing's newest kept reading there, and the share in stock. Only readings at most 48 hours old count as in or out of stock; listings read there in the last 30 days whose newest reading is older, does not report stock, or falls on a pin-day left out of the data are counted under unknown, by reason. From a summary refreshed hourly (meta.refreshedAt). Charged like GET /v1/data/listings, 1 credit per 10 retailer rows with a known share, rounded up; rows without one and an empty answer cost nothing; re-reading the same answer within 7 days is free. When the credits cannot cover it: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PinAvailabilityAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pincode",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110092"
              ],
              "pattern": "^[1-9][0-9]{5}$"
            },
            "description": "A six-digit pin code."
          },
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer."
          }
        ]
      }
    },
    "/v1/data/backers": {
      "get": {
        "operationId": "listBackerRecords",
        "summary": "List investor records (firms and angels)",
        "description": "Investors Rewalto holds, one record per investor: venture funds, accelerators, incubators, family offices, corporate venture arms, private equity and angel networks, and individual angels (investorKind). Each with its type, headquarters, the geographies, stages and sectors it states, cheque size, thesis, website, LinkedIn and public email; a firm’s office number only, never an individual’s phone. Most recently added first; optionally a name fragment, kind, type, sector, stage or India focus. Catalogue entry ds_funding_rounds; one record is one investor. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Backer records page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "BackerRecord",
                        "description": "One investor: a firm (venture fund, accelerator, incubator, family office, corporate venture arm, private equity, angel network) or an individual angel (investorKind), with what it states it invests in. A firm’s office number only; never an individual’s phone.",
                        "additionalProperties": false,
                        "required": [
                          "investorId",
                          "name",
                          "investorKind",
                          "investorType",
                          "hqCountry",
                          "hqCity",
                          "geos",
                          "stages",
                          "sectors",
                          "chequeText",
                          "chequeMinUsd",
                          "chequeMaxUsd",
                          "leadsRounds",
                          "thesis",
                          "recentActivity",
                          "website",
                          "title",
                          "organisation",
                          "linkedinUrl",
                          "twitterUrl",
                          "email",
                          "companyPhone",
                          "indiaFocus",
                          "firstSeen",
                          "lastUpdated"
                        ],
                        "properties": {
                          "investorId": {
                            "type": "string",
                            "title": "Investor id",
                            "description": "Rewalto investor id.",
                            "examples": [
                              "2210"
                            ]
                          },
                          "name": {
                            "type": "string",
                            "title": "Name",
                            "description": "Firm name, or the angel investor’s name.",
                            "examples": [
                              "Reach Capital"
                            ]
                          },
                          "investorKind": {
                            "type": "string",
                            "title": "Kind",
                            "description": "firm or individual.",
                            "examples": [
                              "firm"
                            ],
                            "enum": [
                              "firm",
                              "individual"
                            ]
                          },
                          "investorType": {
                            "type": "string",
                            "title": "Type",
                            "description": "vc_fund, micro_vc, accelerator, incubator, venture_studio, family_office, corporate_vc, private_equity, angel_network, venture_debt, government_fund, other_firm, or angel for an individual.",
                            "examples": [
                              "vc_fund"
                            ]
                          },
                          "hqCountry": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "HQ country",
                            "description": "Headquarters country, where known.",
                            "examples": [
                              "United States"
                            ]
                          },
                          "hqCity": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "HQ city",
                            "description": "Headquarters city, where known.",
                            "examples": [
                              "San Francisco"
                            ]
                          },
                          "geos": {
                            "type": "array",
                            "title": "Geographies",
                            "description": "Countries or regions it invests in, as stated.",
                            "items": {
                              "type": "string"
                            },
                            "examples": [
                              [
                                "India"
                              ]
                            ]
                          },
                          "stages": {
                            "type": "array",
                            "title": "Stages",
                            "description": "Stages it invests at, as stated.",
                            "items": {
                              "type": "string"
                            },
                            "examples": [
                              [
                                "Seed",
                                "Series A"
                              ]
                            ]
                          },
                          "sectors": {
                            "type": "array",
                            "title": "Sectors",
                            "description": "Sectors it invests in, as stated.",
                            "items": {
                              "type": "string"
                            },
                            "examples": [
                              [
                                "Consumer",
                                "D2C"
                              ]
                            ]
                          },
                          "chequeText": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Cheque size",
                            "description": "Cheque size as stated.",
                            "examples": [
                              "Seed $1.2M - $5.5M"
                            ]
                          },
                          "chequeMinUsd": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Cheque from (USD)",
                            "description": "Smallest cheque in US dollars, where readable.",
                            "examples": [
                              1200000
                            ]
                          },
                          "chequeMaxUsd": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Cheque to (USD)",
                            "description": "Largest cheque in US dollars, where readable.",
                            "examples": [
                              5500000
                            ]
                          },
                          "leadsRounds": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Leads rounds",
                            "description": "Whether it leads rounds, as stated.",
                            "examples": [
                              "Yes"
                            ]
                          },
                          "thesis": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Thesis",
                            "description": "Investment thesis, as stated.",
                            "examples": [
                              "Backs education and workforce brands."
                            ]
                          },
                          "recentActivity": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Recent activity",
                            "description": "Recent deals, as stated.",
                            "examples": [
                              "Led a seed round in 2026."
                            ]
                          },
                          "website": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Website",
                            "description": "The firm’s website.",
                            "examples": [
                              "https://reachcapital.com"
                            ]
                          },
                          "title": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Title",
                            "description": "An individual’s title, as stated.",
                            "examples": [
                              "Partner"
                            ]
                          },
                          "organisation": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Organisation",
                            "description": "An individual’s organisation, as stated.",
                            "examples": [
                              "Example Ventures"
                            ]
                          },
                          "linkedinUrl": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "LinkedIn",
                            "description": "The firm’s LinkedIn page, or the individual’s public profile.",
                            "examples": [
                              "https://www.linkedin.com/company/reach-capital"
                            ]
                          },
                          "twitterUrl": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "X",
                            "description": "X (Twitter) account.",
                            "examples": [
                              "https://x.com/example"
                            ]
                          },
                          "email": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Email",
                            "description": "Public email address.",
                            "examples": [
                              "hello@example.com"
                            ]
                          },
                          "companyPhone": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Office phone",
                            "description": "A firm’s office number; never an individual’s phone.",
                            "examples": [
                              "+91 22 6100 0000"
                            ]
                          },
                          "indiaFocus": {
                            "type": "boolean",
                            "title": "India focus",
                            "description": "True when it states India among the places it invests or is based.",
                            "examples": [
                              true
                            ]
                          },
                          "firstSeen": {
                            "type": "string",
                            "format": "date-time",
                            "title": "First seen",
                            "description": "When Rewalto first held the record (UTC).",
                            "examples": [
                              "2026-10-22T09:30:00Z"
                            ]
                          },
                          "lastUpdated": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Last updated",
                            "description": "When the record last changed (UTC). A change keeps the earlier version.",
                            "examples": [
                              "2026-10-22T09:30:00Z"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Name",
              "examples": [
                "capital"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "Only records whose name contains this text (case-insensitive), 2 to 100 characters."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Kind",
              "examples": [
                "firm"
              ],
              "pattern": "^(firm|individual)$"
            },
            "description": "firm or individual."
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Type",
              "examples": [
                "vc_fund"
              ],
              "pattern": "^[a-z_]{3,30}$"
            },
            "description": "Only this investor type, as in investorType."
          },
          {
            "name": "sector",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Sector",
              "examples": [
                "Consumer"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "Only investors stating this sector (case-insensitive, whole sector)."
          },
          {
            "name": "stage",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Stage",
              "examples": [
                "Seed"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "Only investors stating this stage (case-insensitive, whole stage)."
          },
          {
            "name": "india",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "India focus",
              "examples": [
                "true"
              ],
              "pattern": "^(true|false)$"
            },
            "description": "true for investors that state India."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/badges": {
      "get": {
        "operationId": "listBadges",
        "summary": "List the badges a product showed per pin code",
        "description": "For one retailer: each listing that showed at least one badge on an IST day (bestseller, assured, only few left, deal tags and the like), per pin code, with the distinct badges as the retailer wrote them, the readings that showed one and the day’s last reading. Newest day first, optionally one product (retailerSku), one pin code and a day range. Catalogue entry lib_badges; one record is one listing-day. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Badges page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "BadgeDay",
                        "description": "One listing at one pin code on one IST day that showed at least one badge (bestseller, assured, only few left, deal tags), as the retailer wrote them.",
                        "additionalProperties": false,
                        "required": [
                          "day",
                          "retailer",
                          "retailerSku",
                          "pincode",
                          "badges",
                          "readings",
                          "lastObservationId",
                          "lastObservedAt"
                        ],
                        "properties": {
                          "day": {
                            "type": "string",
                            "format": "date",
                            "title": "Day",
                            "description": "The IST day.",
                            "examples": [
                              "2026-10-21"
                            ]
                          },
                          "retailer": {
                            "type": "string",
                            "title": "Retailer",
                            "description": "The retailer.",
                            "examples": [
                              "blinkit"
                            ]
                          },
                          "retailerSku": {
                            "type": "string",
                            "title": "Retailer SKU",
                            "description": "The retailer's own product id.",
                            "examples": [
                              "512345"
                            ]
                          },
                          "pincode": {
                            "type": "string",
                            "title": "Pin code",
                            "description": "The pin code, or national.",
                            "examples": [
                              "560034"
                            ]
                          },
                          "badges": {
                            "type": "array",
                            "title": "Badges",
                            "description": "The distinct badges shown that day, sorted, as written (at most 50).",
                            "items": {
                              "type": "string",
                              "examples": [
                                "BESTSELLER"
                              ]
                            }
                          },
                          "readings": {
                            "type": "integer",
                            "title": "Readings",
                            "description": "Readings of the day that showed a badge.",
                            "examples": [
                              2
                            ]
                          },
                          "lastObservationId": {
                            "type": "string",
                            "title": "Last observation",
                            "description": "The day’s last kept reading (its source, fetch time and SHA-256).",
                            "examples": [
                              "48210377"
                            ]
                          },
                          "lastObservedAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Last observed at",
                            "description": "When that reading was taken.",
                            "examples": [
                              "2026-10-21T15:40:00Z"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "512345"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this retailer product id."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^(national|[1-9][0-9]{5})$"
            },
            "description": "Only this six-digit pin code, or national."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-09-02"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-09-06"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0wOS0wNlQwMDowMDowMFoiLCJpIjoiMCJ9"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/banners": {
      "get": {
        "operationId": "listBannerPlacements",
        "summary": "List banner ads in quick-commerce search",
        "description": "For one app (zepto or instamart): each brand banner ad seen on a search term at a pin code on an IST day, with the brand, the keyword it bought and the billing model where the app states them, how many search replies and dark stores carried it, its best position and the products it links to. The creative is a SHA-256 fingerprint, never the image. Newest day first, optionally one brand, one search term, one pin code and a day range. Catalogue entry lib_banner_units; one record is one banner placement. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BannerPlacementsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "zepto"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The app: zepto or instamart."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Mamaearth"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand (exact match, case-sensitive)."
          },
          {
            "name": "searchTerm",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Search term",
              "examples": [
                "shampoo"
              ],
              "minLength": 1,
              "maxLength": 100
            },
            "description": "Only this search term (exact)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^[0-9]{6}$"
            },
            "description": "Only this six-digit pin code."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/brand-shelf": {
      "get": {
        "operationId": "listBrandShelf",
        "summary": "List a brand’s share of shelf by pin code",
        "description": "For one retailer: each brand’s distinct listings read at a pin code on an IST day against all distinct listings read there (the shelf), as a share in basis points. Rolled up daily from Rewalto’s own readings from 25 Aug 2026. Newest day first, optionally one pin code, one brand and a day range. Catalogue entry lib_brand_shelf; one record is one brand at one pin on one day. Charged per record delivered at the history rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandShelfPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^(national|[0-9]{6})$"
            },
            "description": "Only this six-digit pin code, or national."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Amul"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand (exact match, case-sensitive)."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/brands": {
      "get": {
        "operationId": "getBrand",
        "summary": "Get a brand profile",
        "description": "One brand profile by name (case-insensitive exact match): category, website, and its logo and favicon URLs, never the files. An empty list when the brand is unknown. Free: no credits are charged.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Name",
              "examples": [
                "Amul"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "The brand name (case-insensitive exact match)."
          }
        ]
      }
    },
    "/v1/data/brands/directory": {
      "get": {
        "operationId": "listBrandDirectory",
        "summary": "List brands with their spellings and owners",
        "description": "Canonical brands in brand-key order (the name lower-cased, accents folded, letters and digits only), optionally only those whose key starts with q: every spelling seen for the brand and where (written by retailers on listings, read from titles by a model, or a person-checked alias), how many listings and titles carry it, and its owning companies where known, with the basis. Refreshed daily. Catalogue entry ds_brands; one record is one brand. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Brand directory page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "BrandDirectoryEntry",
                        "description": "One canonical brand: every spelling seen for it, where, and who owns it.",
                        "additionalProperties": false,
                        "required": [
                          "brandKey",
                          "name",
                          "aliases",
                          "listings",
                          "titlesTagged",
                          "owners",
                          "refreshedAt"
                        ],
                        "properties": {
                          "brandKey": {
                            "type": "string",
                            "title": "Brand key",
                            "description": "The brand lower-cased with only letters and digits kept.",
                            "examples": [
                              "nivea"
                            ]
                          },
                          "name": {
                            "type": "string",
                            "title": "Name",
                            "description": "The spelling seen on most listings.",
                            "examples": [
                              "Nivea"
                            ]
                          },
                          "aliases": {
                            "type": "array",
                            "title": "Spellings",
                            "description": "Every spelling, most seen first.",
                            "items": {
                              "type": "object",
                              "title": "BrandAlias",
                              "description": "One spelling of the brand and where it was seen.",
                              "additionalProperties": false,
                              "required": [
                                "alias",
                                "source",
                                "seen",
                                "retailers"
                              ],
                              "properties": {
                                "alias": {
                                  "type": "string",
                                  "title": "Spelling",
                                  "description": "The brand as written (a promo alias is its key).",
                                  "examples": [
                                    "NIVEA"
                                  ]
                                },
                                "source": {
                                  "type": "string",
                                  "enum": [
                                    "retailer",
                                    "model_tag",
                                    "promo_alias"
                                  ],
                                  "title": "Source",
                                  "description": "retailer: written by a retailer on a listing; model_tag: read from a product title by a model; promo_alias: an alias a person checked.",
                                  "examples": [
                                    "retailer"
                                  ]
                                },
                                "seen": {
                                  "type": "integer",
                                  "title": "Seen",
                                  "description": "Listings (retailer) or titles (model_tag) carrying it; 0 for a promo alias.",
                                  "examples": [
                                    812
                                  ]
                                },
                                "retailers": {
                                  "type": "integer",
                                  "title": "Retailers",
                                  "description": "Retailers writing it (retailer only; else 0).",
                                  "examples": [
                                    11
                                  ]
                                }
                              }
                            }
                          },
                          "listings": {
                            "type": "integer",
                            "title": "Listings",
                            "description": "Retailer listings carrying the brand.",
                            "examples": [
                              1240
                            ]
                          },
                          "titlesTagged": {
                            "type": "integer",
                            "title": "Titles tagged",
                            "description": "Product titles a model read the brand from.",
                            "examples": [
                              530
                            ]
                          },
                          "owners": {
                            "type": "array",
                            "title": "Owners",
                            "description": "Owning companies, with the basis; empty when not known.",
                            "items": {
                              "type": "object",
                              "title": "BrandOwner",
                              "description": "A company that owns the brand, with the basis for the link.",
                              "additionalProperties": false,
                              "required": [
                                "company",
                                "basis",
                                "companyRecordId"
                              ],
                              "properties": {
                                "company": {
                                  "type": "string",
                                  "title": "Company",
                                  "description": "The owning company’s name.",
                                  "examples": [
                                    "Honasa Consumer"
                                  ]
                                },
                                "basis": {
                                  "type": "string",
                                  "enum": [
                                    "promo_alias",
                                    "company_name",
                                    "company_website"
                                  ],
                                  "title": "Basis",
                                  "description": "promo_alias: a person named the company; company_name: a company record’s name (without legal words) is the brand; company_website: a company record’s website is the brand’s name.",
                                  "examples": [
                                    "promo_alias"
                                  ]
                                },
                                "companyRecordId": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "Company record",
                                  "description": "The company’s record in /v1/data/companies, when there is one.",
                                  "examples": [
                                    "1042"
                                  ]
                                }
                              }
                            }
                          },
                          "refreshedAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Refreshed at",
                            "description": "When the directory last refreshed the brand.",
                            "examples": [
                              "2026-10-22T15:00:00Z"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Name",
              "examples": [
                "nive"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only brands whose key starts with this name’s letters and digits (case and accents ignored)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/brands/owners": {
      "get": {
        "operationId": "listBrandOwners",
        "summary": "List brands with their owning companies",
        "description": "The brands Rewalto can link to an owning company, in brand-key order, optionally only those whose key starts with q, each with the company, the basis (a person named it, a company record’s name is the brand, or a company record’s website is the brand’s name) and the company record when there is one. Same records as the brand directory, owned brands only. Catalogue entry ds_brand_company; one record is one brand. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Brand directory page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "BrandDirectoryEntry",
                        "description": "One canonical brand: every spelling seen for it, where, and who owns it.",
                        "additionalProperties": false,
                        "required": [
                          "brandKey",
                          "name",
                          "aliases",
                          "listings",
                          "titlesTagged",
                          "owners",
                          "refreshedAt"
                        ],
                        "properties": {
                          "brandKey": {
                            "type": "string",
                            "title": "Brand key",
                            "description": "The brand lower-cased with only letters and digits kept.",
                            "examples": [
                              "nivea"
                            ]
                          },
                          "name": {
                            "type": "string",
                            "title": "Name",
                            "description": "The spelling seen on most listings.",
                            "examples": [
                              "Nivea"
                            ]
                          },
                          "aliases": {
                            "type": "array",
                            "title": "Spellings",
                            "description": "Every spelling, most seen first.",
                            "items": {
                              "type": "object",
                              "title": "BrandAlias",
                              "description": "One spelling of the brand and where it was seen.",
                              "additionalProperties": false,
                              "required": [
                                "alias",
                                "source",
                                "seen",
                                "retailers"
                              ],
                              "properties": {
                                "alias": {
                                  "type": "string",
                                  "title": "Spelling",
                                  "description": "The brand as written (a promo alias is its key).",
                                  "examples": [
                                    "NIVEA"
                                  ]
                                },
                                "source": {
                                  "type": "string",
                                  "enum": [
                                    "retailer",
                                    "model_tag",
                                    "promo_alias"
                                  ],
                                  "title": "Source",
                                  "description": "retailer: written by a retailer on a listing; model_tag: read from a product title by a model; promo_alias: an alias a person checked.",
                                  "examples": [
                                    "retailer"
                                  ]
                                },
                                "seen": {
                                  "type": "integer",
                                  "title": "Seen",
                                  "description": "Listings (retailer) or titles (model_tag) carrying it; 0 for a promo alias.",
                                  "examples": [
                                    812
                                  ]
                                },
                                "retailers": {
                                  "type": "integer",
                                  "title": "Retailers",
                                  "description": "Retailers writing it (retailer only; else 0).",
                                  "examples": [
                                    11
                                  ]
                                }
                              }
                            }
                          },
                          "listings": {
                            "type": "integer",
                            "title": "Listings",
                            "description": "Retailer listings carrying the brand.",
                            "examples": [
                              1240
                            ]
                          },
                          "titlesTagged": {
                            "type": "integer",
                            "title": "Titles tagged",
                            "description": "Product titles a model read the brand from.",
                            "examples": [
                              530
                            ]
                          },
                          "owners": {
                            "type": "array",
                            "title": "Owners",
                            "description": "Owning companies, with the basis; empty when not known.",
                            "items": {
                              "type": "object",
                              "title": "BrandOwner",
                              "description": "A company that owns the brand, with the basis for the link.",
                              "additionalProperties": false,
                              "required": [
                                "company",
                                "basis",
                                "companyRecordId"
                              ],
                              "properties": {
                                "company": {
                                  "type": "string",
                                  "title": "Company",
                                  "description": "The owning company’s name.",
                                  "examples": [
                                    "Honasa Consumer"
                                  ]
                                },
                                "basis": {
                                  "type": "string",
                                  "enum": [
                                    "promo_alias",
                                    "company_name",
                                    "company_website"
                                  ],
                                  "title": "Basis",
                                  "description": "promo_alias: a person named the company; company_name: a company record’s name (without legal words) is the brand; company_website: a company record’s website is the brand’s name.",
                                  "examples": [
                                    "promo_alias"
                                  ]
                                },
                                "companyRecordId": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "Company record",
                                  "description": "The company’s record in /v1/data/companies, when there is one.",
                                  "examples": [
                                    "1042"
                                  ]
                                }
                              }
                            }
                          },
                          "refreshedAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Refreshed at",
                            "description": "When the directory last refreshed the brand.",
                            "examples": [
                              "2026-10-22T15:00:00Z"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Name",
              "examples": [
                "nive"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only brands whose key starts with this name’s letters and digits (case and accents ignored)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/companies": {
      "get": {
        "operationId": "listCompanyRecords",
        "summary": "List company and brand records",
        "description": "Companies and brands Rewalto holds, one record per company: name, kind (brand, agency, startup, company), website and web host, place, industry and sectors, description, employee, revenue and online sales bands, founded year, store platform, the company’s own social accounts with their Instagram and LinkedIn follower counts, an annual revenue estimate in rupees and estimated monthly site visits where measured, and its company email and phone where public. Most recently added first; optionally a name fragment, one web host, kind, startup or not, state, city or store platform. Catalogue entry ds_company_records; one record is one company. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Company records page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "CompanyRecord",
                        "description": "One company or brand with its public facts: identity, place, industry, size bands, store platform, its own web and social accounts, and its company email and phone where public. Never a person’s phone, and never the private sales pipeline.",
                        "additionalProperties": false,
                        "required": [
                          "companyId",
                          "name",
                          "kind",
                          "isStartup",
                          "website",
                          "websiteHost",
                          "country",
                          "state",
                          "city",
                          "industry",
                          "sectors",
                          "description",
                          "employeeBand",
                          "revenueBand",
                          "gmvBand",
                          "foundedYear",
                          "startupStage",
                          "storefrontPlatform",
                          "storefrontUrl",
                          "linkedinUrl",
                          "instagramUrl",
                          "facebookUrl",
                          "twitterUrl",
                          "youtubeUrl",
                          "instagramFollowers",
                          "linkedinFollowers",
                          "revenueEstimateInr",
                          "monthlyVisits",
                          "email",
                          "companyPhone",
                          "firstSeen",
                          "lastUpdated"
                        ],
                        "properties": {
                          "companyId": {
                            "type": "string",
                            "title": "Company id",
                            "description": "Rewalto company id.",
                            "examples": [
                              "1042"
                            ]
                          },
                          "name": {
                            "type": "string",
                            "title": "Name",
                            "description": "Company or brand name.",
                            "examples": [
                              "Nakedlyyours"
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "title": "Kind",
                            "description": "brand, agency, startup or company.",
                            "examples": [
                              "brand"
                            ],
                            "enum": [
                              "brand",
                              "agency",
                              "startup",
                              "company"
                            ]
                          },
                          "isStartup": {
                            "type": "boolean",
                            "title": "Startup",
                            "description": "True for a startup.",
                            "examples": [
                              false
                            ]
                          },
                          "website": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Website",
                            "description": "The company’s website.",
                            "examples": [
                              "https://nakedlyyours.com"
                            ]
                          },
                          "websiteHost": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Website host",
                            "description": "Its web host, without www.",
                            "examples": [
                              "nakedlyyours.com"
                            ]
                          },
                          "country": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Country",
                            "description": "Country.",
                            "examples": [
                              "IN"
                            ]
                          },
                          "state": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "State",
                            "description": "State, where known.",
                            "examples": [
                              "Kerala"
                            ]
                          },
                          "city": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "City",
                            "description": "City, where known.",
                            "examples": [
                              "Ernakulam"
                            ]
                          },
                          "industry": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Industry",
                            "description": "Industry or category path.",
                            "examples": [
                              "Beauty & Fitness/Face & Body Care/Skin & Nail Care"
                            ]
                          },
                          "sectors": {
                            "type": "array",
                            "title": "Sectors",
                            "description": "Sectors or categories.",
                            "items": {
                              "type": "string"
                            },
                            "examples": [
                              [
                                "Beauty & Fitness",
                                "Skin & Nail Care"
                              ]
                            ]
                          },
                          "description": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Description",
                            "description": "What the company does.",
                            "examples": [
                              "Vegetarian bath and beauty range."
                            ]
                          },
                          "employeeBand": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Employee band",
                            "description": "Employee count band, where known.",
                            "examples": [
                              "11-50"
                            ]
                          },
                          "revenueBand": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Revenue band",
                            "description": "Revenue band, where known; an estimate, never a filing.",
                            "examples": [
                              "1-10cr"
                            ]
                          },
                          "gmvBand": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Online sales band",
                            "description": "Online sales band, where known; an estimate.",
                            "examples": [
                              "1-10cr"
                            ]
                          },
                          "foundedYear": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Founded",
                            "description": "Year founded, where known.",
                            "examples": [
                              2017
                            ]
                          },
                          "startupStage": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Stage",
                            "description": "Startup stage, where known.",
                            "examples": [
                              "Seed"
                            ]
                          },
                          "storefrontPlatform": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Store platform",
                            "description": "Online store platform, where known.",
                            "examples": [
                              "shopify"
                            ]
                          },
                          "storefrontUrl": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Store",
                            "description": "Online store address.",
                            "examples": [
                              "https://nakedlyyours.com"
                            ]
                          },
                          "linkedinUrl": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "LinkedIn",
                            "description": "The company’s own LinkedIn page.",
                            "examples": [
                              "https://www.linkedin.com/company/example"
                            ]
                          },
                          "instagramUrl": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Instagram",
                            "description": "The company’s own Instagram account.",
                            "examples": [
                              "https://instagram.com/example"
                            ]
                          },
                          "facebookUrl": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Facebook",
                            "description": "The company’s own Facebook page.",
                            "examples": [
                              "https://facebook.com/example"
                            ]
                          },
                          "twitterUrl": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "X",
                            "description": "The company’s own X (Twitter) account.",
                            "examples": [
                              "https://x.com/example"
                            ]
                          },
                          "youtubeUrl": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "YouTube",
                            "description": "The company’s own YouTube channel.",
                            "examples": [
                              "https://youtube.com/@example"
                            ]
                          },
                          "instagramFollowers": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Instagram followers",
                            "description": "Followers of the company’s own Instagram account, where measured.",
                            "examples": [
                              12974
                            ]
                          },
                          "linkedinFollowers": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "LinkedIn followers",
                            "description": "Followers of the company’s own LinkedIn page, where measured.",
                            "examples": [
                              1187
                            ]
                          },
                          "revenueEstimateInr": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Revenue estimate (INR)",
                            "description": "Annual revenue estimate in rupees, where known; an estimate, never a filing.",
                            "examples": [
                              643116
                            ]
                          },
                          "monthlyVisits": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Monthly visits",
                            "description": "Estimated monthly visits to its website, where measured.",
                            "examples": [
                              195901
                            ]
                          },
                          "email": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Email",
                            "description": "The company’s email address, where public.",
                            "examples": [
                              "hello@example.com"
                            ]
                          },
                          "companyPhone": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Phone",
                            "description": "The company’s phone number, where public.",
                            "examples": [
                              "+91 22 6100 0000"
                            ]
                          },
                          "firstSeen": {
                            "type": "string",
                            "format": "date-time",
                            "title": "First seen",
                            "description": "When Rewalto first held the record (UTC).",
                            "examples": [
                              "2026-10-22T09:30:00Z"
                            ]
                          },
                          "lastUpdated": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Last updated",
                            "description": "When the record last changed (UTC). A change keeps the earlier version.",
                            "examples": [
                              "2026-10-22T09:30:00Z"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Name",
              "examples": [
                "capital"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "Only records whose name contains this text (case-insensitive), 2 to 100 characters."
          },
          {
            "name": "host",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Website host",
              "examples": [
                "nakedlyyours.com"
              ],
              "pattern": "^[a-z0-9.-]{1,253}$"
            },
            "description": "Only the company at this web host (exact, without www)."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Kind",
              "examples": [
                "brand"
              ],
              "pattern": "^(brand|agency|startup|company)$"
            },
            "description": "Only this kind."
          },
          {
            "name": "startup",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Startup",
              "examples": [
                "true"
              ],
              "pattern": "^(true|false)$"
            },
            "description": "true for startups only, false for the rest."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "State",
              "examples": [
                "Maharashtra"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "Only this state (case-insensitive)."
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "City",
              "examples": [
                "Mumbai"
              ],
              "minLength": 2,
              "maxLength": 200
            },
            "description": "Only this city (case-insensitive)."
          },
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Store platform",
              "examples": [
                "shopify"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "Only this online store platform (case-insensitive)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/d2c-brands": {
      "get": {
        "operationId": "listD2cBrands",
        "summary": "List D2C brands from the brand directory",
        "description": "Each Indian D2C brand in Rewalto’s brand directory: store host, brand name, platform, categories, city and state, employees and a size band, estimated monthly visits and sales with bands (estimates, not reported figures; sales in US cents), products sold, sales channels, technologies, public social pages, and the platform Rewalto itself detected when the store is in the storefront index. Brand level only: no personal contact data. Host order, optionally one store, one platform, a category, a state or a city. Catalogue entry ds_d2c_brand_directory; one record is one brand store. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/D2cBrandsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "host",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Store",
              "examples": [
                "www.kent.co.in"
              ],
              "pattern": "^[a-z0-9][a-z0-9.-]{1,252}$"
            },
            "description": "Only this store (its host name, lower case, with or without www.)."
          },
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Platform",
              "examples": [
                "Shopify"
              ],
              "maxLength": 64
            },
            "description": "Only brands on this platform, as the directory writes it (case-insensitive)."
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Category",
              "examples": [
                "Home & Garden"
              ],
              "maxLength": 100
            },
            "description": "Only brands with a category containing this text (case-insensitive)."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "State",
              "examples": [
                "Karnataka"
              ],
              "maxLength": 64
            },
            "description": "Only brands in this state (case-insensitive)."
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "City",
              "examples": [
                "Bengaluru"
              ],
              "maxLength": 64
            },
            "description": "Only brands in this city (case-insensitive)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/dark-stores": {
      "get": {
        "operationId": "listDarkStores",
        "summary": "List quick-commerce dark stores and their catchments",
        "description": "Each dark store Rewalto holds on Blinkit, Zepto, Instamart, BigBasket, Flipkart Minutes, JioMart and DMart, every source merged into one record per store: the app’s store id and name, the pin code, area, address, point, city and state where it is (each with where it came from), the pin codes it was seen serving, when it was first and last seen, whether it is open, newly opened or closed, and which sources hold it (the old weekly sweep, Core’s own weekly serviceability sweeps, which add stores as they run, Rewalto’s other readings of the app, and store lists Rewalto holds). Kept data, served as it stands (the newest last-seen day shows how current it is). Newest last-seen day first, optionally one platform, one city, one status, a day range, and pincode for the stores that serve that pin. BigBasket’s BB Now delivery areas are not stores and are not in it (they are counted apart in GET /v1/dark-stores/summary). Catalogue entry qc_dark_store_map; one record is one dark store. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Dark stores page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "DarkStore",
                        "description": "One quick-commerce dark store Rewalto holds, every source merged into one record (C-029): its app, store id, name, the pin code, area, address, point, city and state where it is, the pin codes it was seen serving (its catchment), when it was first and last seen, and whether it is open, newly opened or closed.",
                        "additionalProperties": false,
                        "required": [
                          "day",
                          "source",
                          "platform",
                          "storeId",
                          "name",
                          "city",
                          "status",
                          "sweepStatus",
                          "catchmentPins",
                          "catchmentPoints",
                          "firstSeen",
                          "lastSeen",
                          "closedAt",
                          "seenSweeps",
                          "missedSweeps",
                          "lat",
                          "lon",
                          "id",
                          "sources",
                          "homePincode",
                          "pincodeSource",
                          "area",
                          "address",
                          "state",
                          "country",
                          "coordSource"
                        ],
                        "properties": {
                          "day": {
                            "type": "string",
                            "format": "date",
                            "title": "Day",
                            "description": "The IST day the store was last seen. The order and the from and to filters use this day.",
                            "examples": [
                              "2026-10-15"
                            ]
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "old_sweep",
                              "core_sweep",
                              "app_reading",
                              "store_list"
                            ],
                            "title": "Source",
                            "description": "Where its status comes from: old_sweep (the weekly sweeps up to 17 Oct 2026) or core_sweep (Core’s weekly serviceability sweeps), the one that saw it most recently; for a store no sweep has seen, app_reading (Rewalto’s other readings of the app: its locator, product readings at a pin) or store_list (a store list Rewalto holds). Every source that holds the store is in sources.",
                            "examples": [
                              "old_sweep"
                            ]
                          },
                          "platform": {
                            "type": "string",
                            "title": "Platform",
                            "description": "The quick-commerce app: blinkit, zepto, instamart, bigbasket, flipkart_minutes or jiomart.",
                            "examples": [
                              "blinkit"
                            ],
                            "pattern": "^[a-z0-9_]{2,40}$"
                          },
                          "storeId": {
                            "type": "string",
                            "title": "Store id",
                            "description": "The app’s own id for the store; for a store known only from a store list, Rewalto’s own id for it (ds-<id>).",
                            "examples": [
                              "1234"
                            ]
                          },
                          "name": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Name",
                            "description": "The store name the app states; null when it states none.",
                            "examples": [
                              "HSR"
                            ]
                          },
                          "city": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "City",
                            "description": "The city the sweep found it in, else the city of its first catchment pin; null when neither is known.",
                            "examples": [
                              "Bengaluru"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "open",
                              "opened",
                              "closed"
                            ],
                            "title": "Status",
                            "description": "open (seen in the sweeps since the first one), opened (first seen after the first sweep of its city: a new store) or closed (no longer seen).",
                            "examples": [
                              "open"
                            ]
                          },
                          "sweepStatus": {
                            "type": "string",
                            "title": "Sweep status",
                            "description": "The sweep’s own status word. old_sweep: active, opened, flicker (missed in one sweep and seen again) or closed. core_sweep: seen (in the app’s newest sweep week) or missed.",
                            "examples": [
                              "active"
                            ]
                          },
                          "catchmentPins": {
                            "type": "array",
                            "title": "Catchment pin codes",
                            "description": "The pin codes the store was seen serving, ascending.",
                            "items": {
                              "type": "string",
                              "pattern": "^[1-9][0-9]{5}$"
                            },
                            "examples": [
                              [
                                "560034",
                                "560102"
                              ]
                            ]
                          },
                          "catchmentPoints": {
                            "type": "array",
                            "title": "Catchment points",
                            "description": "Sweep grid points (latitude,longitude) the store was seen serving that the sweep did not place on a pin code; empty for most stores.",
                            "items": {
                              "type": "string"
                            },
                            "examples": [
                              [
                                "22.48303,88.35303"
                              ]
                            ]
                          },
                          "firstSeen": {
                            "type": "string",
                            "format": "date-time",
                            "title": "First seen",
                            "description": "When a sweep first saw the store (UTC).",
                            "examples": [
                              "2026-10-13T14:30:26.000Z"
                            ]
                          },
                          "lastSeen": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Last seen",
                            "description": "When a sweep last saw the store (UTC).",
                            "examples": [
                              "2026-10-15T16:27:27.000Z"
                            ]
                          },
                          "closedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "title": "Closed at",
                            "description": "When the store was marked closed; null while open.",
                            "examples": [
                              "2026-10-20T00:00:00.000Z"
                            ]
                          },
                          "seenSweeps": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Sweeps seen",
                            "description": "How many sweeps saw the store; null for core_sweep stores.",
                            "examples": [
                              2
                            ]
                          },
                          "missedSweeps": {
                            "type": "integer",
                            "title": "Sweeps missed",
                            "description": "How many sweeps since it was last seen missed it.",
                            "examples": [
                              0
                            ],
                            "minimum": 0
                          },
                          "lat": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Latitude",
                            "description": "Latitude when located; null otherwise.",
                            "examples": [
                              12.9116
                            ]
                          },
                          "lon": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Longitude",
                            "description": "Longitude when located; null otherwise.",
                            "examples": [
                              77.6389
                            ]
                          },
                          "id": {
                            "type": "string",
                            "title": "Id",
                            "description": "Rewalto’s own id for the store, stable across refreshes.",
                            "examples": [
                              "1042"
                            ],
                            "pattern": "^[0-9]+$"
                          },
                          "sources": {
                            "type": "array",
                            "title": "Sources",
                            "description": "Every kind of source that holds the store (old_sweep, core_sweep, app_reading, store_list).",
                            "items": {
                              "type": "string",
                              "enum": [
                                "old_sweep",
                                "core_sweep",
                                "app_reading",
                                "store_list"
                              ]
                            },
                            "examples": [
                              [
                                "old_sweep",
                                "app_reading"
                              ]
                            ]
                          },
                          "homePincode": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "pattern": "^[1-9][0-9]{5}$",
                            "title": "Pin code",
                            "description": "The pin code the store is in; null when unknown. pincodeSource says how it is known: an estimate (catchment, catchment_point) is the pin it serves most, not its address.",
                            "examples": [
                              "560034"
                            ]
                          },
                          "pincodeSource": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "old_sweep",
                              "core_sweep",
                              "app_reading",
                              "store_list",
                              "pin_code",
                              "nearest_pin_centre",
                              "catchment",
                              "catchment_point",
                              "served_points_centroid",
                              "store_label",
                              null
                            ],
                            "title": "Pin code source",
                            "description": "app_reading or store_list (stated), nearest_pin_centre (the pin whose centre is nearest the store’s own point), catchment (its most-seen catchment pin) or catchment_point (the pin nearest a grid point it served); null with no pin.",
                            "examples": [
                              "catchment"
                            ]
                          },
                          "area": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Area",
                            "description": "The locality the store is in: as a source stated it, else the main locality of its pin code (India Post); null when unknown.",
                            "examples": [
                              "Koramangala"
                            ]
                          },
                          "address": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Address",
                            "description": "The store’s address as the app or a store list states it; null when none does.",
                            "examples": [
                              "Sector 110, Gurugram, Haryana, 122017"
                            ]
                          },
                          "state": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "State",
                            "description": "The state: as a source stated it, else its pin code’s; null when unknown.",
                            "examples": [
                              "Karnataka"
                            ]
                          },
                          "country": {
                            "type": "string",
                            "title": "Country",
                            "description": "ISO 3166-1 alpha-2 country code.",
                            "examples": [
                              "IN"
                            ],
                            "pattern": "^[A-Z]{2}$"
                          },
                          "coordSource": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "old_sweep",
                              "core_sweep",
                              "app_reading",
                              "store_list",
                              "pin_code",
                              "nearest_pin_centre",
                              "catchment",
                              "catchment_point",
                              "served_points_centroid",
                              "store_label",
                              null
                            ],
                            "title": "Point source",
                            "description": "Where lat and lon come from: the app’s own statement of the store’s point (old_sweep, core_sweep, app_reading), or served_points_centroid, the centroid of the points the store served, derived by Rewalto because the app states none; null when not located.",
                            "examples": [
                              "core_sweep"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Platform",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The quick-commerce app: blinkit, zepto, instamart, bigbasket, flipkart_minutes or jiomart."
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "City",
              "examples": [
                "Bengaluru"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "Only stores in this city (case-insensitive, exact name)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^[1-9][0-9]{5}$"
            },
            "description": "Only stores that serve this six-digit pin code."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Status",
              "examples": [
                "opened"
              ],
              "pattern": "^(open|opened|closed)$"
            },
            "description": "Only stores with this status: open, opened or closed."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/delivery-eta": {
      "get": {
        "operationId": "listDeliveryEta",
        "summary": "List delivery time by pin code",
        "description": "The delivery time quick-commerce apps stated at each pin code on each IST day: how many readings, the share that stated a time, and the least, median, 90th percentile and greatest minutes, with the source labelled (search: Rewalto’s product searches; partner: partner app reads, 16 Sep to 14 Oct 2026; sweep: one reading per pin per weekly dark-store sweep). Kept data, served as it stands. Newest day first, optionally one retailer, one pin code, one source and a day range. Catalogue entry qc_eta_by_pin; one record is one retailer, pin, day and source. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Delivery time by pin page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "DeliveryEtaDay",
                        "description": "The delivery time an app stated at one pin code on one IST day, from one kind of reading: how many readings there were, the share that stated a time, and the least, median, 90th percentile and greatest minutes.",
                        "additionalProperties": false,
                        "required": [
                          "day",
                          "retailer",
                          "pincode",
                          "city",
                          "source",
                          "readings",
                          "etaReadings",
                          "etaShare",
                          "minMinutes",
                          "medianMinutes",
                          "p90Minutes",
                          "maxMinutes",
                          "newestObservedAt"
                        ],
                        "properties": {
                          "day": {
                            "type": "string",
                            "format": "date",
                            "title": "Day",
                            "description": "The IST day of the readings.",
                            "examples": [
                              "2026-10-21"
                            ]
                          },
                          "retailer": {
                            "type": "string",
                            "title": "Retailer",
                            "description": "The app.",
                            "examples": [
                              "blinkit"
                            ],
                            "pattern": "^[a-z0-9_]{2,40}$"
                          },
                          "pincode": {
                            "type": "string",
                            "title": "Pin code",
                            "description": "The six-digit pin code.",
                            "examples": [
                              "560034"
                            ],
                            "pattern": "^[1-9][0-9]{5}$"
                          },
                          "city": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "City",
                            "description": "The pin code’s city in the India Post directory; null when it is not listed.",
                            "examples": [
                              "Bengaluru"
                            ]
                          },
                          "source": {
                            "type": "string",
                            "enum": [
                              "search",
                              "partner",
                              "sweep"
                            ],
                            "title": "Source",
                            "description": "Which readings: search (Rewalto’s product searches; many readings a day), partner (a partner’s app reads, 16 Sep to 14 Oct 2026), sweep (one reading per pin per weekly dark-store sweep).",
                            "examples": [
                              "search"
                            ]
                          },
                          "readings": {
                            "type": "integer",
                            "title": "Readings",
                            "description": "Readings from this source at the pin that day.",
                            "examples": [
                              5735
                            ],
                            "minimum": 1
                          },
                          "etaReadings": {
                            "type": "integer",
                            "title": "Readings with a time",
                            "description": "How many of them stated a delivery time.",
                            "examples": [
                              5701
                            ],
                            "minimum": 1
                          },
                          "etaShare": {
                            "type": "number",
                            "title": "Share with a time",
                            "description": "etaReadings / readings, three decimals.",
                            "examples": [
                              0.799
                            ]
                          },
                          "minMinutes": {
                            "type": "integer",
                            "title": "Least minutes",
                            "description": "The shortest delivery time stated.",
                            "examples": [
                              8
                            ],
                            "minimum": 0
                          },
                          "medianMinutes": {
                            "type": "number",
                            "title": "Median minutes",
                            "description": "The median delivery time stated, one decimal.",
                            "examples": [
                              15
                            ]
                          },
                          "p90Minutes": {
                            "type": "number",
                            "title": "90th percentile minutes",
                            "description": "Nine in ten stated times were at or under this, one decimal.",
                            "examples": [
                              30
                            ]
                          },
                          "maxMinutes": {
                            "type": "integer",
                            "title": "Greatest minutes",
                            "description": "The longest delivery time stated.",
                            "examples": [
                              30
                            ],
                            "minimum": 0
                          },
                          "newestObservedAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Newest reading",
                            "description": "The newest reading that stated a time (UTC).",
                            "examples": [
                              "2026-10-21T18:20:00.000000Z"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this app."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^[1-9][0-9]{5}$"
            },
            "description": "Only this six-digit pin code."
          },
          {
            "name": "source",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Source",
              "examples": [
                "search"
              ],
              "pattern": "^(search|partner|sweep)$"
            },
            "description": "Only this source: search, partner or sweep."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/discounts": {
      "get": {
        "operationId": "listDiscounts",
        "summary": "List discount depth by brand and category",
        "description": "For one retailer: for each brand and category on an IST day, the readings with a selling price and an MRP, how many were priced below MRP, and the average, median and deepest discount in basis points of MRP. Rolled up daily from Rewalto’s own readings from 25 Aug 2026, so the festive season’s discounting can be read day by day. Newest day first, optionally one brand, one category and a day range. Catalogue entry lib_festive_discounts; one record is one brand and category on one day. Charged per record delivered at the history rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiscountsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Amul"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand (exact match, case-sensitive)."
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Category",
              "examples": [
                "Dairy"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this category, as the retailer wrote it."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/discover": {
      "get": {
        "operationId": "discoverListings",
        "summary": "Preview a product search, free",
        "description": "Free discovery before a paid Fetch (issue #12). For the words and filters searchListings takes: up to 25 real matching listings, best first, each with an opaque selectionId, its primary image address and matched Rewalto product id where held, and its newest kept price, MRP and stock reading of the last 30 days (never a guess: a state says when there is none); exact counts over every match (total, by retailer, by brand) with how they matched; the fields a Fetch delivers; when the matches were last read; and the published rates with what fetching every match would cost. Each organisation has a number of free previews per IST day (allowance; a preview that finds nothing does not count); a free preview takes no credits and meta.credits is zero. Past them a preview is never refused: it is charged at the listings rate for the rows shown, exactly like searchListings (allowance.paid is true and meta.credits says what it cost; identical rows re-read within 7 days are free, nothing found costs nothing), and only when the credits cannot cover it is it refused with 402 credits_exhausted and no data. An organisation with unlimited credits is never capped. To fetch: searchListings with fetch.all.query (every match), or listListings with selection (chosen rows), or listObservations with a row's retailer and retailerSku (its history); each charges on delivery at the rate shown.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DiscoverPreview"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Words",
              "examples": [
                "amul butter"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Name, brand or retailer product id words; up to 8 are used."
          },
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Amul"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand, exactly as the retailer wrote it."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110092"
              ],
              "pattern": "^[1-9][0-9]{5}$"
            },
            "description": "Only listings read at this pin code in the last 30 days; the price shown is the newest reading there."
          },
          {
            "name": "location",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Location",
              "examples": [
                "loc_in_city_bengaluru"
              ],
              "minLength": 1,
              "maxLength": 120
            },
            "description": "A Core location id (location lookup: a pin, city, area or dark store). With confirmPins, only listings read at its pin codes: the same consent rule as searchListings. A dark store means the pin codes it serves."
          },
          {
            "name": "confirmPins",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Confirm pin codes",
              "examples": [
                "42"
              ],
              "pattern": "^[1-9][0-9]{0,4}$"
            },
            "description": "The pin-code count the location filter answered, to confirm using them (as on searchListings)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Rows",
              "examples": [
                "25"
              ],
              "pattern": "^[1-9][0-9]?$"
            },
            "description": "Preview rows, 1 to 25. Default 25. The counts are always over every match."
          }
        ]
      }
    },
    "/v1/data/launches": {
      "get": {
        "operationId": "listLaunches",
        "summary": "List launches: new listings the day they first appeared",
        "description": "Each listing that appeared on a retailer’s shelf at a pin code on an IST day where it was not before, classified new_product, new_pack, new_seller or relisting, with its brand, title, pack, first-seen price and MRP and the reading it was first seen in. detectedBy says whether the previous system’s launch radar found it (2 to 6 Sep 2026, kept as history) or Rewalto’s daily launch roll. Newest day first, optionally one retailer, pin code, brand, class and a day range. Catalogue entry lib_launches; one record is one listing. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Launches page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "Launch",
                        "description": "A listing that appeared on a retailer’s shelf at a pin code on an IST day where it was not before, classified, with the reading it was first seen in.",
                        "additionalProperties": false,
                        "required": [
                          "day",
                          "retailer",
                          "retailerSku",
                          "pincode",
                          "class",
                          "category",
                          "brand",
                          "title",
                          "packSizeText",
                          "firstObservedAt",
                          "priceMinor",
                          "mrpMinor",
                          "inStock",
                          "gapDays",
                          "observationId",
                          "detectedBy"
                        ],
                        "properties": {
                          "day": {
                            "type": "string",
                            "format": "date",
                            "title": "Day",
                            "description": "The IST day it first appeared.",
                            "examples": [
                              "2026-09-03"
                            ]
                          },
                          "retailer": {
                            "type": "string",
                            "title": "Retailer",
                            "description": "The retailer.",
                            "examples": [
                              "blinkit"
                            ]
                          },
                          "retailerSku": {
                            "type": "string",
                            "title": "Retailer SKU",
                            "description": "The retailer's own product id.",
                            "examples": [
                              "512345"
                            ]
                          },
                          "pincode": {
                            "type": "string",
                            "title": "Pin code",
                            "description": "The pin code it appeared at.",
                            "examples": [
                              "560034"
                            ]
                          },
                          "class": {
                            "type": "string",
                            "enum": [
                              "new_product",
                              "new_pack",
                              "new_seller",
                              "relisting"
                            ],
                            "title": "Class",
                            "description": "new_product (never seen anywhere), new_pack (a new size of a known product), new_seller (sold elsewhere, new at this retailer) or relisting (back after at least 14 days off this retailer’s shelf).",
                            "examples": [
                              "new_product"
                            ]
                          },
                          "category": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Category",
                            "description": "The category it was read under.",
                            "examples": [
                              "Dairy"
                            ]
                          },
                          "brand": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Brand",
                            "description": "The brand, as listed.",
                            "examples": [
                              "Amul"
                            ]
                          },
                          "title": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Title",
                            "description": "The title, as listed.",
                            "examples": [
                              "Amul High Protein Milk 1 L"
                            ]
                          },
                          "packSizeText": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Pack size",
                            "description": "The pack size as written.",
                            "examples": [
                              "1 L"
                            ]
                          },
                          "firstObservedAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "First observed at",
                            "description": "The first reading of the day it was seen in.",
                            "examples": [
                              "2026-09-03T02:14:00Z"
                            ]
                          },
                          "priceMinor": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Price",
                            "description": "The first-seen price in paise.",
                            "examples": [
                              "9900"
                            ]
                          },
                          "mrpMinor": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "MRP",
                            "description": "The MRP in paise, if shown.",
                            "examples": [
                              "10500"
                            ]
                          },
                          "inStock": {
                            "type": [
                              "null",
                              "boolean"
                            ],
                            "title": "In stock",
                            "description": "In stock at that reading, if known.",
                            "examples": [
                              true
                            ]
                          },
                          "gapDays": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Gap",
                            "description": "For a relisting, the days it was off the shelf.",
                            "examples": [
                              21
                            ]
                          },
                          "observationId": {
                            "type": "string",
                            "title": "Observation",
                            "description": "The kept reading it was first seen in (its source, fetch time and SHA-256).",
                            "examples": [
                              "48210377"
                            ]
                          },
                          "detectedBy": {
                            "type": "string",
                            "enum": [
                              "previous_system",
                              "core"
                            ],
                            "title": "Detected by",
                            "description": "previous_system: the previous system’s launch radar (2 to 6 Sep 2026, kept as history); core: Rewalto’s daily launch roll.",
                            "examples": [
                              "core"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^[1-9][0-9]{5}$"
            },
            "description": "Only this six-digit pin code."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Amul"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand, as the retailer wrote it (exact match)."
          },
          {
            "name": "class",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Class",
              "examples": [
                "new_product"
              ],
              "pattern": "^(new_product|new_pack|new_seller|relisting)$"
            },
            "description": "Only this class: new_product, new_pack, new_seller or relisting."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-09-02"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-09-06"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0wOS0wNlQwMDowMDowMFoiLCJpIjoiMCJ9"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/listings": {
      "get": {
        "operationId": "listListings",
        "summary": "List retailer listings",
        "description": "Retailer listings (what a retailer sells, as last seen), newest first, each with all its image URLs (primary first). With selection, exactly the listings chosen in a free preview (discoverListings), by their selectionIds. Charged 1 credit per 10 listings delivered, rounded up; re-reading the same listings within 7 days is free, and an empty page costs nothing. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListingsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Aashirvaad"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only records with exactly this brand text, as the retailer wrote it (exact match, case-sensitive)."
          },
          {
            "name": "productId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Product",
              "examples": [
                "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
              ],
              "format": "uuid"
            },
            "description": "Only records matched to this Rewalto product id."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "prd-88213"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this retailer product id (use together with retailer)."
          },
          {
            "name": "selection",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Selection",
              "examples": [
                "sel_7c1e5f0a2f554d2b8c360f3f1d9c2b77,sel_0d6b4a524b6e4c1a9a7e5b0d2f8f1a11"
              ],
              "pattern": "^sel_[0-9a-f]{32}(,sel_[0-9a-f]{32}){0,99}$"
            },
            "description": "Only these listings: comma-separated selectionIds from the free preview (discoverListings), 1 to 100; a repeated id counts once. Charged like every listings page, for the listings delivered."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/listings/search": {
      "get": {
        "operationId": "searchListings",
        "summary": "Search retailer listings by name",
        "description": "Listings whose name, brand or retailer product id contain every word of q. Whole words first (contract 0.58.0): when any listing holds every word of q as a whole word, only such listings are returned (\"amul butter\" finds Amul butters, never Amul Buttermilk, and never the brand's other products); otherwise each word matches the start of a word (\"aashir atta\" finds \"Aashirvaad Atta\"). Each result carries match: how it matched (exact_id, phrase, words, brand, near) and how many words of q are whole words of it. Optionally only one retailer, one exact brand, or listings read at one pin code in the last 30 days. Best match first: a listing whose retailer product id is exactly q; then listings where more words of q are whole words of the name (\"atta\" finds \"Aashirvaad Atta\" before \"Attar\"); then listings whose product is the thing typed: the main part of the name (before a |, a comma, \" - \", or for, with, made or by) ends with the last word of q, sizes, units and pack words aside (\"amul butter\" finds \"Amul Salted Butter\" before \"Amul Butter Bread\"); then names with fewer words that are not in q (\"Amul Butter\" before \"Amul Salted Butter\"); then, only to break a tie, names holding the words of q in order and next to each other; then more frequent matches, then the most recently seen. When fewer than 10 listings match, listings whose name holds each word of q of 5 or more letters approximately (a likely misspelling: \"ashirvad\" finds \"Aashirvaad\") follow, after every listing that matches: first those whose name also has the shorter words of q (\"oil\" in \"sunflwr oil\"), then those closest to the whole of q. Paged with nextCursor. With include=latest (contract 0.59.0) each result also carries latest, its newest kept price reading in the last 30 days (price, MRP, stock, pin code, time; at the pin codes asked for, else at any pin), never a guess. Each result is a listing, charged like GET /v1/data/listings: 1 credit per 10 listings delivered, prices included (contract 0.72.0, issue #221: a price reading adds nothing), rounded up, so 10 results cost 1 credit and 25 cost 3; re-reading the same page within 7 days is free, and a search that finds nothing costs nothing. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListingsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Words",
              "examples": [
                "aashirvaad atta"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "What to look for: name, brand or retailer product id words."
          },
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Aashirvaad"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only records with exactly this brand text, as the retailer wrote it (exact match, case-sensitive)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110092"
              ],
              "pattern": "^[1-9][0-9]{5}$"
            },
            "description": "Only listings read at this six-digit pin code in the last 30 days."
          },
          {
            "name": "location",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Location",
              "examples": [
                "IN:city:karnataka:bengaluru"
              ],
              "pattern": "^[A-Z]{2}:(pin:[1-9][0-9]{5}|city:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}|area:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}:[a-z0-9]{1,120}|store:[a-z0-9_]{2,40}:[A-Za-z0-9_-]{1,64})$"
            },
            "description": "A Core location id from the free lookup (GET /v1/data/locations, /cities or /stores): a pin, a city, an area or a dark store. It resolves to an explicit list of pin codes (see GET /v1/data/locations/filter). Never combine with pincode. More than one pin needs confirmPins. A store id (IN:store:<retailer>:<store id>) means the pin codes that dark store serves (its catchment as the sweeps saw it). Readings are kept per pin code, not per store, so it reads every kept reading at those pin codes, whichever store served them; no reading is attributed to the store itself."
          },
          {
            "name": "confirmPins",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Confirm pins",
              "examples": [
                "112"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "Your consent to a multi-pin read: the number of pins the location resolves to, as GET /v1/data/locations/filter showed it. A different number is refused with the current count, so a place is never silently broadened."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "50"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many listings to return, 1 to 100. Default 50."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          },
          {
            "name": "mode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Mode",
              "examples": [
                "semantic"
              ],
              "pattern": "^(words|semantic)$"
            },
            "description": "words (the default): the word search described above. semantic: the listings nearest in meaning to q (its embedding against each listing's embedding of title, brand and retailer; OpenAI text-embedding-3-small), with the same retailer, brand and location filters, nearest first, each with a similarity. Semantic answers one page of up to limit listings and takes no cursor (nextCursor is always null); a listing not embedded yet is found only by the word search. 503 unavailable when semantic search is not available on this deployment."
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^latest$",
              "title": "Include",
              "examples": [
                "latest"
              ]
            },
            "description": "latest: each result also carries its newest kept price reading in the last 30 days (price, MRP, stock, pin code, time; at the pin codes asked for, else at any pin), never a guess. Prices are included: the page is charged by listings delivered only, at the published listings rate (contract 0.72.0, issue #221). Omit for listings only."
          }
        ]
      }
    },
    "/v1/data/locations": {
      "get": {
        "operationId": "listLocations",
        "summary": "Find locations (pin codes) by pin, city, area or district",
        "description": "The free location selector. Find pin codes by a pin or its first digits, or by the start of a city, area (post office) or district name. Each row has stable Core location ids (locationId for the pin, cityLocationId, areaLocationId), the market, labels, the centre point, KEPT coverage (the retailers with readings there in the last 30 days and the newest day: rows we already hold) and, when a retailer is chosen, FRESH eligibility (whether a new on-demand collection could run there). meta.resolution says whether the words pointed at one place, were ambiguous, matched nothing, or the market has no location directory (meta.supported false). Rows carry warnings (a city name in several states, an area name in several cities, a pin that spans several areas, an estimated centre). Nothing here picks a pin or starts any paid work. Free: no credits are charged.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Words",
              "examples": [
                "koramangala"
              ],
              "minLength": 1,
              "maxLength": 100
            },
            "description": "A pin code, its first 1 to 5 digits, or a city, area or district name."
          },
          {
            "name": "market",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Market",
              "examples": [
                "IN"
              ],
              "pattern": "^[A-Z]{2}$"
            },
            "description": "The market (Core Retailer.market). Default: the chosen retailer’s market, else IN. A market with no location directory answers empty with supported false."
          },
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The retailer chosen (a key from /v1/data/retailers). Its market decides which location directory applies. It adds kept and fresh information per place; see coverage for whether it also filters."
          },
          {
            "name": "coverage",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Coverage",
              "examples": [
                "any"
              ],
              "pattern": "^(any|kept|fresh)$"
            },
            "description": "any (default): every matching place, kept first, then fresh-eligible, then the rest. kept: only places with kept data for the retailer. fresh: only places a fresh run could serve (needs retailer)."
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "City",
              "examples": [
                "Bengaluru"
              ],
              "minLength": 1,
              "maxLength": 100
            },
            "description": "Only pins of this city (case-insensitive exact match, as listed by /v1/data/locations/cities)."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "State",
              "examples": [
                "Karnataka"
              ],
              "minLength": 1,
              "maxLength": 100
            },
            "description": "Only this state (case-insensitive exact match). Use it when a city or area name exists in several states."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "50"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many rows, 1 to 200. Default 50."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMTk3MC0wMS0wMVQwMDowMDowMC4wMDBaIiwiaSI6IjU2MDAzNCIsImYiOiJhYmMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/locations/cities": {
      "get": {
        "operationId": "listLocationCities",
        "summary": "List cities with their pin counts and coverage",
        "description": "Cities by the start of their name, with a stable location id, how many pin codes each has, KEPT coverage (pins with readings in the last 30 days, for the chosen retailer when one is chosen) and, with a retailer, FRESH eligibility (how many of its pins a new collection could serve). A city name that exists in several states appears once per state with a warning. To see a city pins and what a paid read of it needs, call GET /v1/data/locations/filter with its locationId. Free: no credits are charged.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationCitiesPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Words",
              "examples": [
                "beng"
              ],
              "minLength": 1,
              "maxLength": 100
            },
            "description": "The start of a city name."
          },
          {
            "name": "market",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Market",
              "examples": [
                "IN"
              ],
              "pattern": "^[A-Z]{2}$"
            },
            "description": "The market (Core Retailer.market). Default: the chosen retailer’s market, else IN. A market with no location directory answers empty with supported false."
          },
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The retailer chosen (a key from /v1/data/retailers). Its market decides which location directory applies. It adds kept and fresh information per place; see coverage for whether it also filters."
          },
          {
            "name": "coverage",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Coverage",
              "examples": [
                "any"
              ],
              "pattern": "^(any|kept|fresh)$"
            },
            "description": "any (default): every matching place, kept first, then fresh-eligible, then the rest. kept: only places with kept data for the retailer. fresh: only places a fresh run could serve (needs retailer)."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "State",
              "examples": [
                "Karnataka"
              ],
              "minLength": 1,
              "maxLength": 100
            },
            "description": "Only this state (case-insensitive exact match). Use it when a city or area name exists in several states."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "50"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many rows, 1 to 200. Default 50."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMTk3MC0wMS0wMVQwMDowMDowMC4wMDBaIiwiaSI6IjU2MDAzNCIsImYiOiJhYmMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/locations/filter": {
      "get": {
        "operationId": "getLocationFilter",
        "summary": "Resolve a location id to its pin codes and what a paid read needs",
        "description": "Resolves a stable Core location id (a pin, a city, an area or a dark store) to its complete, explicit list of pin codes, and says what is kept there (per retailer), where a fresh collection could run (per retailer, for the chosen one or every retailer of the market), and exactly what a paid read of the location needs: send the id as `location` and the number of pins as `confirmPins` to GET /v1/data/observations or GET /v1/data/listings/search; the read is charged by the records delivered at the published rate, not by the number of pins, and pages over all the pins together. A place with more pins than maxPincodes is not readable and is never cut. A dark store resolves to the pin codes it serves (kind store): readings are kept per pin code and never attributed to the store itself. Free, and it starts nothing.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationFilterAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "location",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Location id",
              "examples": [
                "IN:city:karnataka:bengaluru"
              ],
              "pattern": "^[A-Z]{2}:(pin:[1-9][0-9]{5}|city:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}|area:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}:[a-z0-9]{1,120}|store:[a-z0-9_]{2,40}:[A-Za-z0-9_-]{1,64})$"
            },
            "description": "A locationId, areaLocationId or cityLocationId, or a store locationId from /v1/data/locations/stores."
          },
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The retailer chosen (a key from /v1/data/retailers). Its market decides which location directory applies. It adds kept and fresh information per place; see coverage for whether it also filters."
          }
        ]
      }
    },
    "/v1/data/locations/pincode": {
      "get": {
        "operationId": "getPincode",
        "summary": "Look up one pin code",
        "description": "The free pin code lookup (catalogue entry tool_pincode). For one six-digit pin code: its city, district and state, its centre point and whether it is urban, every post office India Post lists for it (name, type, delivery, taluk, division, region, circle), and every retailer Rewalto has kept readings for there, with the first and newest IST day, the days read and the readings kept. A pin India Post does not list answers 404 not_found. Free: no credits are charged.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Pin code lookup",
                  "description": "One pin code. Free: nothing is charged.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Pin code",
                      "description": "One pin code: where it is, the post offices that carry it, and the retailers Rewalto reads there.",
                      "additionalProperties": false,
                      "required": [
                        "pincode",
                        "locationId",
                        "cityLocationId",
                        "city",
                        "district",
                        "state",
                        "urban",
                        "lat",
                        "lng",
                        "postOffices",
                        "retailers"
                      ],
                      "properties": {
                        "pincode": {
                          "type": "string",
                          "title": "Pin code",
                          "description": "The six-digit pin code.",
                          "examples": [
                            "560034"
                          ],
                          "pattern": "^[1-9][0-9]{5}$"
                        },
                        "locationId": {
                          "type": "string",
                          "title": "Location id",
                          "description": "The stable filter id of this pin.",
                          "examples": [
                            "IN:pin:560034"
                          ],
                          "pattern": "^[A-Z]{2}:(pin:[1-9][0-9]{5}|city:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}|area:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}:[a-z0-9]{1,120}|store:[a-z0-9_]{2,40}:[A-Za-z0-9_-]{1,64})$"
                        },
                        "cityLocationId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "City location id",
                          "description": "The filter id of the pin city; null when the directory has no city for the pin.",
                          "examples": [
                            "IN:city:karnataka:bengaluru"
                          ]
                        },
                        "city": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "City",
                          "description": "The city, as customers say it.",
                          "examples": [
                            "Bengaluru"
                          ]
                        },
                        "district": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "District",
                          "description": "The India Post district.",
                          "examples": [
                            "BENGALURU URBAN"
                          ]
                        },
                        "state": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "State",
                          "description": "The state.",
                          "examples": [
                            "KARNATAKA"
                          ]
                        },
                        "urban": {
                          "type": [
                            "null",
                            "boolean"
                          ],
                          "title": "Urban",
                          "description": "True when the pin is urban by the directory rule; null when not decided.",
                          "examples": [
                            true
                          ]
                        },
                        "lat": {
                          "type": [
                            "null",
                            "number"
                          ],
                          "title": "Latitude",
                          "description": "Centre latitude of the pin.",
                          "examples": [
                            12.9352
                          ]
                        },
                        "lng": {
                          "type": [
                            "null",
                            "number"
                          ],
                          "title": "Longitude",
                          "description": "Centre longitude of the pin.",
                          "examples": [
                            77.6245
                          ]
                        },
                        "postOffices": {
                          "type": "array",
                          "title": "Post offices",
                          "description": "Every office India Post lists for this pin, by name.",
                          "items": {
                            "type": "object",
                            "title": "Post office",
                            "description": "One India Post office that carries this pin code.",
                            "additionalProperties": false,
                            "required": [
                              "name",
                              "type",
                              "delivery",
                              "taluk",
                              "division",
                              "region",
                              "circle"
                            ],
                            "properties": {
                              "name": {
                                "type": "string",
                                "title": "Name",
                                "description": "The office name, as India Post writes it.",
                                "examples": [
                                  "Koramangala S.O"
                                ]
                              },
                              "type": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Type",
                                "description": "HO (head office), SO (sub office) or BO (branch office).",
                                "examples": [
                                  "SO"
                                ]
                              },
                              "delivery": {
                                "type": "boolean",
                                "title": "Delivery",
                                "description": "True when the office delivers mail.",
                                "examples": [
                                  true
                                ]
                              },
                              "taluk": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Taluk",
                                "description": "The taluk (sub-district).",
                                "examples": [
                                  "Bangalore South"
                                ]
                              },
                              "division": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Division",
                                "description": "The postal division.",
                                "examples": [
                                  "Bengaluru South Division"
                                ]
                              },
                              "region": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Region",
                                "description": "The postal region.",
                                "examples": [
                                  "Bengaluru HQ Region"
                                ]
                              },
                              "circle": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Circle",
                                "description": "The postal circle.",
                                "examples": [
                                  "Karnataka Circle"
                                ]
                              }
                            }
                          }
                        },
                        "retailers": {
                          "type": "array",
                          "title": "Retailers read here",
                          "description": "Every retailer Rewalto has kept readings for at this pin, by retailer key; empty when none. The readings themselves are paid reads (observations, listings).",
                          "items": {
                            "type": "object",
                            "title": "Retailer read here",
                            "description": "One retailer Rewalto has collected at this pin code, from the daily coverage summary.",
                            "additionalProperties": false,
                            "required": [
                              "retailer",
                              "firstDay",
                              "lastDay",
                              "days",
                              "readings"
                            ],
                            "properties": {
                              "retailer": {
                                "type": "string",
                                "title": "Retailer",
                                "description": "The retailer key (see /v1/data/retailers).",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "firstDay": {
                                "type": "string",
                                "title": "First day",
                                "description": "The first IST day with a reading here.",
                                "examples": [
                                  "2026-08-25"
                                ]
                              },
                              "lastDay": {
                                "type": "string",
                                "title": "Last day",
                                "description": "The newest IST day with a reading here.",
                                "examples": [
                                  "2026-10-22"
                                ]
                              },
                              "days": {
                                "type": "integer",
                                "title": "Days",
                                "description": "IST days with at least one reading here.",
                                "examples": [
                                  52
                                ]
                              },
                              "readings": {
                                "type": "integer",
                                "title": "Readings",
                                "description": "Readings kept here across those days.",
                                "examples": [
                                  184220
                                ]
                              }
                            }
                          }
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from, and that it is free.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOfDay",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "reference"
                          ],
                          "title": "Kind",
                          "description": "reference: India Post pin directory joined with the daily coverage summary.",
                          "examples": [
                            "reference"
                          ]
                        },
                        "asOfDay": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Coverage as of",
                          "description": "The newest IST day in the coverage summary; null when it is empty.",
                          "examples": [
                            "2026-10-20"
                          ]
                        },
                        "credits": {
                          "type": "object",
                          "title": "Credits",
                          "description": "Always free.",
                          "additionalProperties": false,
                          "required": [
                            "charged",
                            "units",
                            "freeReread",
                            "rate"
                          ],
                          "properties": {
                            "charged": {
                              "type": "integer",
                              "title": "Charged",
                              "description": "Credits charged: always 0.",
                              "examples": [
                                0
                              ]
                            },
                            "units": {
                              "type": "integer",
                              "title": "Units",
                              "description": "Always 0.",
                              "examples": [
                                0
                              ]
                            },
                            "freeReread": {
                              "type": "boolean",
                              "title": "Free re-read",
                              "description": "Always false.",
                              "examples": [
                                false
                              ]
                            },
                            "rate": {
                              "type": "null",
                              "title": "Rate",
                              "description": "Always null: no rate applies."
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pincode",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^[1-9][0-9]{5}$"
            },
            "description": "A six-digit Indian pin code."
          }
        ]
      }
    },
    "/v1/data/locations/stores": {
      "get": {
        "operationId": "listLocationStores",
        "summary": "List a retailer’s dark stores in a city",
        "description": "One quick-commerce retailer's dark stores in a city, as Rewalto's sweeps found them: a stable location id (IN:store:<retailer>:<store id>), a customer-facing label, city and state, open or closed, first and last seen, the pin codes each serves, and KEPT coverage at those pins (last 30 days). Stores whose catchment holds no listed pin code are left out. Ordered by store id; keyset pages. Send a store's locationId as location (with confirmPins = its pin count when it serves more than one) to GET /v1/data/locations/filter and to the reads that take a location (countSeries, getSeries, observations, listings search, discover). A store id (IN:store:<retailer>:<store id>) means the pin codes that dark store serves (its catchment as the sweeps saw it). Readings are kept per pin code, not per store, so it reads every kept reading at those pin codes, whichever store served them; no reading is attributed to the store itself. Free: no credits are charged.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocationStoresPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The quick-commerce retailer (a key from /v1/data/retailers), for example blinkit, zepto or instamart."
          },
          {
            "name": "city",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "City",
              "examples": [
                "Mumbai"
              ],
              "minLength": 1,
              "maxLength": 100
            },
            "description": "The city (case-insensitive exact match on the city the sweeps covered)."
          },
          {
            "name": "state",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "State",
              "examples": [
                "Maharashtra"
              ],
              "minLength": 1,
              "maxLength": 100
            },
            "description": "Only stores whose pin codes are in this state (case-insensitive exact match)."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Words",
              "examples": [
                "andheri"
              ],
              "minLength": 1,
              "maxLength": 100
            },
            "description": "The start of the store id, the store name, an area (post office) name of a pin it serves, or the first digits of a pin it serves."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "50"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many rows, 1 to 200. Default 50."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMTk3MC0wMS0wMVQwMDowMDowMC4wMDBaIiwiaSI6IjU2MDAzNCIsImYiOiJhYmMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/mentions": {
      "get": {
        "operationId": "listBrandMentions",
        "summary": "List YouTube brand mentions per day",
        "description": "For each brand and IST day: how many public YouTube videos published in India that day mention the brand, with their summed public views, likes and comments when last read (atLeast is true when the page of 50 was full). Newest day first, optionally one brand and a day range. Catalogue entry lib_youtube_mentions; one record is one brand-day. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BrandMentionsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Mamaearth"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand (exact match, case-sensitive)."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/observations": {
      "get": {
        "operationId": "listObservations",
        "summary": "List price and availability history",
        "description": "Price and availability history for listings, newest first. Charged 1 credit per 10 records delivered, rounded up; re-reading the same records within 7 days is free, and an empty page costs nothing. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ObservationsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110092"
              ],
              "pattern": "^(national|[0-9]{6})$"
            },
            "description": "Only readings for this six-digit pin code, or national for readings that are not pin-scoped."
          },
          {
            "name": "location",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Location",
              "examples": [
                "IN:city:karnataka:bengaluru"
              ],
              "pattern": "^[A-Z]{2}:(pin:[1-9][0-9]{5}|city:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}|area:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}:[a-z0-9]{1,120}|store:[a-z0-9_]{2,40}:[A-Za-z0-9_-]{1,64})$"
            },
            "description": "A Core location id from the free lookup (GET /v1/data/locations, /cities or /stores): a pin, a city, an area or a dark store. It resolves to an explicit list of pin codes (see GET /v1/data/locations/filter). Never combine with pincode. More than one pin needs confirmPins. A store id (IN:store:<retailer>:<store id>) means the pin codes that dark store serves (its catchment as the sweeps saw it). Readings are kept per pin code, not per store, so it reads every kept reading at those pin codes, whichever store served them; no reading is attributed to the store itself."
          },
          {
            "name": "confirmPins",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Confirm pins",
              "examples": [
                "112"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "Your consent to a multi-pin read: the number of pins the location resolves to, as GET /v1/data/locations/filter showed it. A different number is refused with the current count, so a place is never silently broadened."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Aashirvaad"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only records with exactly this brand text, as the retailer wrote it (exact match, case-sensitive)."
          },
          {
            "name": "productId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Product",
              "examples": [
                "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
              ],
              "format": "uuid"
            },
            "description": "Only records matched to this Rewalto product id."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "prd-88213"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this retailer product id (use together with retailer)."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "title": "From",
              "examples": [
                "2026-10-01T00:00:00Z"
              ]
            },
            "description": "Only readings at or after this time. Default: 30 days before now."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "title": "To",
              "examples": [
                "2026-10-15T00:00:00Z"
              ]
            },
            "description": "Only readings before this time. Default: now."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/oos-rate": {
      "get": {
        "operationId": "listOosRate",
        "summary": "List out-of-stock rate by brand and city",
        "description": "For one retailer: for each brand and city on an IST day, the readings that stated stock and how many of them were out of stock (oosBp is null when none stated stock; Flipkart states none). The city is the pin code’s city in the India Post directory, or national. Rolled up daily from Rewalto’s own readings from 25 Aug 2026. Newest day first, optionally one city, one brand and a day range. Catalogue entry lib_oos_rate; one record is one brand in one city on one day. Charged per record delivered at the history rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OosRatePage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "city",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "City",
              "examples": [
                "Bengaluru"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this city, as the India Post directory names it, or national."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Amul"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand (exact match, case-sensitive)."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/price-per-unit": {
      "get": {
        "operationId": "listPricePerUnit",
        "summary": "List price per unit per product and pin code",
        "description": "For one retailer: each listing’s price per gram, millilitre or piece on each IST day at each pin code (or national), per pack, from that day’s priced readings: lowest, highest and mean in paise per unit, the pack it was worked out from, and the selling prices. A pack that could not be read is kept with an empty price per unit, never 0. Newest day first, optionally one product (retailerSku), one pin code and a day range. Catalogue entry wf_price_per_unit; one record is one data point (a listing, pin, day and pack). Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Price per unit page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "PricePerUnitCell",
                        "description": "One listing at one pin code (or national) on one IST day and one pack: the price per gram, millilitre or piece from that day’s priced readings, so pack sizes compare fairly. A pack that could not be read is kept with an empty price per unit, never 0.",
                        "additionalProperties": false,
                        "required": [
                          "retailer",
                          "retailerSku",
                          "pincode",
                          "day",
                          "packSource",
                          "packUnit",
                          "packValue",
                          "packCount",
                          "packTotal",
                          "pricePerUnitMin",
                          "pricePerUnitMax",
                          "pricePerUnitAvg",
                          "priceMinorMin",
                          "priceMinorMax",
                          "readings",
                          "pricedReadings",
                          "lastObservedAt"
                        ],
                        "properties": {
                          "retailer": {
                            "type": "string",
                            "title": "Retailer",
                            "description": "The retailer.",
                            "examples": [
                              "blinkit"
                            ]
                          },
                          "retailerSku": {
                            "type": "string",
                            "title": "Retailer SKU",
                            "description": "The retailer's own product id.",
                            "examples": [
                              "483921"
                            ]
                          },
                          "pincode": {
                            "type": "string",
                            "title": "Pin code",
                            "description": "The pin code, or national.",
                            "examples": [
                              "560034"
                            ]
                          },
                          "day": {
                            "type": "string",
                            "format": "date",
                            "title": "Day",
                            "description": "The IST day.",
                            "examples": [
                              "2026-10-21"
                            ]
                          },
                          "packSource": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "typed",
                              "parsed",
                              null
                            ],
                            "title": "Pack source",
                            "description": "typed: the retailer’s own pack fields; parsed: read from the printed pack text; null: the pack could not be read.",
                            "examples": [
                              "typed"
                            ]
                          },
                          "packUnit": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "g",
                              "ml",
                              "pc",
                              null
                            ],
                            "title": "Pack unit",
                            "description": "g, ml or pc (pieces); null when the pack could not be read.",
                            "examples": [
                              "g"
                            ]
                          },
                          "packValue": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Pack value",
                            "description": "The size of one item in the pack, in packUnit.",
                            "examples": [
                              500
                            ]
                          },
                          "packCount": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Pack count",
                            "description": "Items in the pack (2 for a pack of 2).",
                            "examples": [
                              1
                            ]
                          },
                          "packTotal": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Pack total",
                            "description": "packValue times packCount.",
                            "examples": [
                              500
                            ]
                          },
                          "pricePerUnitMin": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Price per unit, lowest",
                            "description": "Paise per packUnit, the lowest that day (six decimals).",
                            "examples": [
                              0.198
                            ]
                          },
                          "pricePerUnitMax": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Price per unit, highest",
                            "description": "Paise per packUnit, the highest that day.",
                            "examples": [
                              0.21
                            ]
                          },
                          "pricePerUnitAvg": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Price per unit, average",
                            "description": "Paise per packUnit, the mean that day.",
                            "examples": [
                              0.204
                            ]
                          },
                          "priceMinorMin": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Price, lowest",
                            "description": "The lowest selling price that day, in paise.",
                            "examples": [
                              9900
                            ]
                          },
                          "priceMinorMax": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Price, highest",
                            "description": "The highest selling price that day, in paise.",
                            "examples": [
                              10500
                            ]
                          },
                          "readings": {
                            "type": "integer",
                            "title": "Readings",
                            "description": "Readings of the listing that day at the pin.",
                            "examples": [
                              4
                            ],
                            "minimum": 1
                          },
                          "pricedReadings": {
                            "type": "integer",
                            "title": "Priced readings",
                            "description": "Of those, the readings that carried a price.",
                            "examples": [
                              4
                            ],
                            "minimum": 0
                          },
                          "lastObservedAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Last observed",
                            "description": "The newest reading of the day.",
                            "examples": [
                              "2026-10-21T15:40:00Z"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "prd-88213"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this retailer product id (use together with retailer)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^(national|[0-9]{6})$"
            },
            "description": "Only this six-digit pin code, or national."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/products/listings": {
      "get": {
        "operationId": "listProductListings",
        "summary": "List one product’s listings across retailers",
        "description": "One product (give product, or retailer with retailerSku to start from one listing): every retailer listing Rewalto’s matcher matched to it, with each listing’s newest reading per pin code (or national) in a window of IST days: price and MRP in paise, in stock, and the observation it came from. Matches are the kept matcher results (score 0.92 or above, decided up to 16 Oct 2026). Ordered by retailer, listing and pin code. Catalogue entry ds_product_match; one record is one listing at one pin code. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Product listings page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "ProductListing",
                        "description": "One retailer listing matched to the product, at one pin code (or national), with the newest reading in the window.",
                        "additionalProperties": false,
                        "required": [
                          "productId",
                          "productTitle",
                          "retailer",
                          "retailerSku",
                          "title",
                          "brand",
                          "packSize",
                          "url",
                          "pincode",
                          "priceMinor",
                          "mrpMinor",
                          "inStock",
                          "observationId",
                          "observedAt",
                          "match"
                        ],
                        "properties": {
                          "productId": {
                            "type": "string",
                            "title": "Product",
                            "description": "The Rewalto product id the listing is matched to; one product groups the same item across retailers.",
                            "examples": [
                              "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
                            ]
                          },
                          "productTitle": {
                            "type": "string",
                            "title": "Product title",
                            "description": "The product’s normalised title (lower case), shared by every listing matched to it.",
                            "examples": [
                              "neutrogena hydro boost hyaluronic acid water gel"
                            ]
                          },
                          "retailer": {
                            "type": "string",
                            "title": "Retailer",
                            "description": "The retailer.",
                            "examples": [
                              "nykaa"
                            ]
                          },
                          "retailerSku": {
                            "type": "string",
                            "title": "Retailer SKU",
                            "description": "The retailer's own product id.",
                            "examples": [
                              "875156"
                            ]
                          },
                          "title": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Title",
                            "description": "The listing title as the retailer shows it.",
                            "examples": [
                              "Neutrogena Hydro Boost Water Gel"
                            ]
                          },
                          "brand": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Brand",
                            "description": "The brand as the retailer wrote it.",
                            "examples": [
                              "Neutrogena"
                            ]
                          },
                          "packSize": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Pack size",
                            "description": "The pack size as shown.",
                            "examples": [
                              "50 g"
                            ]
                          },
                          "url": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Link",
                            "description": "The listing page.",
                            "examples": [
                              "https://www.nykaa.com/p/875156"
                            ]
                          },
                          "pincode": {
                            "type": "string",
                            "title": "Pin code",
                            "description": "The pin code the reading is for, or national.",
                            "examples": [
                              "110001"
                            ]
                          },
                          "priceMinor": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Price",
                            "description": "Selling price in paise; null when it could not be read.",
                            "examples": [
                              104700
                            ]
                          },
                          "mrpMinor": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "MRP",
                            "description": "MRP in paise; null when none was shown.",
                            "examples": [
                              119000
                            ]
                          },
                          "inStock": {
                            "type": [
                              "null",
                              "boolean"
                            ],
                            "title": "In stock",
                            "description": "In stock as shown; null when the page had no signal.",
                            "examples": [
                              true
                            ]
                          },
                          "observationId": {
                            "type": "string",
                            "title": "Observation",
                            "description": "The kept reading the values come from (its source, fetch time, SHA-256 and the exact text read).",
                            "examples": [
                              "48210377"
                            ]
                          },
                          "observedAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Observed at",
                            "description": "When it was read.",
                            "examples": [
                              "2026-10-21T20:02:04Z"
                            ]
                          },
                          "match": {
                            "type": "object",
                            "title": "Match",
                            "description": "Why the listing belongs to the product.",
                            "additionalProperties": false,
                            "required": [
                              "basis",
                              "score",
                              "confidence"
                            ],
                            "properties": {
                              "basis": {
                                "type": "string",
                                "enum": [
                                  "kept",
                                  "model"
                                ],
                                "title": "Basis",
                                "description": "kept: grouped under the product by the old matcher (the listing it was made from, or a match scored 0.92 or above, to 16 Oct 2026); model: a candidate pair the old matcher left undecided, judged the same product by a model (confidence 0.85 or above).",
                                "examples": [
                                  "kept"
                                ]
                              },
                              "score": {
                                "type": [
                                  "null",
                                  "number"
                                ],
                                "title": "Score",
                                "description": "The old matcher’s score for the pair, 0 to 1; null for the listing the product was made from.",
                                "examples": [
                                  0.97
                                ]
                              },
                              "confidence": {
                                "type": [
                                  "null",
                                  "number"
                                ],
                                "title": "Model confidence",
                                "description": "The model’s confidence, 0 to 1 (model only).",
                                "examples": [
                                  null
                                ]
                              }
                            }
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "product",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Product",
              "examples": [
                "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
              ],
              "format": "uuid"
            },
            "description": "The Rewalto product id. Give this, or retailer with retailerSku to start from one listing."
          },
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "nykaa"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "With retailerSku: the product that listing is matched to (a key from /v1/data/retailers)."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "875156"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "With retailer: the product that listing is matched to."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110001"
              ],
              "pattern": "^(national|[0-9]{6})$"
            },
            "description": "Only this six-digit pin code, or national."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/products/price-parity": {
      "get": {
        "operationId": "listPriceParity",
        "summary": "List one product’s price parity per day",
        "description": "One product (give product, or retailer with retailerSku): for each IST day it was priced, every matched listing’s newest priced reading per pin code, the lowest and highest of them, and the gap in paise and basis points of the lowest. Newest day first, optionally one pin code. Catalogue entry sig_price_parity; one record is one product-day. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Price parity page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "PriceParityDay",
                        "description": "One product on one IST day: the lowest and highest price across every retailer and pin code that priced it, the gap between them, and each price.",
                        "additionalProperties": false,
                        "required": [
                          "productId",
                          "day",
                          "retailers",
                          "pincodes",
                          "lowestPriceMinor",
                          "highestPriceMinor",
                          "gapMinor",
                          "gapBps",
                          "lowest",
                          "highest",
                          "prices"
                        ],
                        "properties": {
                          "productId": {
                            "type": "string",
                            "title": "Product",
                            "description": "The Rewalto product id the listing is matched to; one product groups the same item across retailers.",
                            "examples": [
                              "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
                            ]
                          },
                          "day": {
                            "type": "string",
                            "format": "date",
                            "title": "Day",
                            "description": "The IST day.",
                            "examples": [
                              "2026-10-21"
                            ]
                          },
                          "retailers": {
                            "type": "integer",
                            "title": "Retailers",
                            "description": "How many retailers priced it that day.",
                            "examples": [
                              2
                            ]
                          },
                          "pincodes": {
                            "type": "integer",
                            "title": "Pin codes",
                            "description": "How many pin codes (national counts as one) it was priced at.",
                            "examples": [
                              2
                            ]
                          },
                          "lowestPriceMinor": {
                            "type": "integer",
                            "title": "Lowest price",
                            "description": "The lowest price that day, in paise.",
                            "examples": [
                              71000
                            ]
                          },
                          "highestPriceMinor": {
                            "type": "integer",
                            "title": "Highest price",
                            "description": "The highest price that day, in paise.",
                            "examples": [
                              104700
                            ]
                          },
                          "gapMinor": {
                            "type": "integer",
                            "title": "Gap",
                            "description": "Highest minus lowest, in paise.",
                            "examples": [
                              33700
                            ]
                          },
                          "gapBps": {
                            "type": "integer",
                            "title": "Gap (basis points)",
                            "description": "The gap as a share of the lowest price, in basis points.",
                            "examples": [
                              4746
                            ]
                          },
                          "lowest": {
                            "type": "object",
                            "title": "PricePoint",
                            "description": "One listing’s price at one pin code on the day, from that day’s newest priced reading.",
                            "additionalProperties": false,
                            "required": [
                              "retailer",
                              "retailerSku",
                              "pincode",
                              "priceMinor",
                              "mrpMinor",
                              "observedAt"
                            ],
                            "properties": {
                              "retailer": {
                                "type": "string",
                                "title": "Retailer",
                                "description": "The retailer.",
                                "examples": [
                                  "flipkart"
                                ]
                              },
                              "retailerSku": {
                                "type": "string",
                                "title": "Retailer SKU",
                                "description": "The retailer's own product id.",
                                "examples": [
                                  "MSCFAHKRHHHEVQHM"
                                ]
                              },
                              "pincode": {
                                "type": "string",
                                "title": "Pin code",
                                "description": "The pin code, or national.",
                                "examples": [
                                  "national"
                                ]
                              },
                              "priceMinor": {
                                "type": "integer",
                                "title": "Price",
                                "description": "Selling price in paise.",
                                "examples": [
                                  71000
                                ]
                              },
                              "mrpMinor": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "title": "MRP",
                                "description": "MRP in paise; null when none was shown.",
                                "examples": [
                                  119000
                                ]
                              },
                              "observedAt": {
                                "type": "string",
                                "format": "date-time",
                                "title": "Observed at",
                                "description": "When it was read.",
                                "examples": [
                                  "2026-10-21T08:00:00Z"
                                ]
                              }
                            }
                          },
                          "highest": {
                            "type": "object",
                            "title": "PricePoint",
                            "description": "One listing’s price at one pin code on the day, from that day’s newest priced reading.",
                            "additionalProperties": false,
                            "required": [
                              "retailer",
                              "retailerSku",
                              "pincode",
                              "priceMinor",
                              "mrpMinor",
                              "observedAt"
                            ],
                            "properties": {
                              "retailer": {
                                "type": "string",
                                "title": "Retailer",
                                "description": "The retailer.",
                                "examples": [
                                  "flipkart"
                                ]
                              },
                              "retailerSku": {
                                "type": "string",
                                "title": "Retailer SKU",
                                "description": "The retailer's own product id.",
                                "examples": [
                                  "MSCFAHKRHHHEVQHM"
                                ]
                              },
                              "pincode": {
                                "type": "string",
                                "title": "Pin code",
                                "description": "The pin code, or national.",
                                "examples": [
                                  "national"
                                ]
                              },
                              "priceMinor": {
                                "type": "integer",
                                "title": "Price",
                                "description": "Selling price in paise.",
                                "examples": [
                                  71000
                                ]
                              },
                              "mrpMinor": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "title": "MRP",
                                "description": "MRP in paise; null when none was shown.",
                                "examples": [
                                  119000
                                ]
                              },
                              "observedAt": {
                                "type": "string",
                                "format": "date-time",
                                "title": "Observed at",
                                "description": "When it was read.",
                                "examples": [
                                  "2026-10-21T08:00:00Z"
                                ]
                              }
                            }
                          },
                          "prices": {
                            "type": "array",
                            "title": "Prices",
                            "description": "Every price that day, lowest first.",
                            "items": {
                              "type": "object",
                              "title": "PricePoint",
                              "description": "One listing’s price at one pin code on the day, from that day’s newest priced reading.",
                              "additionalProperties": false,
                              "required": [
                                "retailer",
                                "retailerSku",
                                "pincode",
                                "priceMinor",
                                "mrpMinor",
                                "observedAt"
                              ],
                              "properties": {
                                "retailer": {
                                  "type": "string",
                                  "title": "Retailer",
                                  "description": "The retailer.",
                                  "examples": [
                                    "flipkart"
                                  ]
                                },
                                "retailerSku": {
                                  "type": "string",
                                  "title": "Retailer SKU",
                                  "description": "The retailer's own product id.",
                                  "examples": [
                                    "MSCFAHKRHHHEVQHM"
                                  ]
                                },
                                "pincode": {
                                  "type": "string",
                                  "title": "Pin code",
                                  "description": "The pin code, or national.",
                                  "examples": [
                                    "national"
                                  ]
                                },
                                "priceMinor": {
                                  "type": "integer",
                                  "title": "Price",
                                  "description": "Selling price in paise.",
                                  "examples": [
                                    71000
                                  ]
                                },
                                "mrpMinor": {
                                  "type": [
                                    "null",
                                    "integer"
                                  ],
                                  "title": "MRP",
                                  "description": "MRP in paise; null when none was shown.",
                                  "examples": [
                                    119000
                                  ]
                                },
                                "observedAt": {
                                  "type": "string",
                                  "format": "date-time",
                                  "title": "Observed at",
                                  "description": "When it was read.",
                                  "examples": [
                                    "2026-10-21T08:00:00Z"
                                  ]
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "product",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Product",
              "examples": [
                "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
              ],
              "format": "uuid"
            },
            "description": "The Rewalto product id. Give this, or retailer with retailerSku to start from one listing."
          },
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "nykaa"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "With retailerSku: the product that listing is matched to (a key from /v1/data/retailers)."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "875156"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "With retailer: the product that listing is matched to."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110001"
              ],
              "pattern": "^(national|[0-9]{6})$"
            },
            "description": "Only prices at this six-digit pin code, or national."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/promos/emails": {
      "get": {
        "operationId": "listPromoEmails",
        "summary": "List brand promo emails",
        "description": "Each promotion a brand emailed to subscribers, as recorded by Rewalto: the send day, the brand (matched to a canonical brand where known) and the brand as written, the offer, the sale dates and discount code if stated, and the brand’s page it links to; never the email itself. Newest send day first, optionally one brand and a day range. Catalogue entry lib_promo_emails; one record is one promo email. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PromoEmailsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "The Derma Co"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this canonical brand (exact match), as in the brand field."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/promos/storefront": {
      "get": {
        "operationId": "listStorefrontPromos",
        "summary": "List the D2C promo calendar",
        "description": "For each watched brand store and IST day: product variants seen and on sale, the median and deepest discount in basis points, and how many variants went on sale, ended a sale, were cut in price or discounted deeper since the last read. Newest day first, optionally one brand, one store and a day range. Catalogue entry lib_d2c_promo_calendar; one record is one store-day. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StorefrontPromosPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Mamaearth"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand (exact match, case-sensitive)."
          },
          {
            "name": "domain",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Store",
              "examples": [
                "mamaearth.in"
              ],
              "minLength": 3,
              "maxLength": 200
            },
            "description": "Only this watched store, e.g. mamaearth.in."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/ratings": {
      "get": {
        "operationId": "listRatingChanges",
        "summary": "List rating changes per product and pin code",
        "description": "For one retailer: each listing’s rating, rating count and review count on every IST day one of them changed, per pin code (or national), from that day’s newest reading, with the observation it came from. Newest day first, optionally one product (retailerSku), one pin code and a day range. Catalogue entry rr_rating_series; one record is one rating change. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RatingChangesPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "prd-88213"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this retailer product id (use together with retailer)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "national"
              ],
              "pattern": "^(national|[0-9]{6})$"
            },
            "description": "Only this six-digit pin code, or national."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/regulatory-notices": {
      "get": {
        "operationId": "listRegulatoryNotices",
        "summary": "List CDSCO public notices and FSSAI notifications",
        "description": "Each public notice India’s drug regulator (CDSCO public notices) and food regulator (FSSAI notifications) lists on its own site, read weekly: the title, the release day the regulator states, the link to its document and its size, and for FSSAI its category (draft, gazette, notice, WTO SPS or TBT, ordinary), its comments link and further documents. The documents themselves are not kept; the links open them on the regulator’s site. Newest release day first, optionally one regulator, a day range and words in the title. Catalogue entries rcp_cdsco_notices and rcp_fssai_notifications; one record is one notice. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RegulatoryNoticesPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "authority",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Regulator",
              "examples": [
                "fssai"
              ],
              "pattern": "^(cdsco|fssai)$"
            },
            "description": "Only this regulator: cdsco or fssai."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only notices published on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only notices published on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Title words",
              "examples": [
                "medical device"
              ],
              "minLength": 2,
              "maxLength": 200
            },
            "description": "Only notices whose title contains this text (any case)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/retailers": {
      "get": {
        "operationId": "listRetailers",
        "summary": "List the tracked retailers",
        "description": "The retailers Rewalto tracks, one page at a time. Free: no credits are charged.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RetailersPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/data/samples": {
      "get": {
        "operationId": "listDatasetSamples",
        "summary": "Free real samples of each dataset",
        "description": "Up to 5 real rows Rewalto keeps for each dataset sold through /v1/data, each exactly a record of the paid read named, and every one at least 7 days old (D-1830 D-e). Never made up (illustrative is always false): a dataset with nothing that old shows an empty list. Each entry names its paid operation, rate-card unit, published rate and catalogue entry. Public and free: no credential, nothing charged.",
        "tags": [
          "Data"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DatasetSamples"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "dataset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Dataset",
              "examples": [
                "listings"
              ],
              "pattern": "^(listings|price_history|mentions|ratings|banners|storefront_promos|promo_emails|ad_creatives)$"
            },
            "description": "Only this dataset: one of listings, price_history, mentions, ratings, banners, storefront_promos, promo_emails, ad_creatives."
          }
        ]
      }
    },
    "/v1/data/search-ranks": {
      "get": {
        "operationId": "listSearchRanks",
        "summary": "List search rank per product and search term",
        "description": "For one retailer: on each IST day, for each search term and pin code (or national) Rewalto searched, where each listing ranked: its best place in the whole result list (ads included; null where the reply does not state where its page starts, beyond the first page), the first page and slot it was seen at, and how many replies showed it, placed it in places 1 to 10 and marked it sponsored. Observed, never a model. Newest day first, optionally one product (retailerSku), one search term, one pin code and a day range. Catalogue entries qc_rank_history and mp_rank_history; one record is one listing, term, pin and day. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SearchRanksPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "sku-123"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this product (the retailer’s own id)."
          },
          {
            "name": "searchTerm",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Search term",
              "examples": [
                "shampoo"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this search term (exact)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^(national|[0-9]{6})$"
            },
            "description": "Only this six-digit pin code, or national."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/series": {
      "get": {
        "operationId": "getSeries",
        "summary": "Daily price, stock and search-position series",
        "description": "Daily series for one product, brand, retailer or location, for charts: lowest, middle and highest price, stock readings counted as in, out and unknown, and the place in search results where a reading recorded one. Every day of the window is listed; a day with no reading is a gap with no values, never filled or estimated. Charged at the published history rate per day that has readings; gaps cost nothing; re-reading identical data within 7 days is free. Count the scope first, free, with /v1/data/series/count. When the credits cannot cover it: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SeriesAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110092"
              ],
              "pattern": "^([1-9][0-9]{5}|national)$"
            },
            "description": "Only readings for this six-digit pin code, or national."
          },
          {
            "name": "location",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Location",
              "examples": [
                "IN:city:karnataka:bengaluru"
              ],
              "minLength": 1,
              "maxLength": 300
            },
            "description": "A Core location id (/v1/data/locations, /cities or /stores): a pin, city, area or dark store; needs confirmPins like the other reads. A dark store means the pin codes it serves: readings are kept per pin code, so a store reads every reading at those pins, not readings attributed to the store."
          },
          {
            "name": "confirmPins",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Confirm pins",
              "examples": [
                "3"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Confirms the pin codes a location resolves to."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Aashirvaad"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only readings with exactly this brand text (case-sensitive)."
          },
          {
            "name": "productId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Product",
              "examples": [
                "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
              ],
              "format": "uuid"
            },
            "description": "Only readings matched to this Rewalto product id."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "prd-88213"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this retailer product id (use with retailer)."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01T00:00:00Z"
              ],
              "format": "date-time"
            },
            "description": "First moment of the window. Default: 30 days before now."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-15T00:00:00Z"
              ],
              "format": "date-time"
            },
            "description": "End of the window (exclusive). Default: now."
          },
          {
            "name": "groupBy",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Group by",
              "examples": [
                "retailer"
              ],
              "pattern": "^(none|retailer|pincode|brand|product)$"
            },
            "description": "Split the series along one dimension: none, retailer, pincode, brand or product. Default none."
          }
        ]
      }
    },
    "/v1/data/series/count": {
      "get": {
        "operationId": "countSeries",
        "summary": "Count a series before reading it",
        "description": "The days, gap days, points with readings and readings a series read of this scope would deliver. Free: no prices, nothing charged.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SeriesCountAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110092"
              ],
              "pattern": "^([1-9][0-9]{5}|national)$"
            },
            "description": "Only readings for this six-digit pin code, or national."
          },
          {
            "name": "location",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Location",
              "examples": [
                "IN:city:karnataka:bengaluru"
              ],
              "minLength": 1,
              "maxLength": 300
            },
            "description": "A Core location id (/v1/data/locations, /cities or /stores): a pin, city, area or dark store; needs confirmPins like the other reads. A dark store means the pin codes it serves: readings are kept per pin code, so a store reads every reading at those pins, not readings attributed to the store."
          },
          {
            "name": "confirmPins",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Confirm pins",
              "examples": [
                "3"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Confirms the pin codes a location resolves to."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Aashirvaad"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only readings with exactly this brand text (case-sensitive)."
          },
          {
            "name": "productId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Product",
              "examples": [
                "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
              ],
              "format": "uuid"
            },
            "description": "Only readings matched to this Rewalto product id."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "prd-88213"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this retailer product id (use with retailer)."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01T00:00:00Z"
              ],
              "format": "date-time"
            },
            "description": "First moment of the window. Default: 30 days before now."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-15T00:00:00Z"
              ],
              "format": "date-time"
            },
            "description": "End of the window (exclusive). Default: now."
          },
          {
            "name": "groupBy",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Group by",
              "examples": [
                "retailer"
              ],
              "pattern": "^(none|retailer|pincode|brand|product)$"
            },
            "description": "Split the series along one dimension: none, retailer, pincode, brand or product. Default none."
          }
        ]
      }
    },
    "/v1/data/share-of-search": {
      "get": {
        "operationId": "listShareOfSearch",
        "summary": "List share of search per brand and search term",
        "description": "For one retailer: on each IST day, for each search term and pin code (or national) Rewalto searched, each brand’s share of the first ten places, organic and sponsored together: its cards in places 1 to 10 over every brand’s, over all the replies read that day whose page start is known, with how much of it was marked sponsored and how many of its listings reached the top ten. Observed, never a model. Newest day first, optionally one brand, one search term, one pin code and a day range. Catalogue entry lib_share_of_search; one record is one brand, term, pin and day. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareOfSearchPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Mamaearth"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand (exact match, case-sensitive)."
          },
          {
            "name": "searchTerm",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Search term",
              "examples": [
                "shampoo"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this search term (exact)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^(national|[0-9]{6})$"
            },
            "description": "Only this six-digit pin code, or national."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/sponsored-share": {
      "get": {
        "operationId": "listSponsoredShare",
        "summary": "List sponsored share per brand and search term",
        "description": "For one retailer: on each IST day, for each search term and pin code Rewalto searched, the product cards each brand held, how many were marked sponsored (in all and in places 1 to 10), and the brand’s share of all the sponsored cards of that term, pin and day. Ads are counted only from readings that can see the retailer’s ad marker (Blinkit, Zepto, Nykaa and Tata 1mg today); elsewhere the ad counts are 0 and the shares null. Observed counts, never a model. Newest day first, optionally one brand, one search term, one pin code and a day range. Catalogue entry lib_sponsored_share; one record is one brand, term, pin and day. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SponsoredSharePage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "The retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Mamaearth"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand (exact match, case-sensitive)."
          },
          {
            "name": "searchTerm",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Search term",
              "examples": [
                "shampoo"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this search term (exact)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^[0-9]{6}$"
            },
            "description": "Only this six-digit pin code."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/stock-states": {
      "get": {
        "operationId": "listStockStates",
        "summary": "List stock states per product and pin code",
        "description": "For one retailer: each listing’s stock state at the close of each IST day at each pin code (in, low, out, delisted or unknown), whether it was out at that pin only or at every pin read, the stock count where the page shows one, and how many days in a row it has been out or gone. Newest day first, optionally one product (retailerSku), one pin code, one state and a day range. Catalogue entry wf_stock_state; one record is one stock state (a product x retailer x pin x day). Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Stock states page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "StockState",
                        "description": "One listing at one pin code on one IST day: in, low, out, delisted or unknown at the close of the day, with how long it has been out or gone. One record is one product x retailer x pin x day.",
                        "additionalProperties": false,
                        "required": [
                          "retailer",
                          "retailerSku",
                          "pincode",
                          "day",
                          "category",
                          "stockState",
                          "oosScope",
                          "outAtClose",
                          "closeInventory",
                          "minInventory",
                          "readings",
                          "outReadings",
                          "lowStockReadings",
                          "absentDays",
                          "outStreakDays",
                          "delistedStreakDays",
                          "lastReadingAt",
                          "closeObservationId"
                        ],
                        "properties": {
                          "retailer": {
                            "type": "string",
                            "title": "Retailer",
                            "description": "The retailer.",
                            "examples": [
                              "zepto"
                            ]
                          },
                          "retailerSku": {
                            "type": "string",
                            "title": "Retailer SKU",
                            "description": "The retailer's own product id.",
                            "examples": [
                              "a1b2c3"
                            ]
                          },
                          "pincode": {
                            "type": "string",
                            "title": "Pin code",
                            "description": "The pin code.",
                            "examples": [
                              "560034"
                            ]
                          },
                          "day": {
                            "type": "string",
                            "format": "date",
                            "title": "Day",
                            "description": "The IST day.",
                            "examples": [
                              "2026-10-21"
                            ]
                          },
                          "category": {
                            "type": "string",
                            "title": "Category",
                            "description": "The search the listing was collected under; (unknown) when none.",
                            "examples": [
                              "atta"
                            ]
                          },
                          "stockState": {
                            "type": "string",
                            "enum": [
                              "in",
                              "low",
                              "out",
                              "delisted",
                              "unknown"
                            ],
                            "title": "Stock state",
                            "description": "At the close of the day: in, low (few left), out, delisted (not listed for days) or unknown (the page said nothing).",
                            "examples": [
                              "out"
                            ]
                          },
                          "oosScope": {
                            "type": "string",
                            "enum": [
                              "pin",
                              "retailer_wide"
                            ],
                            "title": "Out of stock where",
                            "description": "pin: out at this pin; retailer_wide: out at every pin read that day.",
                            "examples": [
                              "pin"
                            ]
                          },
                          "outAtClose": {
                            "type": "boolean",
                            "title": "Out at close",
                            "description": "Out at the last reading of the day.",
                            "examples": [
                              true
                            ]
                          },
                          "closeInventory": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Stock at close",
                            "description": "Units shown at the last reading, when the page shows a count.",
                            "examples": [
                              3
                            ]
                          },
                          "minInventory": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Lowest stock",
                            "description": "The lowest unit count shown that day.",
                            "examples": [
                              2
                            ]
                          },
                          "readings": {
                            "type": "integer",
                            "title": "Readings",
                            "description": "Readings that said something about stock.",
                            "examples": [
                              6
                            ],
                            "minimum": 0
                          },
                          "outReadings": {
                            "type": "integer",
                            "title": "Out readings",
                            "description": "Of those, readings that said out of stock.",
                            "examples": [
                              2
                            ],
                            "minimum": 0
                          },
                          "lowStockReadings": {
                            "type": "integer",
                            "title": "Low stock readings",
                            "description": "Readings that said only a few were left.",
                            "examples": [
                              1
                            ],
                            "minimum": 0
                          },
                          "absentDays": {
                            "type": "integer",
                            "title": "Days absent",
                            "description": "Days in a row the listing was not listed (up to 60).",
                            "examples": [
                              0
                            ],
                            "minimum": 0
                          },
                          "outStreakDays": {
                            "type": "integer",
                            "title": "Days out",
                            "description": "Days in a row it has been out at close.",
                            "examples": [
                              1
                            ],
                            "minimum": 0
                          },
                          "delistedStreakDays": {
                            "type": "integer",
                            "title": "Days delisted",
                            "description": "Days in a row it has been delisted.",
                            "examples": [
                              0
                            ],
                            "minimum": 0
                          },
                          "lastReadingAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "title": "Last reading",
                            "description": "The newest reading of the day; null for a day it was not listed.",
                            "examples": [
                              "2026-10-21T15:40:00Z"
                            ]
                          },
                          "closeObservationId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Observation",
                            "description": "The kept reading the close state comes from (its source, fetch time and SHA-256); null for a day it was not listed.",
                            "examples": [
                              "48210377"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "prd-88213"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this retailer product id (use together with retailer)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^(national|[0-9]{6})$"
            },
            "description": "Only this six-digit pin code, or national."
          },
          {
            "name": "stockState",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Stock state",
              "examples": [
                "out"
              ],
              "pattern": "^(in|low|out|delisted|unknown)$"
            },
            "description": "Only this state at close: in, low, out, delisted or unknown."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/storefronts": {
      "get": {
        "operationId": "listStorefronts",
        "summary": "List D2C stores and their platforms",
        "description": "Each online store in Rewalto’s storefront index with a decided platform (shopify, woocommerce, magento, fynd, unicommerce and others): how sure Rewalto is of the platform, the market, when Rewalto first and last read the store, when a read last succeeded, and how many products and variants Rewalto holds from its catalogue. In host order, optionally one store, one platform and one market. Catalogue entry ds_d2c_platforms; one record is one store, charged as a listing. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StorefrontsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "host",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Store",
              "examples": [
                "www.mamaearth.in"
              ],
              "pattern": "^[a-z0-9][a-z0-9.-]{1,252}$"
            },
            "description": "Only this store (its host name, lower case)."
          },
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Platform",
              "examples": [
                "shopify"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only stores on this platform."
          },
          {
            "name": "market",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Market",
              "examples": [
                "IN"
              ],
              "pattern": "^[A-Z]{2}$"
            },
            "description": "Only stores in this market (ISO 3166 country code)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/storefronts/changes": {
      "get": {
        "operationId": "listStorefrontChanges",
        "summary": "List what D2C stores changed",
        "description": "Each change Rewalto saw on a D2C store’s catalogue between two reads: a product launched (with its name, variant count and the store’s own published date) or delisted (with how many reads it was missing), a variant’s price changed (old and new price and struck-through price, in minor units), its struck-through price moved while the price held (promotion_changed), or its stock changed (a read past the per-read event budget is one summary record). Newest first, optionally one store, one kind of change and an IST day range. Catalogue entry wf_d2c_changes; one record is one change, charged as a listing. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StorefrontChangesPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "host",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Store",
              "examples": [
                "www.mamaearth.in"
              ],
              "pattern": "^[a-z0-9][a-z0-9.-]{1,252}$"
            },
            "description": "Only this store (its host name, lower case)."
          },
          {
            "name": "change",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Change",
              "examples": [
                "price_changed"
              ],
              "pattern": "^(launched|delisted|price_changed|promotion_changed|stock_changed)$"
            },
            "description": "Only this kind of change: launched, delisted, price_changed, promotion_changed or stock_changed."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-10-01"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-10-17"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/storefronts/products": {
      "get": {
        "operationId": "listStorefrontProducts",
        "summary": "List products and prices on D2C store catalogues",
        "description": "Each product variant on a D2C store’s own catalogue as Rewalto last read it: name, variant, brand, SKU and barcode, price and struck-through price in minor units (paise for INR), in stock or not, tags, image addresses, when Rewalto first and last saw it, and how many reads in a row missed it. One store (host), a name search (q), a brand or a barcode, in any combination; sku with host. Catalogue entry lib_d2c_catalogue; one record is one variant, charged as a listing. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/StorefrontProductsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "host",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Store",
              "examples": [
                "www.mamaearth.in"
              ],
              "pattern": "^[a-z0-9][a-z0-9.-]{1,252}$"
            },
            "description": "Only this store (its host name, lower case)."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Name contains",
              "examples": [
                "hair oil"
              ],
              "minLength": 3,
              "maxLength": 100
            },
            "description": "Only products whose name contains this text (case-insensitive, 3 to 100 characters)."
          },
          {
            "name": "brand",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Mamaearth"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this brand (case-insensitive exact match)."
          },
          {
            "name": "barcode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Barcode",
              "examples": [
                "8906087771234"
              ],
              "pattern": "^[0-9A-Za-z-]{4,40}$"
            },
            "description": "Only this barcode (GTIN/EAN)."
          },
          {
            "name": "sku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "SKU",
              "examples": [
                "MAE-OHO-250"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this SKU (exact; use with host)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/data/units": {
      "get": {
        "operationId": "listUnits",
        "summary": "List units left and units gone per product and pin code",
        "description": "For one retailer: each listing’s units on every IST day it showed a units counter, per pin code: the units left at the day’s last reading, the first, fewest and most units, the units at its last reading of the 3 days before, and the units gone between readings (every fall counted, every rise counted as a restock): a LOWER BOUND on units sold, never an estimate. unitsFrom says whether the units are the app’s own counter (Blinkit, Zepto, Myntra, Nykaa) or Flipkart’s \"Only N left\" badge. Newest day first, optionally one product (retailerSku), one pin code and a day range. Catalogue entry lib_unit_velocity; one record is one listing-day. Charged per record delivered at the dataset’s published rate (GET /v1/catalogue/entries/{id} shows it); re-reading the same records within 7 days is free, and an empty page costs nothing. No quote is needed: meta.credits shows the rate charged and the credits left. When the credits cannot cover the page: 402 credits_exhausted and no data.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Units page",
                  "description": "One page of records with paging, the as-of time and what the page cost.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page",
                    "meta"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Records",
                      "description": "The records of this page, newest first.",
                      "items": {
                        "type": "object",
                        "title": "UnitDay",
                        "description": "One listing at one pin code on one IST day: the units the retailer showed as left, and the units that went between readings (a lower bound on units sold).",
                        "additionalProperties": false,
                        "required": [
                          "day",
                          "retailer",
                          "retailerSku",
                          "pincode",
                          "unitsFrom",
                          "readings",
                          "unitsLeft",
                          "firstUnits",
                          "minUnits",
                          "maxUnits",
                          "previousUnits",
                          "unitsGone",
                          "unitsRestocked",
                          "restocks",
                          "lastObservationId",
                          "lastObservedAt"
                        ],
                        "properties": {
                          "day": {
                            "type": "string",
                            "format": "date",
                            "title": "Day",
                            "description": "The IST day.",
                            "examples": [
                              "2026-10-21"
                            ]
                          },
                          "retailer": {
                            "type": "string",
                            "title": "Retailer",
                            "description": "The retailer.",
                            "examples": [
                              "blinkit"
                            ]
                          },
                          "retailerSku": {
                            "type": "string",
                            "title": "Retailer SKU",
                            "description": "The retailer's own product id.",
                            "examples": [
                              "512345"
                            ]
                          },
                          "pincode": {
                            "type": "string",
                            "title": "Pin code",
                            "description": "The pin code, or national.",
                            "examples": [
                              "560034"
                            ]
                          },
                          "unitsFrom": {
                            "type": "string",
                            "enum": [
                              "counter",
                              "badge"
                            ],
                            "title": "Units from",
                            "description": "counter: the app’s own units counter (Blinkit, Zepto, Myntra, Nykaa); badge: Flipkart’s \"Only N left\".",
                            "examples": [
                              "counter"
                            ]
                          },
                          "readings": {
                            "type": "integer",
                            "title": "Readings",
                            "description": "Readings of the day that showed units.",
                            "examples": [
                              2
                            ]
                          },
                          "unitsLeft": {
                            "type": "integer",
                            "title": "Units left",
                            "description": "The units shown at the day’s last reading.",
                            "examples": [
                              3
                            ]
                          },
                          "firstUnits": {
                            "type": "integer",
                            "title": "First units",
                            "description": "The units shown at the day’s first reading.",
                            "examples": [
                              5
                            ]
                          },
                          "minUnits": {
                            "type": "integer",
                            "title": "Fewest units",
                            "description": "The fewest units shown that day.",
                            "examples": [
                              3
                            ]
                          },
                          "maxUnits": {
                            "type": "integer",
                            "title": "Most units",
                            "description": "The most units shown that day.",
                            "examples": [
                              5
                            ]
                          },
                          "previousUnits": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Previous units",
                            "description": "The units at the listing’s last reading of the 3 days before; null when none.",
                            "examples": [
                              6
                            ]
                          },
                          "unitsGone": {
                            "type": "integer",
                            "title": "Units gone",
                            "description": "Every fall in the units between consecutive readings, from the previous units on: a LOWER BOUND on units sold (sales inside a restock, or while a counter sits at its cap, are not seen).",
                            "examples": [
                              3
                            ]
                          },
                          "unitsRestocked": {
                            "type": "integer",
                            "title": "Units restocked",
                            "description": "Every rise in the units, summed.",
                            "examples": [
                              0
                            ]
                          },
                          "restocks": {
                            "type": "integer",
                            "title": "Restocks",
                            "description": "How many times the units rose.",
                            "examples": [
                              0
                            ]
                          },
                          "lastObservationId": {
                            "type": "string",
                            "title": "Last observation",
                            "description": "The day’s last kept reading (its source, fetch time and SHA-256).",
                            "examples": [
                              "48210377"
                            ]
                          },
                          "lastObservedAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Last observed at",
                            "description": "When that reading was taken.",
                            "examples": [
                              "2026-10-21T15:40:00Z"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging state.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            100
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                          "examples": [
                            "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                          ]
                        }
                      }
                    },
                    "meta": {
                      "type": "object",
                      "title": "Meta",
                      "description": "Where the data comes from and what the page cost.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "asOf",
                        "credits"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "enum": [
                            "kept"
                          ],
                          "title": "Kind",
                          "description": "kept: read from data Rewalto stores as history.",
                          "examples": [
                            "kept"
                          ]
                        },
                        "asOf": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "As of",
                          "description": "The newest ingestion time among the records; null for an empty page.",
                          "examples": [
                            "2026-10-14T10:40:00Z"
                          ]
                        },
                        "credits": {
                          "$ref": "#/components/schemas/ReadCredits"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "retailer",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Retailer",
              "examples": [
                "blinkit"
              ],
              "pattern": "^[a-z0-9_]{2,40}$"
            },
            "description": "Only this retailer (a key from /v1/data/retailers)."
          },
          {
            "name": "retailerSku",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Retailer product id",
              "examples": [
                "512345"
              ],
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Only this retailer product id."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "560034"
              ],
              "pattern": "^(national|[1-9][0-9]{5})$"
            },
            "description": "Only this six-digit pin code, or national."
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "From",
              "examples": [
                "2026-09-02"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or after this day (YYYY-MM-DD)."
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "To",
              "examples": [
                "2026-09-06"
              ],
              "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
            },
            "description": "Only IST days on or before this day (YYYY-MM-DD)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "100"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many records to return, 1 to 500. Default 100."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0wOS0wNlQwMDowMDowMFoiLCJpIjoiMCJ9"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, sent back with exactly the same filters. A cursor from other filters is refused."
          }
        ]
      }
    },
    "/v1/demo": {
      "get": {
        "operationId": "getDemoWorkspace",
        "summary": "The demo workspace: a free real sample",
        "description": "A fixed sample for a new account (D-1893): real ghee listings on Blinkit, Instamart and Zepto from Rewalto's own collection, each with its price, MRP, stock, pin, city, time seen and evidence (source URL and SHA-256), a summary per retailer (price range, below-MRP count, in-stock share), and chart series in exactly the shape of getSeries. Always label it as a sample with its snapshot day: it is not the account's data and is not live. Brands are alphabetical and never ranked. Free: nothing is charged, held or needed, and meta.credits is always zero.",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DemoWorkspace"
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/exports": {
      "post": {
        "operationId": "startExport",
        "summary": "Buy a snapshot: start its export",
        "description": "Starts the purchase of an approved snapshot quote (POST /v1/snapshots/{id}/quote, then POST /v1/quotes/{id}/approve). The worker builds the JSON Lines file of exactly that edition; the hold is settled on the rows delivered, never above the quote, and a failed export charges nothing. Idempotent: starting the same quote again returns the same purchase and starts nothing new. Any member may buy (D-1557).",
        "tags": [
          "Exports"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Purchase answer",
                  "description": "One purchase.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Dataset purchase",
                      "description": "One purchase of a snapshot edition: its state, the file once built, what was charged, and how long it can be downloaded.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "snapshotId",
                        "quoteId",
                        "asOf",
                        "licenceVersion",
                        "format",
                        "state",
                        "rows",
                        "bytes",
                        "sha256",
                        "receiptId",
                        "error",
                        "createdAt",
                        "finishedAt",
                        "availableUntil"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The purchase id.",
                          "examples": [
                            "3f2a0c5e-9b1d-4c1e-8f00-1a2b3c4d5e6f"
                          ],
                          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                        },
                        "snapshotId": {
                          "type": "string",
                          "title": "Snapshot",
                          "description": "The snapshot bought.",
                          "examples": [
                            "listings_blinkit_in"
                          ],
                          "pattern": "^[a-z][a-z0-9_]{1,63}$"
                        },
                        "quoteId": {
                          "type": "string",
                          "title": "Quote",
                          "description": "The approved quote it was bought on.",
                          "examples": [
                            "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
                          ],
                          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                        },
                        "asOf": {
                          "type": "string",
                          "title": "As of",
                          "description": "The edition date (IST).",
                          "examples": [
                            "2026-10-16"
                          ],
                          "format": "date"
                        },
                        "licenceVersion": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Licence",
                          "description": "The licence version accepted (D-1556).",
                          "examples": [
                            1
                          ]
                        },
                        "format": {
                          "type": "string",
                          "const": "jsonl",
                          "title": "Format",
                          "description": "JSON Lines."
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "queued",
                            "running",
                            "ready",
                            "failed",
                            "expired"
                          ],
                          "title": "State",
                          "description": "queued, running, ready, failed or expired.",
                          "examples": [
                            "queued"
                          ]
                        },
                        "rows": {
                          "type": [
                            "null",
                            "integer"
                          ],
                          "minimum": 0,
                          "title": "Rows",
                          "description": "Records in the file; null until ready.",
                          "examples": [
                            648142
                          ]
                        },
                        "bytes": {
                          "type": [
                            "null",
                            "integer"
                          ],
                          "minimum": 0,
                          "title": "Bytes",
                          "description": "File size; null until ready.",
                          "examples": [
                            260000000
                          ]
                        },
                        "sha256": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "SHA-256",
                          "description": "Of the file; null until ready.",
                          "examples": [
                            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                          ],
                          "pattern": "^[0-9a-f]{64}$"
                        },
                        "receiptId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Receipt",
                          "description": "What was charged; null until finished.",
                          "examples": [
                            "7b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e"
                          ]
                        },
                        "error": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Error",
                          "description": "Why it failed; null otherwise.",
                          "examples": [
                            "upload failed"
                          ]
                        },
                        "createdAt": {
                          "type": "string",
                          "title": "Bought at",
                          "description": "When the purchase started.",
                          "examples": [
                            "2026-10-17T06:30:00Z"
                          ],
                          "format": "date-time"
                        },
                        "finishedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Finished at",
                          "description": "When it was built or failed.",
                          "examples": [
                            "2026-10-17T06:40:00Z"
                          ],
                          "format": "date-time"
                        },
                        "availableUntil": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Available until",
                          "description": "Downloadable until (D-1555: 12 months after ready).",
                          "examples": [
                            "2027-10-17T06:40:00Z"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Start a purchase",
                "description": "Start the export of an approved snapshot quote. Idempotent: the same quote returns the same purchase.",
                "additionalProperties": false,
                "required": [
                  "quoteId"
                ],
                "properties": {
                  "quoteId": {
                    "type": "string",
                    "title": "Quote",
                    "description": "An approved snapshot quote of your organisation.",
                    "examples": [
                      "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
                    ],
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listExports",
        "summary": "List your dataset purchases",
        "description": "Your organisation's snapshot purchases, newest first: state, file size and SHA-256 once built, the receipt, and until when each can be downloaded (D-1555).",
        "tags": [
          "Exports"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Purchases",
                  "description": "Your organisation's purchases, newest first.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Purchases",
                      "description": "The purchases.",
                      "items": {
                        "type": "object",
                        "title": "Dataset purchase",
                        "description": "One purchase of a snapshot edition: its state, the file once built, what was charged, and how long it can be downloaded.",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "snapshotId",
                          "quoteId",
                          "asOf",
                          "licenceVersion",
                          "format",
                          "state",
                          "rows",
                          "bytes",
                          "sha256",
                          "receiptId",
                          "error",
                          "createdAt",
                          "finishedAt",
                          "availableUntil"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "title": "Id",
                            "description": "The purchase id.",
                            "examples": [
                              "3f2a0c5e-9b1d-4c1e-8f00-1a2b3c4d5e6f"
                            ],
                            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                          },
                          "snapshotId": {
                            "type": "string",
                            "title": "Snapshot",
                            "description": "The snapshot bought.",
                            "examples": [
                              "listings_blinkit_in"
                            ],
                            "pattern": "^[a-z][a-z0-9_]{1,63}$"
                          },
                          "quoteId": {
                            "type": "string",
                            "title": "Quote",
                            "description": "The approved quote it was bought on.",
                            "examples": [
                              "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
                            ],
                            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                          },
                          "asOf": {
                            "type": "string",
                            "title": "As of",
                            "description": "The edition date (IST).",
                            "examples": [
                              "2026-10-16"
                            ],
                            "format": "date"
                          },
                          "licenceVersion": {
                            "type": "integer",
                            "minimum": 1,
                            "title": "Licence",
                            "description": "The licence version accepted (D-1556).",
                            "examples": [
                              1
                            ]
                          },
                          "format": {
                            "type": "string",
                            "const": "jsonl",
                            "title": "Format",
                            "description": "JSON Lines."
                          },
                          "state": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "running",
                              "ready",
                              "failed",
                              "expired"
                            ],
                            "title": "State",
                            "description": "queued, running, ready, failed or expired.",
                            "examples": [
                              "queued"
                            ]
                          },
                          "rows": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "minimum": 0,
                            "title": "Rows",
                            "description": "Records in the file; null until ready.",
                            "examples": [
                              648142
                            ]
                          },
                          "bytes": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "minimum": 0,
                            "title": "Bytes",
                            "description": "File size; null until ready.",
                            "examples": [
                              260000000
                            ]
                          },
                          "sha256": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "SHA-256",
                            "description": "Of the file; null until ready.",
                            "examples": [
                              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                            ],
                            "pattern": "^[0-9a-f]{64}$"
                          },
                          "receiptId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Receipt",
                            "description": "What was charged; null until finished.",
                            "examples": [
                              "7b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e"
                            ]
                          },
                          "error": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Error",
                            "description": "Why it failed; null otherwise.",
                            "examples": [
                              "upload failed"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "title": "Bought at",
                            "description": "When the purchase started.",
                            "examples": [
                              "2026-10-17T06:30:00Z"
                            ],
                            "format": "date-time"
                          },
                          "finishedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Finished at",
                            "description": "When it was built or failed.",
                            "examples": [
                              "2026-10-17T06:40:00Z"
                            ],
                            "format": "date-time"
                          },
                          "availableUntil": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Available until",
                            "description": "Downloadable until (D-1555: 12 months after ready).",
                            "examples": [
                              "2027-10-17T06:40:00Z"
                            ],
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            20
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Pass as cursor for the next page; null at the end.",
                          "examples": [
                            "eyJ0Ijo..."
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Limit",
              "examples": [
                "20"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many, 1 to 100 (default 20)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xN1QwNjozMDowMFoiLCJpIjoiLi4uIn0"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,200}$"
            },
            "description": "page.nextCursor from the previous page."
          }
        ]
      }
    },
    "/v1/exports/{id}": {
      "get": {
        "operationId": "getExport",
        "summary": "Read a dataset purchase",
        "description": "One purchase of your organisation. Another organisation's purchase is not found.",
        "tags": [
          "Exports"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Purchase answer",
                  "description": "One purchase.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Dataset purchase",
                      "description": "One purchase of a snapshot edition: its state, the file once built, what was charged, and how long it can be downloaded.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "snapshotId",
                        "quoteId",
                        "asOf",
                        "licenceVersion",
                        "format",
                        "state",
                        "rows",
                        "bytes",
                        "sha256",
                        "receiptId",
                        "error",
                        "createdAt",
                        "finishedAt",
                        "availableUntil"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The purchase id.",
                          "examples": [
                            "3f2a0c5e-9b1d-4c1e-8f00-1a2b3c4d5e6f"
                          ],
                          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                        },
                        "snapshotId": {
                          "type": "string",
                          "title": "Snapshot",
                          "description": "The snapshot bought.",
                          "examples": [
                            "listings_blinkit_in"
                          ],
                          "pattern": "^[a-z][a-z0-9_]{1,63}$"
                        },
                        "quoteId": {
                          "type": "string",
                          "title": "Quote",
                          "description": "The approved quote it was bought on.",
                          "examples": [
                            "6a1b2c3d-4e5f-4a6b-8c7d-9e0f1a2b3c4d"
                          ],
                          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                        },
                        "asOf": {
                          "type": "string",
                          "title": "As of",
                          "description": "The edition date (IST).",
                          "examples": [
                            "2026-10-16"
                          ],
                          "format": "date"
                        },
                        "licenceVersion": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Licence",
                          "description": "The licence version accepted (D-1556).",
                          "examples": [
                            1
                          ]
                        },
                        "format": {
                          "type": "string",
                          "const": "jsonl",
                          "title": "Format",
                          "description": "JSON Lines."
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "queued",
                            "running",
                            "ready",
                            "failed",
                            "expired"
                          ],
                          "title": "State",
                          "description": "queued, running, ready, failed or expired.",
                          "examples": [
                            "queued"
                          ]
                        },
                        "rows": {
                          "type": [
                            "null",
                            "integer"
                          ],
                          "minimum": 0,
                          "title": "Rows",
                          "description": "Records in the file; null until ready.",
                          "examples": [
                            648142
                          ]
                        },
                        "bytes": {
                          "type": [
                            "null",
                            "integer"
                          ],
                          "minimum": 0,
                          "title": "Bytes",
                          "description": "File size; null until ready.",
                          "examples": [
                            260000000
                          ]
                        },
                        "sha256": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "SHA-256",
                          "description": "Of the file; null until ready.",
                          "examples": [
                            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                          ],
                          "pattern": "^[0-9a-f]{64}$"
                        },
                        "receiptId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Receipt",
                          "description": "What was charged; null until finished.",
                          "examples": [
                            "7b2c3d4e-5f6a-4b7c-8d9e-0f1a2b3c4d5e"
                          ]
                        },
                        "error": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Error",
                          "description": "Why it failed; null otherwise.",
                          "examples": [
                            "upload failed"
                          ]
                        },
                        "createdAt": {
                          "type": "string",
                          "title": "Bought at",
                          "description": "When the purchase started.",
                          "examples": [
                            "2026-10-17T06:30:00Z"
                          ],
                          "format": "date-time"
                        },
                        "finishedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Finished at",
                          "description": "When it was built or failed.",
                          "examples": [
                            "2026-10-17T06:40:00Z"
                          ],
                          "format": "date-time"
                        },
                        "availableUntil": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Available until",
                          "description": "Downloadable until (D-1555: 12 months after ready).",
                          "examples": [
                            "2027-10-17T06:40:00Z"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The purchase id.",
              "examples": [
                "3f2a0c5e-9b1d-4c1e-8f00-1a2b3c4d5e6f"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ]
      }
    },
    "/v1/exports/{id}/link": {
      "post": {
        "operationId": "getExportDownloadLink",
        "summary": "Get a download link for a purchase",
        "description": "A short-lived signed link (15 minutes, never past the window) to the purchase file. Ask again, free, whenever it runs out, for 12 months after the file was ready (D-1555). `export_not_ready` while it is being built; `download_expired` after the 12 months (the file is kept, but no longer offered) or for a purchase that failed (it has no file and charged nothing).",
        "tags": [
          "Exports"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Download link",
                  "description": "A short-lived link to the purchase file. Ask again, free, whenever it has run out, until availableUntil (D-1555: 12 months after it was ready). Check the file against sha256.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Link",
                      "description": "The link and the file it opens.",
                      "additionalProperties": false,
                      "required": [
                        "url",
                        "expiresAt",
                        "availableUntil",
                        "bytes",
                        "sha256",
                        "licenceVersion"
                      ],
                      "properties": {
                        "url": {
                          "type": "string",
                          "title": "Link",
                          "description": "Opens the JSON Lines file; works until expiresAt. Do not share it: it is your licensed copy (D-1556).",
                          "examples": [
                            "https://store.example/exports/..."
                          ]
                        },
                        "expiresAt": {
                          "type": "string",
                          "title": "Expires at",
                          "description": "When this link stops working (minutes from now).",
                          "examples": [
                            "2026-10-17T06:45:00Z"
                          ],
                          "format": "date-time"
                        },
                        "availableUntil": {
                          "type": "string",
                          "title": "Available until",
                          "description": "Until when new links can be asked for.",
                          "examples": [
                            "2027-10-17T06:40:00Z"
                          ],
                          "format": "date-time"
                        },
                        "bytes": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Bytes",
                          "description": "The file size.",
                          "examples": [
                            260000000
                          ]
                        },
                        "sha256": {
                          "type": "string",
                          "title": "SHA-256",
                          "description": "Of the file.",
                          "examples": [
                            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                          ],
                          "pattern": "^[0-9a-f]{64}$"
                        },
                        "licenceVersion": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Licence",
                          "description": "The licence the copy is under.",
                          "examples": [
                            1
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `export_not_ready`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "410": {
            "description": "Error. The `error.code` is one of:\n- `download_expired`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The purchase id.",
              "examples": [
                "3f2a0c5e-9b1d-4c1e-8f00-1a2b3c4d5e6f"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ]
      }
    },
    "/v1/figures": {
      "get": {
        "operationId": "getSiteFigures",
        "summary": "Get Rewalto's headline figures",
        "description": "The site's headline figures, counted from Rewalto's own readings as they land: prices captured (readings with a price, all time), products tracked, platforms tracked (apps and stores Rewalto reads itself), open dark stores and their cities, and pin codes read, with measuredAt, the moment before which every reading is counted. The totals are brought up to date every few minutes, so measuredAt stays within the hour. Answers unavailable while the totals are still being counted for the first time. Public and free.",
        "tags": [
          "Figures"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SiteFigures"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/free/pin-availability": {
      "get": {
        "operationId": "getFreePinAvailability",
        "summary": "Free: is a brand live on the quick-commerce apps at a pin code?",
        "description": "One brand at one six-digit pin code: per app, how many of the brand’s listings were read there in the window and the 8 most recently read, each with stock (in_stock, out_of_stock, or not_reported when the reading did not say), selling price and MRP in paise (null when not shown), and when it was read. Public and free: no sign-in, never charged (meta.credits is zero). At most 60 checks an hour per caller IP across both free tools (`rate_limited`, with Retry-After). The brand is typed text: when it names one tracked brand on the quick-commerce apps (exactly, case ignored, or the only match) that brand is read (`status: measured`); several matches answer `choose_brand` with up to 8 `brandChoices` (call again with one); none answers `no_brand_match`. Apps: blinkit, instamart, zepto. Readings of the last 24 hours count (`window`); each listing’s newest reading per pin code. Per app, `not_collected` means Rewalto reads no listing at that pin code on that app (in the last 30 days), and `no_recent_reading` that it does but read nothing for this brand in the window: neither is a stockout. Readings on a pin-day left out of the data are not counted (`readingsLeftOut`). Every reading carries its app, pin code and time. The site’s /tools/pin-code-availability.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FreePinAvailability"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "brand",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Amul"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "The brand as typed (2 to 100 characters)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110001"
              ],
              "pattern": "^[1-9][0-9]{5}$"
            },
            "description": "A six-digit Indian pin code."
          }
        ]
      }
    },
    "/v1/free/price-parity": {
      "get": {
        "operationId": "getFreePriceParity",
        "summary": "Free: one brand’s selling price against MRP on the quick-commerce apps",
        "description": "One brand, optionally narrowed to listings whose name contains `product` and to one pin code (left out: every pin code read in the window): per app, each listing’s newest reading per pin code, how many there are and how many are flagged, and the 10 newest, each with selling price and MRP in paise, the whole percent below MRP (rounded down; null when either is missing or the price is above MRP) and `flagged` at 10% or more below MRP (not a legal or MAP threshold). Without a pin code no app is `not_collected`. Public and free: no sign-in, never charged (meta.credits is zero). At most 60 checks an hour per caller IP across both free tools (`rate_limited`, with Retry-After). The brand is typed text: when it names one tracked brand on the quick-commerce apps (exactly, case ignored, or the only match) that brand is read (`status: measured`); several matches answer `choose_brand` with up to 8 `brandChoices` (call again with one); none answers `no_brand_match`. Apps: blinkit, instamart, zepto. Readings of the last 24 hours count (`window`); each listing’s newest reading per pin code. Per app, `not_collected` means Rewalto reads no listing at that pin code on that app (in the last 30 days), and `no_recent_reading` that it does but read nothing for this brand in the window: neither is a stockout. Readings on a pin-day left out of the data are not counted (`readingsLeftOut`). Every reading carries its app, pin code and time. The site’s /tools/price-parity.",
        "tags": [
          "Free tools"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FreePriceParity"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "brand",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Brand",
              "examples": [
                "Amul"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "The brand as typed (2 to 100 characters)."
          },
          {
            "name": "product",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Product",
              "examples": [
                "butter"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "Optional: only listings whose name contains this (case ignored)."
          },
          {
            "name": "pincode",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Pin code",
              "examples": [
                "110001"
              ],
              "pattern": "^[1-9][0-9]{5}$"
            },
            "description": "Optional: only this pin code. Left out: every pin code read in the window."
          }
        ]
      }
    },
    "/v1/keys": {
      "post": {
        "operationId": "createKey",
        "summary": "Mint an API key for your organisation",
        "description": "Organisation admins only, signed in with a session (an API key cannot mint keys). The secret is in this response and nowhere else: only its SHA-256 is stored. The response is sent with Cache-Control: no-store.",
        "tags": [
          "API keys"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "cache-control": {
                "description": "Always `no-store`: the answer must not be cached.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CreateKeyResponse"
                },
                "example": {
                  "key": {
                    "id": "9d1c7e52-0a3b-4f68-b2e4-7c5a1d3f8e90",
                    "name": "pricing agent",
                    "prefix": "rwk_Xk3pQ9aB",
                    "scopes": [
                      "data:read"
                    ],
                    "status": "active",
                    "createdAt": "2026-10-16T09:30:00.000Z",
                    "expiresAt": "2026-11-15T09:30:00.000Z",
                    "revokedAt": null,
                    "lastUsedAt": null
                  },
                  "secret": "rwk_EXAMPLEONLYexampleonlyEXAMPLEONLYexampleonl"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateKeyRequest"
              },
              "example": {
                "name": "pricing agent",
                "scopes": [
                  "data:read"
                ],
                "expiresInDays": 30
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listKeys",
        "summary": "List your organisation's API keys",
        "description": "Any signed-in member. Newest first, including expired and revoked keys. Never returns a secret, only its first 12 characters (`prefix`).",
        "tags": [
          "API keys"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ListKeysResponse"
                },
                "example": {
                  "keys": [
                    {
                      "id": "9d1c7e52-0a3b-4f68-b2e4-7c5a1d3f8e90",
                      "name": "pricing agent",
                      "prefix": "rwk_Xk3pQ9aB",
                      "scopes": [
                        "data:read"
                      ],
                      "status": "active",
                      "createdAt": "2026-10-16T09:30:00.000Z",
                      "expiresAt": "2026-11-15T09:30:00.000Z",
                      "revokedAt": null,
                      "lastUsedAt": null
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/keys/first": {
      "post": {
        "operationId": "provisionFirstKey",
        "summary": "Get your organisation's first API key, made once",
        "description": "For the dashboard's Start page (D-1601). The first call for an organisation with no key makes one (\"First key\", scopes data:read and usage:read, 90 days) and answers with `created: true` and its secret, shown once and never again: only its SHA-256 is stored. Every later call, at the same moment or after, answers with the same key, `created: false` and `secret: null`; if the organisation already had keys (made with createKey), it answers with the oldest of them, `created: false` and `secret: null`, and makes nothing. Always 200: `created` says which. It never makes a second key, even when the first is revoked or expired: use createKey for more. No request body. Organisation admins only, with a session, like createKey: a member or an API key gets `forbidden`. Sent with Cache-Control: no-store.",
        "tags": [
          "API keys"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "cache-control": {
                "description": "Always `no-store`: the answer must not be cached.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProvisionFirstKeyResponse"
                },
                "example": {
                  "key": {
                    "id": "4b7e2c19-8d3a-4f6e-a1c5-0e9d2b7f3a64",
                    "name": "First key",
                    "prefix": "rwk_Xk3pQ9aB",
                    "scopes": [
                      "data:read",
                      "usage:read"
                    ],
                    "status": "active",
                    "createdAt": "2026-10-16T06:30:00.000Z",
                    "expiresAt": "2027-01-14T06:30:00.000Z",
                    "revokedAt": null,
                    "lastUsedAt": null
                  },
                  "secret": "rwk_EXAMPLEONLYexampleonlyEXAMPLEONLYexampleonl",
                  "created": true
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/keys/{id}/revoke": {
      "post": {
        "operationId": "revokeKey",
        "summary": "Revoke an API key",
        "description": "Organisation admins only, with a session. Takes effect on the next request. Revoking twice is harmless and keeps the first revocation time. A key of another organisation, or no such key, is `not_found`: the API never confirms that it exists. Keys are never deleted.",
        "tags": [
          "API keys"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RevokeKeyResponse"
                },
                "example": {
                  "key": {
                    "id": "9d1c7e52-0a3b-4f68-b2e4-7c5a1d3f8e90",
                    "name": "pricing agent",
                    "prefix": "rwk_Xk3pQ9aB",
                    "scopes": [
                      "data:read"
                    ],
                    "status": "revoked",
                    "createdAt": "2026-10-16T09:30:00.000Z",
                    "expiresAt": "2026-11-15T09:30:00.000Z",
                    "revokedAt": "2026-10-16T10:05:00.000Z",
                    "lastUsedAt": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/notification-destinations": {
      "get": {
        "operationId": "listNotificationDestinations",
        "summary": "List alert destinations",
        "description": "Your organisation's places to send watch alerts, newest first: channel, a readable label and whether it is working. Never the URL, secret, chat or address.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationDestinationsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createNotificationDestination",
        "summary": "Add an alert destination",
        "description": "Add a destination. slack: an incoming webhook URL (https://hooks.slack.com/services/...). webhook: your https URL; the answer carries its signing secret ONCE. telegram: no URL; the answer carries the links to press Start with. email: no URL; your own verified sign-in address (a signed-in session only). label is optional.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationDestinationCreated"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateNotificationDestination"
              }
            }
          }
        }
      }
    },
    "/v1/notification-destinations/{id}/test": {
      "post": {
        "operationId": "testNotificationDestination",
        "summary": "Send a test alert",
        "description": "Sends a short test message and answers the destination with its new status (working, or failing with lastError). A Telegram chat not linked yet is linked first: open its telegramLink, press Start, then call this. Free.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationDestinationAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^dst_[0-9a-f]{32}$",
              "title": "Destination id",
              "description": "A destination from listNotificationDestinations.",
              "examples": [
                "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
              ]
            }
          }
        ]
      }
    },
    "/v1/notification-preferences": {
      "get": {
        "operationId": "getNotificationPreferences",
        "summary": "Your notification preferences",
        "description": "Per kind of notification, whether it shows in the in-product feed and may be emailed; quiet hours; the email digest. A user who never saved reads `version: 0` and the launch defaults. Core stores these; the web app’s email sender reads them. Signed-in users only (a session); an API key is refused.",
        "tags": [
          "Onboarding and notifications"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationPreferences"
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "saveNotificationPreferences",
        "summary": "Save notification preferences",
        "description": "A partial save: send `version` (the one you read) and only what changed. Every save is kept as a new version; an out-of-date `version` is refused with `stale_version` (409). Turning a kind’s `inApp` off hides it from the feed (nothing is deleted). Free. Signed-in users only (a session); an API key is refused.",
        "tags": [
          "Onboarding and notifications"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationPreferences"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `stale_version`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveNotificationPreferences"
              }
            }
          }
        }
      }
    },
    "/v1/notifications": {
      "get": {
        "operationId": "listNotifications",
        "summary": "Your in-product notifications",
        "description": "The notifications for you and for your whole organisation, newest first, each with whether you have read it, and the count of everything unread. Kinds you turned off in your preferences are left out. Page with `before` = the previous `nextCursor`. Signed-in users only (a session); an API key is refused.",
        "tags": [
          "Onboarding and notifications"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationFeed"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "unread",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(true|false)$"
            },
            "description": "true: only unread ones."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([1-9]|[1-9][0-9]|100)$"
            },
            "description": "1-100, default 30."
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "The previous page’s `nextCursor`."
          }
        ]
      }
    },
    "/v1/notifications/read": {
      "post": {
        "operationId": "markNotificationsRead",
        "summary": "Mark notifications as read",
        "description": "Send `ids` (up to 100) or `all: true`. Marking one already read does nothing. Reads are kept, never removed. Free. Signed-in users only (a session); an API key is refused.",
        "tags": [
          "Onboarding and notifications"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MarkNotificationsReadResult"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MarkNotificationsRead"
              }
            }
          }
        }
      }
    },
    "/v1/onboarding": {
      "get": {
        "operationId": "getOnboarding",
        "summary": "Your saved onboarding answers, defaults and progress",
        "description": "What the signed-in user saved in onboarding: account type, company, referral, goals, preferred agent, the defaults they chose (retailers, pin codes, locations, categories, brand) and which steps are done. A user who never saved reads `version: 0` and empty answers. Send `version` back with the next save. Signed-in users only (a session); an API key is refused.",
        "tags": [
          "Onboarding and notifications"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingState"
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "saveOnboarding",
        "summary": "Save onboarding answers, defaults or progress",
        "description": "A partial save: send `version` (the one you read) and only what changed. Objects merge field by field; an array replaces that array. `completeSteps` marks steps finished, `step` moves the resume point, `finish: true` finishes onboarding. Every save is kept as a new version. If `version` is not the current one the save is refused with `stale_version` (409): read again and re-apply. Free. Signed-in users only (a session); an API key is refused.",
        "tags": [
          "Onboarding and notifications"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OnboardingState"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `stale_version`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SaveOnboarding"
              }
            }
          }
        }
      }
    },
    "/v1/order-requests": {
      "post": {
        "operationId": "createOrderRequest",
        "summary": "Ask for a pilot, brand plan, pack or report",
        "description": "Records an order request from the signed-in organisation: kind pilot (the free 4-week pilot of a brand plan) or order, for one offer of GET /v1/price-list with orderable true, with add-ons (the offer's addOns keys), a quantity, the billing and a note. Nothing is charged: Rewalto replies to the user's verified email, fulfils it by hand and sets its status (received, in_review, fulfilled or declined); a pilot is fulfilled by entitling the organisation (GET /v1/plan-entitlement). The same idempotencyKey answers the first request. At most 5 a minute per caller and 20 per organisation a day. API keys and MCP sign-ins are refused (forbidden).",
        "tags": [
          "Plans"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "message"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Order request",
                      "additionalProperties": false,
                      "required": [
                        "reference",
                        "kind",
                        "offerKey",
                        "offerVersion",
                        "offerName",
                        "addOns",
                        "quantity",
                        "billing",
                        "note",
                        "status",
                        "statusNote",
                        "statusAt",
                        "createdAt",
                        "paidAt",
                        "paymentOrderId",
                        "setup",
                        "deliveries"
                      ],
                      "properties": {
                        "reference": {
                          "type": "string",
                          "pattern": "^OR-[0-9]{6,}$",
                          "examples": [
                            "OR-000001"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "pilot",
                            "order"
                          ]
                        },
                        "offerKey": {
                          "type": "string"
                        },
                        "offerVersion": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "offerName": {
                          "type": "string"
                        },
                        "addOns": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "key",
                              "quantity"
                            ],
                            "properties": {
                              "key": {
                                "type": "string",
                                "pattern": "^[a-z][a-zA-Z0-9_]{0,40}$",
                                "description": "One of the offer’s addOns keys (cities, darkStores, ...)."
                              },
                              "quantity": {
                                "type": "integer",
                                "minimum": 1,
                                "maximum": 100
                              }
                            }
                          }
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "billing": {
                          "type": "string",
                          "enum": [
                            "one_off",
                            "month",
                            "year"
                          ]
                        },
                        "note": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "paid",
                            "fulfilled",
                            "declined"
                          ],
                          "description": "received, then paid (a basket checkout) or in_review; fulfilled when Rewalto has delivered it (or entitled the pilot), declined otherwise."
                        },
                        "statusNote": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "statusAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "paidAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "When its basket was paid; null when not paid online."
                        },
                        "paymentOrderId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid",
                          "description": "The basket order it was paid with (the paid value the payment page returns to), or null."
                        },
                        "setup": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "description": "The buyer’s choices in force (POST /v1/order-requests/{reference}/setup), or null.",
                          "additionalProperties": false,
                          "required": [
                            "choices",
                            "note",
                            "setAt"
                          ],
                          "properties": {
                            "choices": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "note": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "setAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        },
                        "deliveries": {
                          "type": "array",
                          "description": "Files Rewalto delivered, ready to download: POST /v1/order-requests/{reference}/deliveries/{downloadId}/link.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "downloadId",
                              "label",
                              "kind",
                              "fileName",
                              "bytes",
                              "readyAt"
                            ],
                            "properties": {
                              "downloadId": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "label": {
                                "type": "string"
                              },
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "file",
                                  "report"
                                ]
                              },
                              "fileName": {
                                "type": "string"
                              },
                              "bytes": {
                                "type": "integer",
                                "minimum": 1
                              },
                              "readyAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    },
                    "message": {
                      "type": "string",
                      "description": "A sentence to show the person who asked."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Order request",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "offerKey",
                  "idempotencyKey"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "pilot",
                      "order"
                    ],
                    "description": "pilot: the free 4-week pilot of a brand plan that offers one. order: buy the offer."
                  },
                  "offerKey": {
                    "type": "string",
                    "pattern": "^[a-z][a-z0-9_]{1,40}$",
                    "description": "A brand plan, pack or report from GET /v1/price-list (orderable true)."
                  },
                  "addOns": {
                    "type": "array",
                    "maxItems": 20,
                    "items": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "key",
                        "quantity"
                      ],
                      "properties": {
                        "key": {
                          "type": "string",
                          "pattern": "^[a-z][a-zA-Z0-9_]{0,40}$",
                          "description": "One of the offer’s addOns keys (cities, darkStores, ...)."
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1,
                          "maximum": 100
                        }
                      }
                    }
                  },
                  "quantity": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "description": "How many (cities for a per-city report, for example). Default 1."
                  },
                  "billing": {
                    "type": "string",
                    "enum": [
                      "one_off",
                      "month",
                      "year"
                    ],
                    "description": "month or year for a brand plan (default month); month for a monthly report or a pack’s daily refresh; one_off otherwise (default for packs and reports)."
                  },
                  "note": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000,
                    "description": "Anything Rewalto should know."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "minLength": 8,
                    "maxLength": 200,
                    "description": "The same key is the same request: sending it again answers the first."
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listOrderRequests",
        "summary": "The organisation’s order requests",
        "description": "The organisation’s pilot and order requests, newest first, with their status. Never charged.",
        "tags": [
          "Plans"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "title": "Order request",
                        "additionalProperties": false,
                        "required": [
                          "reference",
                          "kind",
                          "offerKey",
                          "offerVersion",
                          "offerName",
                          "addOns",
                          "quantity",
                          "billing",
                          "note",
                          "status",
                          "statusNote",
                          "statusAt",
                          "createdAt",
                          "paidAt",
                          "paymentOrderId",
                          "setup",
                          "deliveries"
                        ],
                        "properties": {
                          "reference": {
                            "type": "string",
                            "pattern": "^OR-[0-9]{6,}$",
                            "examples": [
                              "OR-000001"
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "pilot",
                              "order"
                            ]
                          },
                          "offerKey": {
                            "type": "string"
                          },
                          "offerVersion": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "offerName": {
                            "type": "string"
                          },
                          "addOns": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "key",
                                "quantity"
                              ],
                              "properties": {
                                "key": {
                                  "type": "string",
                                  "pattern": "^[a-z][a-zA-Z0-9_]{0,40}$",
                                  "description": "One of the offer’s addOns keys (cities, darkStores, ...)."
                                },
                                "quantity": {
                                  "type": "integer",
                                  "minimum": 1,
                                  "maximum": 100
                                }
                              }
                            }
                          },
                          "quantity": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "billing": {
                            "type": "string",
                            "enum": [
                              "one_off",
                              "month",
                              "year"
                            ]
                          },
                          "note": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "received",
                              "in_review",
                              "paid",
                              "fulfilled",
                              "declined"
                            ],
                            "description": "received, then paid (a basket checkout) or in_review; fulfilled when Rewalto has delivered it (or entitled the pilot), declined otherwise."
                          },
                          "statusNote": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "statusAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "paidAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "description": "When its basket was paid; null when not paid online."
                          },
                          "paymentOrderId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid",
                            "description": "The basket order it was paid with (the paid value the payment page returns to), or null."
                          },
                          "setup": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "description": "The buyer’s choices in force (POST /v1/order-requests/{reference}/setup), or null.",
                            "additionalProperties": false,
                            "required": [
                              "choices",
                              "note",
                              "setAt"
                            ],
                            "properties": {
                              "choices": {
                                "type": "object",
                                "additionalProperties": true
                              },
                              "note": {
                                "type": [
                                  "null",
                                  "string"
                                ]
                              },
                              "setAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          },
                          "deliveries": {
                            "type": "array",
                            "description": "Files Rewalto delivered, ready to download: POST /v1/order-requests/{reference}/deliveries/{downloadId}/link.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "downloadId",
                                "label",
                                "kind",
                                "fileName",
                                "bytes",
                                "readyAt"
                              ],
                              "properties": {
                                "downloadId": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "label": {
                                  "type": "string"
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "file",
                                    "report"
                                  ]
                                },
                                "fileName": {
                                  "type": "string"
                                },
                                "bytes": {
                                  "type": "integer",
                                  "minimum": 1
                                },
                                "readyAt": {
                                  "type": "string",
                                  "format": "date-time"
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/order-requests/{reference}/deliveries/{downloadId}/link": {
      "post": {
        "operationId": "getOrderDeliveryLink",
        "summary": "Download a delivered file",
        "description": "A signed link, valid 15 minutes, to one file Rewalto delivered for one of the organisation's order requests (its deliveries). Ask again, free, whenever it is needed. Another organisation's request or file answers not_found.",
        "tags": [
          "Plans"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "url",
                        "fileName",
                        "expiresAt"
                      ],
                      "properties": {
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "fileName": {
                          "type": "string"
                        },
                        "expiresAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^OR-[0-9]{6,}$"
            }
          },
          {
            "name": "downloadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/order-requests/{reference}/setup": {
      "post": {
        "operationId": "setOrderRequestSetup",
        "summary": "Choose what an order is for",
        "description": "The buyer's choices for one of the organisation's order requests: the offer's setupFields (GET /v1/price-list), such as apps for a quick-commerce catalogue, cities for a dark-store map, a category, a platform, or a report's brand, competitors and cities. A list takes no more than was bought: the offer's allowance plus its add-on steps, or one per unit bought. Replaces the choices in force (every version is kept); staff read them to fulfil the request. Refused (catalogue_refused) once the request is fulfilled or declined. Never charged.",
        "tags": [
          "Plans"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Order request",
                      "additionalProperties": false,
                      "required": [
                        "reference",
                        "kind",
                        "offerKey",
                        "offerVersion",
                        "offerName",
                        "addOns",
                        "quantity",
                        "billing",
                        "note",
                        "status",
                        "statusNote",
                        "statusAt",
                        "createdAt",
                        "paidAt",
                        "paymentOrderId",
                        "setup",
                        "deliveries"
                      ],
                      "properties": {
                        "reference": {
                          "type": "string",
                          "pattern": "^OR-[0-9]{6,}$",
                          "examples": [
                            "OR-000001"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "pilot",
                            "order"
                          ]
                        },
                        "offerKey": {
                          "type": "string"
                        },
                        "offerVersion": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "offerName": {
                          "type": "string"
                        },
                        "addOns": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "key",
                              "quantity"
                            ],
                            "properties": {
                              "key": {
                                "type": "string",
                                "pattern": "^[a-z][a-zA-Z0-9_]{0,40}$",
                                "description": "One of the offer’s addOns keys (cities, darkStores, ...)."
                              },
                              "quantity": {
                                "type": "integer",
                                "minimum": 1,
                                "maximum": 100
                              }
                            }
                          }
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "billing": {
                          "type": "string",
                          "enum": [
                            "one_off",
                            "month",
                            "year"
                          ]
                        },
                        "note": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "paid",
                            "fulfilled",
                            "declined"
                          ],
                          "description": "received, then paid (a basket checkout) or in_review; fulfilled when Rewalto has delivered it (or entitled the pilot), declined otherwise."
                        },
                        "statusNote": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "statusAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "paidAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "When its basket was paid; null when not paid online."
                        },
                        "paymentOrderId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid",
                          "description": "The basket order it was paid with (the paid value the payment page returns to), or null."
                        },
                        "setup": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "description": "The buyer’s choices in force (POST /v1/order-requests/{reference}/setup), or null.",
                          "additionalProperties": false,
                          "required": [
                            "choices",
                            "note",
                            "setAt"
                          ],
                          "properties": {
                            "choices": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "note": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "setAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        },
                        "deliveries": {
                          "type": "array",
                          "description": "Files Rewalto delivered, ready to download: POST /v1/order-requests/{reference}/deliveries/{downloadId}/link.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "downloadId",
                              "label",
                              "kind",
                              "fileName",
                              "bytes",
                              "readyAt"
                            ],
                            "properties": {
                              "downloadId": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "label": {
                                "type": "string"
                              },
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "file",
                                  "report"
                                ]
                              },
                              "fileName": {
                                "type": "string"
                              },
                              "bytes": {
                                "type": "integer",
                                "minimum": 1
                              },
                              "readyAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `catalogue_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^OR-[0-9]{6,}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "choices"
                ],
                "properties": {
                  "choices": {
                    "type": "object",
                    "description": "The offer’s setupFields: a text (brand: \"Amul\") or a list (apps: [\"blinkit\"]), no more than was bought. Replaces the choices in force.",
                    "additionalProperties": true
                  },
                  "note": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/plan-entitlement": {
      "get": {
        "operationId": "getPlanEntitlement",
        "summary": "The organisation’s brand plan",
        "description": "The brand plan (or its free 4-week pilot) the organisation holds now, or null. With one, the dashboard reads full rows at no credit cost; without one, a credit-spending call made from the dashboard is refused with 402 plan_required (D-1966: the dashboard spends no credits). Never charged.",
        "tags": [
          "Plans"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Plan entitlement",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "description": "The brand plan (or pilot) in force, or null. With one, the dashboard shows full rows at no credit cost.",
                      "additionalProperties": false,
                      "required": [
                        "offerKey",
                        "basis",
                        "startsAt",
                        "endsAt"
                      ],
                      "properties": {
                        "offerKey": {
                          "type": "string",
                          "examples": [
                            "brand_starter"
                          ]
                        },
                        "basis": {
                          "type": "string",
                          "enum": [
                            "pilot",
                            "paid"
                          ]
                        },
                        "startsAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "endsAt": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/plans": {
      "get": {
        "operationId": "listPlans",
        "summary": "List plans and prices",
        "description": "The price list in force (D-1966, C-034; 1 credit costs one rupee at the entry price): the free monthly credits, the paid monthly plans and the top-up, each at its current price version, in display order. Prices are integer paise (hundredths of a rupee); a price change is a new version, never an edit. pricePaise is the price before GST; GST is added at checkout where it applies. Credits are spent only through the API, MCP and CLI; the dashboard spends none. Brand plans, packs and reports are in GET /v1/price-list. Read prices from here rather than writing them into a page or a payment set-up. Public and free.",
        "tags": [
          "Plans"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Plans",
                  "description": "The price list in force: every tier at its current version, in display order.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Tiers",
                      "description": "The tiers, by sortOrder.",
                      "items": {
                        "type": "object",
                        "title": "Plan tier",
                        "description": "One tier of the price list, at the version in force.",
                        "additionalProperties": false,
                        "required": [
                          "tierKey",
                          "version",
                          "kind",
                          "name",
                          "pricePaise",
                          "credits",
                          "period",
                          "sortOrder",
                          "minCredits"
                        ],
                        "properties": {
                          "tierKey": {
                            "type": "string",
                            "title": "Tier",
                            "description": "The tier key: free, starter, growth, scale or top_up (others may be added).",
                            "examples": [
                              "starter"
                            ],
                            "pattern": "^[a-z][a-z0-9_]{1,30}$"
                          },
                          "version": {
                            "type": "integer",
                            "minimum": 1,
                            "title": "Version",
                            "description": "The tier price version in force. A price change is a new version.",
                            "examples": [
                              1
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "free",
                              "plan",
                              "top_up"
                            ],
                            "title": "Kind",
                            "description": "free: the monthly free allowance. plan: a paid monthly plan. top_up: credits bought one at a time.",
                            "examples": [
                              "plan"
                            ]
                          },
                          "name": {
                            "type": "string",
                            "title": "Name",
                            "description": "The tier name to show.",
                            "examples": [
                              "Starter"
                            ]
                          },
                          "pricePaise": {
                            "type": "integer",
                            "minimum": 0,
                            "title": "Price (paise)",
                            "description": "The price in integer paise (hundredths of a rupee). 0 for the free allowance; for the top-up, the price of one credit. pricePaise is the price before GST; GST is added at checkout where it applies.",
                            "examples": [
                              149900
                            ]
                          },
                          "credits": {
                            "type": "integer",
                            "minimum": 1,
                            "title": "Credits",
                            "description": "Credits the price buys: each month for free and plan tiers; 1 per top-up unit.",
                            "examples": [
                              1500
                            ]
                          },
                          "period": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "month",
                              null
                            ],
                            "title": "Period",
                            "description": "month for the free allowance and plans; null for the top-up (a one-off purchase).",
                            "examples": [
                              "month"
                            ]
                          },
                          "sortOrder": {
                            "type": "integer",
                            "minimum": 0,
                            "title": "Order",
                            "description": "Display order on a price list, smallest first.",
                            "examples": [
                              1
                            ]
                          },
                          "minCredits": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "minimum": 1,
                            "title": "Minimum credits",
                            "description": "The fewest credits one purchase of this tier may buy: 1,000 for the top-up (D-1966; 5,000 before contract 0.98.0), checked when an order is made (POST /v1/billing/orders); null for other tiers. Sent from contract 0.39.0.",
                            "examples": [
                              1000
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/price-list": {
      "get": {
        "operationId": "getPriceList",
        "summary": "The whole price list",
        "description": "Everything Rewalto sells, at the prices in force (D-1966): the credit ladder for the API, MCP and CLI (exactly GET /v1/plans; 1 credit costs one rupee at the entry price), and every other offer: the free account, enterprise credits, monthly brand plans with their add-ons, dataset packs and reports. Integer paise (hundredths of a rupee), excluding GST (gstRateBp is added at checkout for customers in India). Prices are data: a change is a new version, never an edit. Brand plans, packs and reports are ordered with POST /v1/order-requests and fulfilled by hand for now. Public and free; read prices from here rather than writing them into a page.",
        "tags": [
          "Plans"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Price list",
                  "description": "The whole catalogue in force (D-1966): credits for the API, MCP and CLI, brand plans with add-ons, dataset packs and reports. Integer paise, excluding GST.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "currency",
                        "gstExcluded",
                        "gstRateBp",
                        "creditPricePaise",
                        "minTopUpCredits",
                        "credits",
                        "offers"
                      ],
                      "properties": {
                        "currency": {
                          "type": "string",
                          "enum": [
                            "INR"
                          ],
                          "title": "Currency"
                        },
                        "gstExcluded": {
                          "type": "boolean",
                          "enum": [
                            true
                          ],
                          "title": "GST excluded",
                          "description": "Every price excludes GST."
                        },
                        "gstRateBp": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "GST rate (basis points)",
                          "description": "Added at checkout for customers in India (1800 = 18%).",
                          "examples": [
                            1800
                          ]
                        },
                        "creditPricePaise": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "One credit (paise)",
                          "description": "The price of one credit at the entry price, in paise (D-1966).",
                          "examples": [
                            100
                          ]
                        },
                        "minTopUpCredits": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Smallest top-up",
                          "description": "The fewest credits one top-up buys (1,000).",
                          "examples": [
                            1000
                          ]
                        },
                        "credits": {
                          "type": "array",
                          "title": "Credit plans",
                          "description": "The credit ladder, exactly as GET /v1/plans. Credits are spent only through the API, MCP and CLI; the dashboard spends none.",
                          "items": {
                            "type": "object",
                            "title": "Plan tier",
                            "description": "One tier of the price list, at the version in force.",
                            "additionalProperties": false,
                            "required": [
                              "tierKey",
                              "version",
                              "kind",
                              "name",
                              "pricePaise",
                              "credits",
                              "period",
                              "sortOrder",
                              "minCredits"
                            ],
                            "properties": {
                              "tierKey": {
                                "type": "string",
                                "title": "Tier",
                                "description": "The tier key: free, starter, growth, scale or top_up (others may be added).",
                                "examples": [
                                  "starter"
                                ],
                                "pattern": "^[a-z][a-z0-9_]{1,30}$"
                              },
                              "version": {
                                "type": "integer",
                                "minimum": 1,
                                "title": "Version",
                                "description": "The tier price version in force. A price change is a new version.",
                                "examples": [
                                  1
                                ]
                              },
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "free",
                                  "plan",
                                  "top_up"
                                ],
                                "title": "Kind",
                                "description": "free: the monthly free allowance. plan: a paid monthly plan. top_up: credits bought one at a time.",
                                "examples": [
                                  "plan"
                                ]
                              },
                              "name": {
                                "type": "string",
                                "title": "Name",
                                "description": "The tier name to show.",
                                "examples": [
                                  "Starter"
                                ]
                              },
                              "pricePaise": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Price (paise)",
                                "description": "The price in integer paise (hundredths of a rupee). 0 for the free allowance; for the top-up, the price of one credit. pricePaise is the price before GST; GST is added at checkout where it applies.",
                                "examples": [
                                  149900
                                ]
                              },
                              "credits": {
                                "type": "integer",
                                "minimum": 1,
                                "title": "Credits",
                                "description": "Credits the price buys: each month for free and plan tiers; 1 per top-up unit.",
                                "examples": [
                                  1500
                                ]
                              },
                              "period": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "enum": [
                                  "month",
                                  null
                                ],
                                "title": "Period",
                                "description": "month for the free allowance and plans; null for the top-up (a one-off purchase).",
                                "examples": [
                                  "month"
                                ]
                              },
                              "sortOrder": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Order",
                                "description": "Display order on a price list, smallest first.",
                                "examples": [
                                  1
                                ]
                              },
                              "minCredits": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 1,
                                "title": "Minimum credits",
                                "description": "The fewest credits one purchase of this tier may buy: 1,000 for the top-up (D-1966; 5,000 before contract 0.98.0), checked when an order is made (POST /v1/billing/orders); null for other tiers. Sent from contract 0.39.0.",
                                "examples": [
                                  1000
                                ]
                              }
                            }
                          }
                        },
                        "offers": {
                          "type": "array",
                          "title": "Offers",
                          "description": "Every other offer, by sortOrder.",
                          "items": {
                            "type": "object",
                            "title": "Offer",
                            "description": "One item of the catalogue at the version in force: a brand plan, an add-on, a dataset pack or a report.",
                            "additionalProperties": false,
                            "required": [
                              "offerKey",
                              "version",
                              "family",
                              "name",
                              "summary",
                              "pricePaise",
                              "priceFrom",
                              "billing",
                              "yearlyPricePaise",
                              "refreshMonthlyPaise",
                              "twiceDailyPercent",
                              "unit",
                              "features",
                              "addOns",
                              "repeatMonthlyPercent",
                              "pilot",
                              "orderable",
                              "setupFields",
                              "sortOrder"
                            ],
                            "properties": {
                              "offerKey": {
                                "type": "string",
                                "title": "Offer",
                                "description": "The offer key.",
                                "examples": [
                                  "brand_starter"
                                ],
                                "pattern": "^[a-z][a-z0-9_]{1,40}$"
                              },
                              "version": {
                                "type": "integer",
                                "minimum": 1,
                                "title": "Version",
                                "description": "The price version in force."
                              },
                              "family": {
                                "type": "string",
                                "enum": [
                                  "free",
                                  "enterprise",
                                  "brand_plan",
                                  "pack",
                                  "report"
                                ],
                                "title": "Family",
                                "description": "free: the free account. enterprise: credits on quote. brand_plan: a monthly brand plan. pack: a dataset pack. report: a report.",
                                "examples": [
                                  "brand_plan"
                                ]
                              },
                              "name": {
                                "type": "string",
                                "title": "Name",
                                "description": "The name to show.",
                                "examples": [
                                  "Brand Starter"
                                ]
                              },
                              "summary": {
                                "type": "string",
                                "title": "Summary",
                                "description": "One line on what it is.",
                                "examples": [
                                  "Watches, alerts and a weekly report."
                                ]
                              },
                              "pricePaise": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 0,
                                "title": "Price (paise)",
                                "description": "Integer paise (hundredths of a rupee) before GST; null when priced on quote.",
                                "examples": [
                                  999900
                                ]
                              },
                              "priceFrom": {
                                "type": "boolean",
                                "title": "From",
                                "description": "The price is a starting price (\"from\")."
                              },
                              "billing": {
                                "type": "string",
                                "enum": [
                                  "month",
                                  "one_off"
                                ],
                                "title": "Billing",
                                "description": "month: billed each month. one_off: paid once."
                              },
                              "yearlyPricePaise": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 0,
                                "title": "Yearly price (paise)",
                                "description": "A brand plan billed yearly; null when not offered.",
                                "examples": [
                                  9999000
                                ]
                              },
                              "refreshMonthlyPaise": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 0,
                                "title": "Daily refresh (paise a month)",
                                "description": "A dataset pack kept fresh daily, per month; null when not offered.",
                                "examples": [
                                  999900
                                ]
                              },
                              "twiceDailyPercent": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 0,
                                "title": "Twice daily (%)",
                                "description": "A brand plan read twice a day costs this percentage of its price more (50); null for other offers.",
                                "examples": [
                                  50
                                ]
                              },
                              "unit": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Unit",
                                "description": "What one unit is (\"per city\"); null when the price is for the whole offer.",
                                "examples": [
                                  "per city"
                                ]
                              },
                              "features": {
                                "type": "array",
                                "title": "Features",
                                "description": "What it includes, one line each.",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "addOns": {
                                "type": "array",
                                "title": "Add-ons",
                                "description": "Add-ons, keyed as the site’s calculator: a brand plan’s are per month, a report’s are paid with it. A step adds unit of the thing (50 products); a flag is on or off.",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": false,
                                  "required": [
                                    "key",
                                    "name",
                                    "pricePaise",
                                    "unit",
                                    "flag"
                                  ],
                                  "properties": {
                                    "key": {
                                      "type": "string",
                                      "pattern": "^[a-z][a-zA-Z0-9_]{0,40}$"
                                    },
                                    "name": {
                                      "type": "string"
                                    },
                                    "pricePaise": {
                                      "type": [
                                        "null",
                                        "integer"
                                      ],
                                      "minimum": 0
                                    },
                                    "unit": {
                                      "type": [
                                        "null",
                                        "integer"
                                      ],
                                      "minimum": 1
                                    },
                                    "flag": {
                                      "type": "boolean"
                                    }
                                  }
                                }
                              },
                              "repeatMonthlyPercent": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 0,
                                "title": "Monthly repeat (%)",
                                "description": "A report repeated monthly costs this percentage of its one-off price (60); null for other offers.",
                                "examples": [
                                  60
                                ]
                              },
                              "pilot": {
                                "type": "boolean",
                                "title": "Pilot",
                                "description": "A brand plan that starts with the free 4-week pilot, run by hand."
                              },
                              "setupFields": {
                                "type": "array",
                                "title": "Setup",
                                "description": "What the buyer chooses once it is bought (POST /v1/order-requests/{reference}/setup): a text (brand, category, platform) or a list (apps, cities, competitors, keywords, categories). max is the list size for one unit with no add-ons; perQuantity lists take one per unit bought (one app per app bought); each add-on step adds one. null max for a text.",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": false,
                                  "required": [
                                    "key",
                                    "kind",
                                    "max",
                                    "perQuantity"
                                  ],
                                  "properties": {
                                    "key": {
                                      "type": "string",
                                      "examples": [
                                        "apps"
                                      ]
                                    },
                                    "kind": {
                                      "type": "string",
                                      "enum": [
                                        "text",
                                        "list"
                                      ]
                                    },
                                    "max": {
                                      "type": [
                                        "null",
                                        "integer"
                                      ],
                                      "minimum": 1
                                    },
                                    "perQuantity": {
                                      "type": "boolean"
                                    }
                                  }
                                }
                              },
                              "orderable": {
                                "type": "boolean",
                                "title": "Orderable",
                                "description": "Can be asked for with POST /v1/order-requests and bought with POST /v1/billing/basket (brand plans, packs and reports not priced on quote)."
                              },
                              "sortOrder": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Order",
                                "description": "Display order, smallest first."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/problem-reports": {
      "post": {
        "operationId": "createProblemReport",
        "summary": "Report a problem with a delivered row",
        "description": "Reports one row Rewalto delivered to your organisation: a listing (from /v1/data/listings or /v1/data/listings/search) or an observation (from /v1/data/observations, with its `evidence.sha256`), with a category and an optional note. Only a row one of your organisation’s own reads delivered can be reported; anything else is `not_found`. Rows read before problem reporting started cannot be reported. Free. Answers a receipt: the reference (PR-000123) and the status `received`. Reporting a row that already has an open report returns that report (`duplicate: true`). Staff review it; a confirmed problem refunds the read that delivered the row, through the existing refund and its rules. At most 50 reports a day per organisation. Signed-in members only.",
        "tags": [
          "Problem reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "ProblemReportCreated",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "report",
                    "duplicate",
                    "message"
                  ],
                  "properties": {
                    "report": {
                      "title": "ProblemReport",
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "reference",
                        "status",
                        "rowKind",
                        "rowId",
                        "evidenceSha256",
                        "category",
                        "note",
                        "receiptId",
                        "createdAt",
                        "inReviewAt",
                        "resolvedAt",
                        "resolutionNote",
                        "refund"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "reference": {
                          "type": "string",
                          "pattern": "^PR-[0-9]{6,}$",
                          "description": "The receipt reference to quote, e.g. PR-000123."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "confirmed",
                            "rejected"
                          ],
                          "description": "received: recorded. in_review: staff are checking. confirmed: the problem is real (see refund). rejected: not a problem (see resolutionNote). Treat an unknown value as in progress."
                        },
                        "rowKind": {
                          "type": "string",
                          "enum": [
                            "listing",
                            "observation"
                          ]
                        },
                        "rowId": {
                          "type": "string"
                        },
                        "evidenceSha256": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "category": {
                          "type": "string",
                          "enum": [
                            "wrong_price",
                            "wrong_availability",
                            "wrong_product_details",
                            "broken_evidence",
                            "duplicate_row",
                            "other"
                          ]
                        },
                        "note": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "receiptId": {
                          "type": "string",
                          "description": "The read receipt (rcp_…) that delivered the row; a confirmed problem refunds it."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "inReviewAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "resolvedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "resolutionNote": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "refund": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": false,
                          "required": [
                            "status",
                            "credits",
                            "refundId",
                            "reason"
                          ],
                          "description": "Set when confirmed: what the refund of the receipt did. refunded: credits returned. already_refunded: the receipt was refunded before. refused: the refund rules refused it (reason). not_requested: confirmed without a refund.",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "refunded",
                                "already_refunded",
                                "refused",
                                "not_requested"
                              ]
                            },
                            "credits": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 0
                            },
                            "refundId": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "reason": {
                              "type": [
                                "null",
                                "string"
                              ]
                            }
                          }
                        }
                      }
                    },
                    "duplicate": {
                      "type": "boolean",
                      "description": "true: this row already has an open report from your organisation; that one is returned."
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "title": "ProblemReportCreate",
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "rowKind",
                  "rowId",
                  "category"
                ],
                "properties": {
                  "rowKind": {
                    "type": "string",
                    "enum": [
                      "listing",
                      "observation"
                    ],
                    "description": "listing: a row from GET /v1/data/listings or /v1/data/listings/search. observation: a row from GET /v1/data/observations."
                  },
                  "rowId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100,
                    "description": "The row’s `id` as delivered (an observation’s numeric id as a string)."
                  },
                  "evidenceSha256": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{64}$",
                    "description": "Observations: the row’s `evidence.sha256` as delivered. Leave it out only when the row came with no evidence (`evidence.sha256` null). Not allowed for listings."
                  },
                  "category": {
                    "type": "string",
                    "enum": [
                      "wrong_price",
                      "wrong_availability",
                      "wrong_product_details",
                      "broken_evidence",
                      "duplicate_row",
                      "other"
                    ]
                  },
                  "note": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000,
                    "description": "What is wrong, briefly."
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listProblemReports",
        "summary": "Your organisation’s problem reports",
        "description": "Your organisation’s problem reports, newest first, with status, resolution and refund.",
        "tags": [
          "Problem reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "ProblemReportList",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "description": "Newest first.",
                      "items": {
                        "title": "ProblemReport",
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "reference",
                          "status",
                          "rowKind",
                          "rowId",
                          "evidenceSha256",
                          "category",
                          "note",
                          "receiptId",
                          "createdAt",
                          "inReviewAt",
                          "resolvedAt",
                          "resolutionNote",
                          "refund"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reference": {
                            "type": "string",
                            "pattern": "^PR-[0-9]{6,}$",
                            "description": "The receipt reference to quote, e.g. PR-000123."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "received",
                              "in_review",
                              "confirmed",
                              "rejected"
                            ],
                            "description": "received: recorded. in_review: staff are checking. confirmed: the problem is real (see refund). rejected: not a problem (see resolutionNote). Treat an unknown value as in progress."
                          },
                          "rowKind": {
                            "type": "string",
                            "enum": [
                              "listing",
                              "observation"
                            ]
                          },
                          "rowId": {
                            "type": "string"
                          },
                          "evidenceSha256": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "category": {
                            "type": "string",
                            "enum": [
                              "wrong_price",
                              "wrong_availability",
                              "wrong_product_details",
                              "broken_evidence",
                              "duplicate_row",
                              "other"
                            ]
                          },
                          "note": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "receiptId": {
                            "type": "string",
                            "description": "The read receipt (rcp_…) that delivered the row; a confirmed problem refunds it."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "inReviewAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "resolvedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "resolutionNote": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "refund": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "additionalProperties": false,
                            "required": [
                              "status",
                              "credits",
                              "refundId",
                              "reason"
                            ],
                            "description": "Set when confirmed: what the refund of the receipt did. refunded: credits returned. already_refunded: the receipt was refunded before. refused: the refund rules refused it (reason). not_requested: confirmed without a refund.",
                            "properties": {
                              "status": {
                                "type": "string",
                                "enum": [
                                  "refunded",
                                  "already_refunded",
                                  "refused",
                                  "not_requested"
                                ]
                              },
                              "credits": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 0
                              },
                              "refundId": {
                                "type": [
                                  "null",
                                  "string"
                                ]
                              },
                              "reason": {
                                "type": [
                                  "null",
                                  "string"
                                ]
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([1-9]|[1-9][0-9]|100)$"
            },
            "description": "At most this many (1-100, default 50)."
          }
        ]
      }
    },
    "/v1/problem-reports/{reference}": {
      "get": {
        "operationId": "getProblemReport",
        "summary": "One of your organisation’s problem reports",
        "description": "One report by its reference. Another organisation’s answers `not_found`, never confirming it exists.",
        "tags": [
          "Problem reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "ProblemReportAnswer",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "report"
                  ],
                  "properties": {
                    "report": {
                      "title": "ProblemReport",
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "reference",
                        "status",
                        "rowKind",
                        "rowId",
                        "evidenceSha256",
                        "category",
                        "note",
                        "receiptId",
                        "createdAt",
                        "inReviewAt",
                        "resolvedAt",
                        "resolutionNote",
                        "refund"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "reference": {
                          "type": "string",
                          "pattern": "^PR-[0-9]{6,}$",
                          "description": "The receipt reference to quote, e.g. PR-000123."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "confirmed",
                            "rejected"
                          ],
                          "description": "received: recorded. in_review: staff are checking. confirmed: the problem is real (see refund). rejected: not a problem (see resolutionNote). Treat an unknown value as in progress."
                        },
                        "rowKind": {
                          "type": "string",
                          "enum": [
                            "listing",
                            "observation"
                          ]
                        },
                        "rowId": {
                          "type": "string"
                        },
                        "evidenceSha256": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "category": {
                          "type": "string",
                          "enum": [
                            "wrong_price",
                            "wrong_availability",
                            "wrong_product_details",
                            "broken_evidence",
                            "duplicate_row",
                            "other"
                          ]
                        },
                        "note": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "receiptId": {
                          "type": "string",
                          "description": "The read receipt (rcp_…) that delivered the row; a confirmed problem refunds it."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "inReviewAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "resolvedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "resolutionNote": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "refund": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": false,
                          "required": [
                            "status",
                            "credits",
                            "refundId",
                            "reason"
                          ],
                          "description": "Set when confirmed: what the refund of the receipt did. refunded: credits returned. already_refunded: the receipt was refunded before. refused: the refund rules refused it (reason). not_requested: confirmed without a refund.",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "refunded",
                                "already_refunded",
                                "refused",
                                "not_requested"
                              ]
                            },
                            "credits": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 0
                            },
                            "refundId": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "reason": {
                              "type": [
                                "null",
                                "string"
                              ]
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^PR-[0-9]{6,}$"
            }
          }
        ]
      }
    },
    "/v1/queries/interpret": {
      "post": {
        "operationId": "interpretQuery",
        "summary": "Read a typed question into the request it would make",
        "description": "Reads one typed question (at most 500 characters) and returns which feature answers it (`route`: data, fresh, watch, finder or request), the operation to call (`target`) and its fields under that operation’s own names, each marked `stated` or `inferred`. A retailer is only ever a slug from listRetailers and a place only a Core location id from the location lookup; what cannot be mapped is in `unresolved`, for the person to choose. Free: it never runs, quotes, charges or saves anything; call the target once the person confirms. When the reading is unavailable (switched off, the day’s model budget spent, no answer in time, or unsure) the answer is `route: null` with `fallback`: run the text as a plain search. Email addresses and phone numbers are removed from the text first. A session, an API key or an MCP sign-in (scope data:read); or anonymous with a Cloudflare Turnstile token, under Ask Walt’s per-IP limits (`rate_limited`, with `Retry-After`; a failed check is `forbidden`).",
        "tags": [
          "Data"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryInterpretResponse"
                },
                "example": {
                  "route": "data",
                  "target": "discoverListings",
                  "fields": {
                    "q": {
                      "value": "Amul butter",
                      "source": "stated"
                    },
                    "retailer": {
                      "value": "blinkit",
                      "source": "stated"
                    },
                    "location": {
                      "value": "IN:city:maharashtra:pune",
                      "label": "Pune",
                      "source": "stated"
                    }
                  },
                  "unresolved": [],
                  "alternatives": [
                    {
                      "route": "fresh",
                      "why": "Latest prices straight from the app, at the published rate"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryInterpretRequest"
              }
            }
          }
        }
      }
    },
    "/v1/quotes": {
      "post": {
        "operationId": "createQuote",
        "summary": "Price a request",
        "description": "What to price: a catalogue recipe, how many units of its data are wanted, and the extras to use. Add a cadence for a recurring report or watch to see the cost of each delivery and of a month. The organisation is taken from the credential, never from the body.",
        "tags": [
          "Quotes"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "cache-control": {
                "description": "Always `no-store`: the answer must not be cached.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                },
                "example": {
                  "id": "9b1d6e0a-4c3f-4f7e-8a21-5d0c7b9e1f42",
                  "mode": "published",
                  "status": "open",
                  "recipe": "commerce_product_page",
                  "unit": "page",
                  "units": 120,
                  "rateVersion": "c1.r1",
                  "extras": [
                    {
                      "key": "browser",
                      "credits": 1,
                      "perUnits": 1,
                      "multiplier": 1
                    }
                  ],
                  "lines": [
                    {
                      "recipe": "commerce_product_page",
                      "unit": "page",
                      "units": 120,
                      "base": {
                        "credits": 1,
                        "perUnits": 1
                      },
                      "extras": [
                        {
                          "key": "browser",
                          "credits": 1,
                          "perUnits": 1,
                          "multiplier": 1
                        }
                      ],
                      "credits": 240
                    }
                  ],
                  "ceiling": 240,
                  "expiresAt": "2026-10-15T10:30:00.000Z",
                  "createdAt": "2026-10-15T10:00:00.000Z",
                  "approvedAt": null,
                  "recurring": {
                    "cadence": "weekly",
                    "deliveriesPerMonth": 5,
                    "perDelivery": 240,
                    "perMonth": 1200,
                    "creditsAvailable": 1000,
                    "fitsPlan": false,
                    "notice": "A month of deliveries can cost up to 1200 credits and 1000 are left: it will not fit. A bigger plan is needed."
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `unknown_capability`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QuoteRequest"
              }
            }
          }
        }
      }
    },
    "/v1/quotes/{id}": {
      "get": {
        "operationId": "getQuote",
        "summary": "Read a quote",
        "description": "A quote of your organisation: the priced lines, the ceiling, and when it expires. Another organisation's quote is not found.",
        "tags": [
          "Quotes"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "cache-control": {
                "description": "Always `no-store`: the answer must not be cached.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Quote"
                },
                "example": {
                  "id": "9b1d6e0a-4c3f-4f7e-8a21-5d0c7b9e1f42",
                  "mode": "published",
                  "status": "open",
                  "recipe": "commerce_product_page",
                  "unit": "page",
                  "units": 120,
                  "rateVersion": "c1.r1",
                  "extras": [
                    {
                      "key": "browser",
                      "credits": 1,
                      "perUnits": 1,
                      "multiplier": 1
                    }
                  ],
                  "lines": [
                    {
                      "recipe": "commerce_product_page",
                      "unit": "page",
                      "units": 120,
                      "base": {
                        "credits": 1,
                        "perUnits": 1
                      },
                      "extras": [
                        {
                          "key": "browser",
                          "credits": 1,
                          "perUnits": 1,
                          "multiplier": 1
                        }
                      ],
                      "credits": 240
                    }
                  ],
                  "ceiling": 240,
                  "expiresAt": "2026-10-15T10:30:00.000Z",
                  "createdAt": "2026-10-15T10:00:00.000Z",
                  "approvedAt": null,
                  "recurring": {
                    "cadence": "weekly",
                    "deliveriesPerMonth": 5,
                    "perDelivery": 240,
                    "perMonth": 1200,
                    "creditsAvailable": 1000,
                    "fitsPlan": false,
                    "notice": "A month of deliveries can cost up to 1200 credits and 1000 are left: it will not fit. A bigger plan is needed."
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The quote id."
            }
          }
        ]
      }
    },
    "/v1/quotes/{id}/approve": {
      "post": {
        "operationId": "approveQuote",
        "summary": "Approve a quote",
        "description": "The quote after approval, and the credits held for the run: free credits first, then paid. Approving an expired or already approved quote, or one that is not yours, is refused.",
        "tags": [
          "Quotes"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "cache-control": {
                "description": "Always `no-store`: the answer must not be cached.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ApprovedQuote"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`\n- `unknown_capability`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `cost_changed`: retry advice `never`\n- `quote_already_approved`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "410": {
            "description": "Error. The `error.code` is one of:\n- `quote_expired`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The quote id."
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "title": "ApproveQuoteRequest",
                "description": "Optional. confirmedCeiling: the credits the person approving was shown and agreed to. When sent, the approval is refused with cost_changed unless it is exactly the quote’s ceiling, so an assistant cannot approve a cost the person did not see.",
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "confirmedCeiling": {
                    "type": "integer",
                    "minimum": 0
                  }
                },
                "examples": [
                  {
                    "confirmedCeiling": 12
                  }
                ]
              }
            }
          }
        }
      }
    },
    "/v1/reports": {
      "get": {
        "operationId": "listReports",
        "summary": "List your reports",
        "description": "Your organisation's report editions, newest first: what each covers, its files, and until when it can be downloaded (D-1764: 12 months). Every report the report tool makes is attached to the Rewalto organisation (C-017).",
        "tags": [
          "Reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Reports page",
                  "description": "Your organisation's report editions, newest first.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "title": "Report edition",
                        "description": "One report edition attached to your organisation: what it covers, its files, and until when it can be downloaded (D-1764: 12 months).",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "kind",
                          "title",
                          "subject",
                          "window",
                          "forOrganisationId",
                          "requestedBy",
                          "formats",
                          "files",
                          "fileCount",
                          "totalBytes",
                          "manifestSha256",
                          "createdAt",
                          "expiresAt",
                          "state",
                          "supersededBy",
                          "supersededAt"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "title": "Id",
                            "description": "The edition id.",
                            "examples": [
                              "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                            ],
                            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                          },
                          "kind": {
                            "type": "string",
                            "title": "Kind",
                            "description": "The report type.",
                            "examples": [
                              "brand_shelf"
                            ]
                          },
                          "title": {
                            "type": "string",
                            "title": "Title",
                            "description": "The report title.",
                            "examples": [
                              "The Love Co. — Shelf Watch report"
                            ]
                          },
                          "subject": {
                            "type": "object",
                            "title": "Subject",
                            "description": "What the report is about.",
                            "additionalProperties": false,
                            "required": [
                              "kind",
                              "name",
                              "slug"
                            ],
                            "properties": {
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "brand",
                                  "category",
                                  "retailer",
                                  "dataset"
                                ],
                                "title": "Kind",
                                "description": "brand, category, retailer or dataset.",
                                "examples": [
                                  "brand"
                                ]
                              },
                              "name": {
                                "type": "string",
                                "title": "Name",
                                "description": "The subject as the report names it.",
                                "examples": [
                                  "The Love Co."
                                ]
                              },
                              "slug": {
                                "type": "string",
                                "title": "Slug",
                                "description": "A short URL-safe name.",
                                "examples": [
                                  "the-love-co"
                                ]
                              }
                            }
                          },
                          "window": {
                            "type": "object",
                            "title": "Window",
                            "description": "The data window, IST dates, inclusive.",
                            "additionalProperties": false,
                            "required": [
                              "from",
                              "to"
                            ],
                            "properties": {
                              "from": {
                                "type": "string",
                                "title": "From",
                                "description": "First day.",
                                "examples": [
                                  "2026-08-26"
                                ],
                                "format": "date"
                              },
                              "to": {
                                "type": "string",
                                "title": "To",
                                "description": "Last day.",
                                "examples": [
                                  "2026-10-16"
                                ],
                                "format": "date"
                              }
                            }
                          },
                          "forOrganisationId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Made for",
                            "description": "On the Rewalto organisation's copy of a report made for a customer: that customer's organisation id (C-017). Null otherwise.",
                            "examples": [
                              "3f2a8c1e-6b4d-4e8a-9c0f-1d7b5a2e9f10"
                            ],
                            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                          },
                          "requestedBy": {
                            "type": "string",
                            "title": "Requested by",
                            "description": "Who asked for it.",
                            "examples": [
                              "vm@rewalto.com"
                            ]
                          },
                          "formats": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "markdown",
                                "html",
                                "json",
                                "jsonl",
                                "csv",
                                "text",
                                "pdf"
                              ],
                              "title": "Format",
                              "description": "A file format present.",
                              "examples": [
                                "markdown"
                              ]
                            },
                            "title": "Formats",
                            "description": "The formats among its files.",
                            "examples": [
                              [
                                "csv",
                                "html",
                                "markdown"
                              ]
                            ]
                          },
                          "files": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "title": "Report file",
                              "description": "One file of a report edition.",
                              "additionalProperties": false,
                              "required": [
                                "name",
                                "format",
                                "role",
                                "contentType",
                                "bytes",
                                "sha256"
                              ],
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "title": "Name",
                                  "description": "The file, relative to the edition (e.g. summary.md, sections/listings.csv).",
                                  "examples": [
                                    "summary.md"
                                  ],
                                  "pattern": "^[A-Za-z0-9_][A-Za-z0-9._-]*(/[A-Za-z0-9_][A-Za-z0-9._-]*)*$"
                                },
                                "format": {
                                  "type": "string",
                                  "enum": [
                                    "markdown",
                                    "html",
                                    "json",
                                    "jsonl",
                                    "csv",
                                    "text",
                                    "pdf"
                                  ],
                                  "title": "Format",
                                  "description": "markdown, html, json, jsonl, csv, text (plain text: .txt, .log, .sql) or pdf.",
                                  "examples": [
                                    "markdown"
                                  ]
                                },
                                "role": {
                                  "type": "string",
                                  "enum": [
                                    "report",
                                    "data"
                                  ],
                                  "title": "Role",
                                  "description": "report: a readable report; data: a table or data file.",
                                  "examples": [
                                    "report"
                                  ]
                                },
                                "contentType": {
                                  "type": "string",
                                  "title": "Content type",
                                  "description": "The MIME type the link serves.",
                                  "examples": [
                                    "text/markdown; charset=utf-8"
                                  ]
                                },
                                "bytes": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "Bytes",
                                  "description": "File size.",
                                  "examples": [
                                    32674
                                  ]
                                },
                                "sha256": {
                                  "type": "string",
                                  "title": "SHA-256",
                                  "description": "Of the file; check the download against it.",
                                  "examples": [
                                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                                  ],
                                  "pattern": "^[0-9a-f]{64}$"
                                }
                              }
                            },
                            "title": "Files",
                            "description": "Every file you may download, in display order: the primary report first, then the other readable reports, then supporting data by name. Internal files are never listed here (D-1830 D-a)."
                          },
                          "fileCount": {
                            "type": "integer",
                            "minimum": 0,
                            "title": "Files",
                            "description": "How many files you may download (the length of files).",
                            "examples": [
                              84
                            ]
                          },
                          "totalBytes": {
                            "type": "integer",
                            "minimum": 0,
                            "title": "Bytes",
                            "description": "The files you may download, together.",
                            "examples": [
                              4500000
                            ]
                          },
                          "manifestSha256": {
                            "type": "string",
                            "title": "Manifest SHA-256",
                            "description": "SHA-256 of the sorted \"name sha256 bytes\" lines of every file: one fingerprint for the whole edition.",
                            "examples": [
                              "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
                            ],
                            "pattern": "^[0-9a-f]{64}$"
                          },
                          "createdAt": {
                            "type": "string",
                            "title": "Created at",
                            "description": "When the report was made.",
                            "examples": [
                              "2026-10-17T12:00:00Z"
                            ],
                            "format": "date-time"
                          },
                          "expiresAt": {
                            "type": "string",
                            "title": "Expires at",
                            "description": "Files are deleted after this (12 months, D-1764).",
                            "examples": [
                              "2027-10-17T12:00:00Z"
                            ],
                            "format": "date-time"
                          },
                          "state": {
                            "type": "string",
                            "enum": [
                              "available",
                              "superseded",
                              "expired"
                            ],
                            "title": "State",
                            "description": "available; superseded when a corrected edition replaced it (its customer files stay downloadable until expiresAt); expired after expiresAt.",
                            "examples": [
                              "available"
                            ]
                          },
                          "supersededBy": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Superseded by",
                            "description": "The corrected edition that replaced this one (GET /v1/reports/{id}); null while this is the current edition.",
                            "examples": [
                              "3f2a8c1e-6b4d-4e8a-9c0f-1d7b5a2e9f10"
                            ],
                            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                          },
                          "supersededAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Superseded at",
                            "description": "When the correction replaced this edition; null while this is the current edition.",
                            "examples": [
                              "2026-10-20T12:00:00Z"
                            ],
                            "format": "date-time"
                          }
                        }
                      },
                      "title": "Reports",
                      "description": "Newest first."
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            20
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Pass as cursor for the next page; null at the end.",
                          "examples": [
                            "eyJ0Ijoi"
                          ],
                          "pattern": "^[A-Za-z0-9_-]{1,200}$"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Limit",
              "examples": [
                "20"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many, 1 to 100 (default 20)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNyJ9"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,200}$"
            },
            "description": "page.nextCursor from the previous page."
          },
          {
            "name": "includeSuperseded",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Include superseded",
              "examples": [
                "true"
              ],
              "pattern": "^(true|false)$"
            },
            "description": "true to also list editions a corrected edition replaced (history); default false."
          }
        ]
      }
    },
    "/v1/reports/archive": {
      "get": {
        "operationId": "listReportArchive",
        "summary": "List the files behind your reports",
        "description": "Every file of your organisation's report editions as one list: the readable reports and their supporting files (tables, data, JSON), newest edition first, with name, format, size, checksum and the report each belongs to. Filter by report, role, format or words. Expired editions are listed and flagged, never hidden. Free. A signed link to one file: POST /v1/reports/{id}/link with file.",
        "tags": [
          "Reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportArchivePage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "editionId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Report",
              "examples": [
                "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
              ],
              "format": "uuid"
            },
            "description": "Only the files of this report edition."
          },
          {
            "name": "role",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Role",
              "examples": [
                "data"
              ],
              "pattern": "^(report|data)$"
            },
            "description": "report: a readable report; data: a supporting file."
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Format",
              "examples": [
                "csv"
              ],
              "pattern": "^(markdown|html|json|jsonl|csv|text|pdf)$"
            },
            "description": "Only this file format: markdown, html, json, jsonl, csv, text or pdf."
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Words",
              "examples": [
                "prices"
              ],
              "minLength": 1,
              "maxLength": 100
            },
            "description": "Only files whose name, or whose report title or subject, contains these words."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "50"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "1 to 200. Default 50."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNCJ9"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,600}$"
            },
            "description": "The nextCursor of the previous page, with the same filters."
          }
        ]
      }
    },
    "/v1/reports/data/packages": {
      "post": {
        "operationId": "buildReportDataPackage",
        "summary": "Build the data package of an approved quote",
        "description": "Builds one frozen snapshot of the records an approved report data quote covers, charging the records delivered and never above the quote (D-1559). Answers 202 with the manifest: treat any state but ready as still building and watch GET /v1/reports/data/packages/{id} until ready (today the package is built within this request, so it is usually ready at once). Repeating it with the same idempotency key returns the same package; one package per quote. Staff only (report_operator), from the Rewalto organisation (D-1763).",
        "tags": [
          "Report data"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportDataPackageAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`\n- `over_quote`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `idempotency_conflict`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "410": {
            "description": "Error. The `error.code` is one of:\n- `quote_expired`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportDataPackageRequest"
              }
            }
          }
        }
      }
    },
    "/v1/reports/data/packages/{id}": {
      "get": {
        "operationId": "getReportDataPackage",
        "summary": "Read a data package manifest",
        "description": "The manifest: per dataset its record count, fields with units, coverage, freshness, source context, limitations and SHA-256. Free.",
        "tags": [
          "Report data"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportDataPackageAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ]
      }
    },
    "/v1/reports/data/packages/{id}/records": {
      "get": {
        "operationId": "listReportDataRecords",
        "summary": "Read one page of a data package",
        "description": "Records of one dataset in package order, with completeness on every page. Free (the package is paid for). Read every dataset to complete: true before treating a report as complete.",
        "tags": [
          "Report data"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportDataRecordsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `package_not_ready`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "410": {
            "description": "Error. The `error.code` is one of:\n- `download_expired`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          },
          {
            "name": "dataset",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Dataset",
              "examples": [
                "observations"
              ],
              "pattern": "^[a-z_]{1,40}$"
            },
            "description": "Which dataset of the package: listings, observations, rating_changes, banner_placements, brand_mentions, promo_emails, storefront_promos, ad_creatives, brands, retailers. One not in the package is refused (invalid_request)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJwIjoxfQ"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,400}$"
            },
            "description": "page.nextCursor from the previous page."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Limit",
              "examples": [
                "1000"
              ],
              "pattern": "^[1-9][0-9]{0,3}$"
            },
            "description": "Records per page, 1 to 1000 (default 1000)."
          }
        ]
      }
    },
    "/v1/reports/data/quotes": {
      "post": {
        "operationId": "quoteReportData",
        "summary": "Count and price the data for a report",
        "description": "Checks a report data request, counts what it matches (free) and prices it at the published rates as a quote (C-012; no report fee, D-1760). Approve it with POST /v1/quotes/{id}/approve before building the package. Nothing is delivered or charged here. Staff only (report_operator), from the Rewalto organisation (D-1763: the house pays).",
        "tags": [
          "Report data"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportDataQuoteAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportDataRequest"
              }
            }
          }
        }
      }
    },
    "/v1/reports/schedules": {
      "post": {
        "operationId": "createReportSchedule",
        "summary": "Create a scheduled report (draft)",
        "description": "A draft with its estimated cost per delivery and per month; it runs nothing until activated.",
        "tags": [
          "Report schedules"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportScheduleAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `idempotency_conflict`: retry advice `never`\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportScheduleCreate"
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listReportSchedules",
        "summary": "List scheduled reports",
        "description": "The organisation's schedules, newest first, cancelled ones last.",
        "tags": [
          "Report schedules"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportSchedulesPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Limit",
              "examples": [
                "20"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many, 1 to 100 (default 20)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0Ijoi"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,400}$"
            },
            "description": "page.nextCursor from the previous page."
          }
        ]
      }
    },
    "/v1/reports/schedules/{id}": {
      "get": {
        "operationId": "getReportSchedule",
        "summary": "Read a scheduled report",
        "description": "Its settings, cost, confirmation, next delivery, last run and saved editions.",
        "tags": [
          "Report schedules"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportScheduleAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ]
      },
      "patch": {
        "operationId": "updateReportSchedule",
        "summary": "Change a scheduled report",
        "description": "A change to what or when it reads (data, window, frequency) re-estimates the cost and returns an active schedule to needs_confirmation (it runs nothing until confirmed again). Other changes keep its state. A cancelled schedule cannot be changed.",
        "tags": [
          "Report schedules"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportScheduleAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportScheduleUpdate"
              }
            }
          }
        }
      }
    },
    "/v1/reports/schedules/{id}/activate": {
      "post": {
        "operationId": "activateReportSchedule",
        "summary": "Confirm the cost and activate",
        "description": "Confirms the current cost (re-estimated now at the published rates; the numbers sent must equal it, otherwise cost_changed with the new ones) and starts deliveries. Also refused (invalid_request) when the renderer is not on the allow-list (D-1777) or the cost is above the spending limit, and (credits_exhausted) when the month does not fit the remaining credits, with the bigger-plan message. Each run then quotes its own window and is skipped, never part-charged, if it is above a spending limit or the credits cannot hold it.",
        "tags": [
          "Report schedules"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportScheduleAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `cost_changed`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportScheduleActivate"
              }
            }
          }
        }
      }
    },
    "/v1/reports/schedules/{id}/cancel": {
      "post": {
        "operationId": "cancelReportSchedule",
        "summary": "Cancel a scheduled report",
        "description": "Ends the schedule for good. Saved editions stay in the report history.",
        "tags": [
          "Report schedules"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportScheduleAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ]
      }
    },
    "/v1/reports/schedules/{id}/pause": {
      "post": {
        "operationId": "pauseReportSchedule",
        "summary": "Pause a scheduled report",
        "description": "Stops deliveries until resumed; nothing runs or is charged while paused.",
        "tags": [
          "Report schedules"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportScheduleAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ]
      }
    },
    "/v1/reports/schedules/{id}/resume": {
      "post": {
        "operationId": "resumeReportSchedule",
        "summary": "Resume a scheduled report",
        "description": "Starts deliveries again. A cost above the confirmed one, or a renderer no longer on the allow-list, needs confirming first (needs_confirmation).",
        "tags": [
          "Report schedules"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportScheduleAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ]
      }
    },
    "/v1/reports/schedules/{id}/runs": {
      "get": {
        "operationId": "listReportRuns",
        "summary": "List a scheduled report's runs",
        "description": "Each delivery: state, skip reason or failure stage, credits quoted and charged, and the saved edition. Until the renderer runner ships (T3e), a run that got its data stops in state rendering with its dataPackageId: data ready, renderer pending.",
        "tags": [
          "Report schedules"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportRunsPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Limit",
              "examples": [
                "20"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many, 1 to 100 (default 20)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0Ijoi"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,400}$"
            },
            "description": "page.nextCursor from the previous page."
          }
        ]
      }
    },
    "/v1/reports/uploads": {
      "post": {
        "operationId": "startReportUpload",
        "summary": "Start saving a report to the account",
        "description": "Declares a frontend-made report and its files and returns a signed PUT for each, into the private bucket under customer-reports/. The owner is the session's server-verified active organisation (the body names none). The storage terms are returned and confirmed separately from data reads; while staff only, storage is free with no limits (D-1775). Repeating it with the same idempotency key and body returns the same upload (with fresh links); the same key with a different body is idempotency_conflict. Staff only (report_operator).",
        "tags": [
          "Report uploads"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportUploadAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `idempotency_conflict`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportUploadRequest"
              }
            }
          }
        }
      }
    },
    "/v1/reports/uploads/{id}": {
      "get": {
        "operationId": "getReportUpload",
        "summary": "Read an upload",
        "description": "Its state, which files were received, and the edition once saved. While awaiting files it carries a fresh signed PUT for each file not yet received.",
        "tags": [
          "Report uploads"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportUploadAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ]
      }
    },
    "/v1/reports/uploads/{id}/finalise": {
      "post": {
        "operationId": "finaliseReportUpload",
        "summary": "Save the uploaded report",
        "description": "Checks every file in the store itself (size and SHA-256) and saves the report under the upload's organisation (C-017): it is then listed by GET /v1/reports with its detail and links. A file not yet in the store is upload_not_ready (nothing recorded; PUT it and finalise again). A file whose size or SHA-256 differs ends the upload as failed (sha256_mismatch or size_mismatch), and nothing is saved. Safe to repeat: a saved upload answers the same edition. The idempotency key must be the upload's own. Staff only (report_operator).",
        "tags": [
          "Report uploads"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ReportUploadAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `idempotency_conflict`: retry advice `never`\n- `upload_not_ready`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The resource id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReportUploadFinaliseRequest"
              }
            }
          }
        }
      }
    },
    "/v1/reports/{id}": {
      "get": {
        "operationId": "getReport",
        "summary": "Read a report",
        "description": "One report edition of your organisation, with its files. Another organisation's is not found.",
        "tags": [
          "Reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Report answer",
                  "description": "One report edition.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Report edition",
                      "description": "One report edition attached to your organisation: what it covers, its files, and until when it can be downloaded (D-1764: 12 months).",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "title",
                        "subject",
                        "window",
                        "forOrganisationId",
                        "requestedBy",
                        "formats",
                        "files",
                        "fileCount",
                        "totalBytes",
                        "manifestSha256",
                        "createdAt",
                        "expiresAt",
                        "state",
                        "supersededBy",
                        "supersededAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The edition id.",
                          "examples": [
                            "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                          ],
                          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                        },
                        "kind": {
                          "type": "string",
                          "title": "Kind",
                          "description": "The report type.",
                          "examples": [
                            "brand_shelf"
                          ]
                        },
                        "title": {
                          "type": "string",
                          "title": "Title",
                          "description": "The report title.",
                          "examples": [
                            "The Love Co. — Shelf Watch report"
                          ]
                        },
                        "subject": {
                          "type": "object",
                          "title": "Subject",
                          "description": "What the report is about.",
                          "additionalProperties": false,
                          "required": [
                            "kind",
                            "name",
                            "slug"
                          ],
                          "properties": {
                            "kind": {
                              "type": "string",
                              "enum": [
                                "brand",
                                "category",
                                "retailer",
                                "dataset"
                              ],
                              "title": "Kind",
                              "description": "brand, category, retailer or dataset.",
                              "examples": [
                                "brand"
                              ]
                            },
                            "name": {
                              "type": "string",
                              "title": "Name",
                              "description": "The subject as the report names it.",
                              "examples": [
                                "The Love Co."
                              ]
                            },
                            "slug": {
                              "type": "string",
                              "title": "Slug",
                              "description": "A short URL-safe name.",
                              "examples": [
                                "the-love-co"
                              ]
                            }
                          }
                        },
                        "window": {
                          "type": "object",
                          "title": "Window",
                          "description": "The data window, IST dates, inclusive.",
                          "additionalProperties": false,
                          "required": [
                            "from",
                            "to"
                          ],
                          "properties": {
                            "from": {
                              "type": "string",
                              "title": "From",
                              "description": "First day.",
                              "examples": [
                                "2026-08-26"
                              ],
                              "format": "date"
                            },
                            "to": {
                              "type": "string",
                              "title": "To",
                              "description": "Last day.",
                              "examples": [
                                "2026-10-16"
                              ],
                              "format": "date"
                            }
                          }
                        },
                        "forOrganisationId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Made for",
                          "description": "On the Rewalto organisation's copy of a report made for a customer: that customer's organisation id (C-017). Null otherwise.",
                          "examples": [
                            "3f2a8c1e-6b4d-4e8a-9c0f-1d7b5a2e9f10"
                          ],
                          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                        },
                        "requestedBy": {
                          "type": "string",
                          "title": "Requested by",
                          "description": "Who asked for it.",
                          "examples": [
                            "vm@rewalto.com"
                          ]
                        },
                        "formats": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "enum": [
                              "markdown",
                              "html",
                              "json",
                              "jsonl",
                              "csv",
                              "text",
                              "pdf"
                            ],
                            "title": "Format",
                            "description": "A file format present.",
                            "examples": [
                              "markdown"
                            ]
                          },
                          "title": "Formats",
                          "description": "The formats among its files.",
                          "examples": [
                            [
                              "csv",
                              "html",
                              "markdown"
                            ]
                          ]
                        },
                        "files": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "title": "Report file",
                            "description": "One file of a report edition.",
                            "additionalProperties": false,
                            "required": [
                              "name",
                              "format",
                              "role",
                              "contentType",
                              "bytes",
                              "sha256"
                            ],
                            "properties": {
                              "name": {
                                "type": "string",
                                "title": "Name",
                                "description": "The file, relative to the edition (e.g. summary.md, sections/listings.csv).",
                                "examples": [
                                  "summary.md"
                                ],
                                "pattern": "^[A-Za-z0-9_][A-Za-z0-9._-]*(/[A-Za-z0-9_][A-Za-z0-9._-]*)*$"
                              },
                              "format": {
                                "type": "string",
                                "enum": [
                                  "markdown",
                                  "html",
                                  "json",
                                  "jsonl",
                                  "csv",
                                  "text",
                                  "pdf"
                                ],
                                "title": "Format",
                                "description": "markdown, html, json, jsonl, csv, text (plain text: .txt, .log, .sql) or pdf.",
                                "examples": [
                                  "markdown"
                                ]
                              },
                              "role": {
                                "type": "string",
                                "enum": [
                                  "report",
                                  "data"
                                ],
                                "title": "Role",
                                "description": "report: a readable report; data: a table or data file.",
                                "examples": [
                                  "report"
                                ]
                              },
                              "contentType": {
                                "type": "string",
                                "title": "Content type",
                                "description": "The MIME type the link serves.",
                                "examples": [
                                  "text/markdown; charset=utf-8"
                                ]
                              },
                              "bytes": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Bytes",
                                "description": "File size.",
                                "examples": [
                                  32674
                                ]
                              },
                              "sha256": {
                                "type": "string",
                                "title": "SHA-256",
                                "description": "Of the file; check the download against it.",
                                "examples": [
                                  "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                                ],
                                "pattern": "^[0-9a-f]{64}$"
                              }
                            }
                          },
                          "title": "Files",
                          "description": "Every file you may download, in display order: the primary report first, then the other readable reports, then supporting data by name. Internal files are never listed here (D-1830 D-a)."
                        },
                        "fileCount": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Files",
                          "description": "How many files you may download (the length of files).",
                          "examples": [
                            84
                          ]
                        },
                        "totalBytes": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Bytes",
                          "description": "The files you may download, together.",
                          "examples": [
                            4500000
                          ]
                        },
                        "manifestSha256": {
                          "type": "string",
                          "title": "Manifest SHA-256",
                          "description": "SHA-256 of the sorted \"name sha256 bytes\" lines of every file: one fingerprint for the whole edition.",
                          "examples": [
                            "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
                          ],
                          "pattern": "^[0-9a-f]{64}$"
                        },
                        "createdAt": {
                          "type": "string",
                          "title": "Created at",
                          "description": "When the report was made.",
                          "examples": [
                            "2026-10-17T12:00:00Z"
                          ],
                          "format": "date-time"
                        },
                        "expiresAt": {
                          "type": "string",
                          "title": "Expires at",
                          "description": "Files are deleted after this (12 months, D-1764).",
                          "examples": [
                            "2027-10-17T12:00:00Z"
                          ],
                          "format": "date-time"
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "available",
                            "superseded",
                            "expired"
                          ],
                          "title": "State",
                          "description": "available; superseded when a corrected edition replaced it (its customer files stay downloadable until expiresAt); expired after expiresAt.",
                          "examples": [
                            "available"
                          ]
                        },
                        "supersededBy": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Superseded by",
                          "description": "The corrected edition that replaced this one (GET /v1/reports/{id}); null while this is the current edition.",
                          "examples": [
                            "3f2a8c1e-6b4d-4e8a-9c0f-1d7b5a2e9f10"
                          ],
                          "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                        },
                        "supersededAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Superseded at",
                          "description": "When the correction replaced this edition; null while this is the current edition.",
                          "examples": [
                            "2026-10-20T12:00:00Z"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The edition id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ]
      }
    },
    "/v1/reports/{id}/link": {
      "post": {
        "operationId": "getReportDownloadLink",
        "summary": "Get a download link for a report file",
        "description": "A signed link to one file of a report, valid 15 minutes (D-1764). Give format for the primary readable report in that format (markdown, html, json, pdf), or file for a file by name. Only files marked for customers can be linked (D-1830 D-a): an internal file answers `not_found` exactly as a file that does not exist, so its name is not confirmed. A superseded edition still links its customer files until it expires. Ask again, free, until the edition expires 12 months after it was made.",
        "tags": [
          "Reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Report download link",
                  "description": "A signed link to one report file, valid 15 minutes (D-1764). Ask again, free, until availableUntil.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Link",
                      "description": "The link and the file it opens.",
                      "additionalProperties": false,
                      "required": [
                        "url",
                        "expiresAt",
                        "availableUntil",
                        "name",
                        "format",
                        "contentType",
                        "bytes",
                        "sha256"
                      ],
                      "properties": {
                        "url": {
                          "type": "string",
                          "title": "Link",
                          "description": "Opens the file; works until expiresAt. Do not share it.",
                          "examples": [
                            "https://store.example/customer-reports/..."
                          ]
                        },
                        "expiresAt": {
                          "type": "string",
                          "title": "Expires at",
                          "description": "When this link stops working (15 minutes from now at most).",
                          "examples": [
                            "2026-10-18T12:15:00Z"
                          ],
                          "format": "date-time"
                        },
                        "availableUntil": {
                          "type": "string",
                          "title": "Available until",
                          "description": "The edition expiry (12 months after it was made).",
                          "examples": [
                            "2027-10-17T12:00:00Z"
                          ],
                          "format": "date-time"
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "The file this link opens.",
                          "examples": [
                            "summary.md"
                          ],
                          "pattern": "^[A-Za-z0-9_][A-Za-z0-9._-]*(/[A-Za-z0-9_][A-Za-z0-9._-]*)*$"
                        },
                        "format": {
                          "type": "string",
                          "enum": [
                            "markdown",
                            "html",
                            "json",
                            "jsonl",
                            "csv",
                            "text",
                            "pdf"
                          ],
                          "title": "Format",
                          "description": "The file format.",
                          "examples": [
                            "markdown"
                          ]
                        },
                        "contentType": {
                          "type": "string",
                          "title": "Content type",
                          "description": "Its MIME type.",
                          "examples": [
                            "text/markdown; charset=utf-8"
                          ]
                        },
                        "bytes": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Bytes",
                          "description": "File size.",
                          "examples": [
                            32674
                          ]
                        },
                        "sha256": {
                          "type": "string",
                          "title": "SHA-256",
                          "description": "Check the download against it.",
                          "examples": [
                            "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                          ],
                          "pattern": "^[0-9a-f]{64}$"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "410": {
            "description": "Error. The `error.code` is one of:\n- `download_expired`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The edition id.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Report link request",
                "description": "Exactly one of format (the readable report in that format, e.g. markdown or html) or file (any file by its name).",
                "additionalProperties": false,
                "required": [],
                "properties": {
                  "format": {
                    "type": "string",
                    "enum": [
                      "markdown",
                      "html",
                      "json",
                      "jsonl",
                      "csv",
                      "text",
                      "pdf"
                    ],
                    "title": "Format",
                    "description": "The readable report in this format.",
                    "examples": [
                      "markdown"
                    ]
                  },
                  "file": {
                    "type": "string",
                    "title": "File",
                    "description": "A file by its name, as listed in files.",
                    "examples": [
                      "sections/listings.csv"
                    ],
                    "pattern": "^[A-Za-z0-9_][A-Za-z0-9._-]*(/[A-Za-z0-9_][A-Za-z0-9._-]*)*$"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/runs": {
      "get": {
        "operationId": "listRuns",
        "summary": "List your fresh-read runs",
        "description": "Your organisation’s fresh-read runs, newest first, a page at a time. Free. A run whose pins have all finished is settled on the first read, as GET /v1/runs/{id} does.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "Runs",
                  "description": "Your organisation’s fresh-read runs, newest first, a page at a time. Free. A run whose pins have all finished is settled on the first read, as GET /v1/runs/{id} does.",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "title": "RunSummary",
                        "description": "One run in the list: its status, pins, rows delivered and, once every pin has finished, the credits charged.",
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "recipe",
                          "query",
                          "status",
                          "pincodes",
                          "pinCount",
                          "rowsDelivered",
                          "ceiling",
                          "creditsCharged",
                          "receiptId",
                          "createdAt",
                          "approvedAt",
                          "finishedAt"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid",
                            "description": "The run id: the approved quote’s id."
                          },
                          "recipe": {
                            "type": "string",
                            "description": "The recipe read: the retailer’s catalogue recipe id, e.g. jiomart."
                          },
                          "query": {
                            "type": "string",
                            "description": "The search term or product reference read."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "running",
                              "delivered",
                              "partial",
                              "empty",
                              "failed"
                            ]
                          },
                          "pincodes": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "The pin codes asked."
                          },
                          "pinCount": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "rowsDelivered": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "ceiling": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "The most the run can be charged."
                          },
                          "creditsCharged": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "minimum": 0,
                            "description": "Credits charged; null until every pin has finished."
                          },
                          "receiptId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "When the quote was made."
                          },
                          "approvedAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "When the quote was approved: the run’s start."
                          },
                          "finishedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "page": {
                      "title": "RunListPageInfo",
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "minimum": 1,
                          "description": "The page size used."
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "description": "Pass as cursor for the next (older) page; null at the end."
                        }
                      }
                    }
                  },
                  "examples": [
                    {
                      "data": [
                        {
                          "id": "9b1d6e0a-4c3f-4f7e-8a21-5d0c7b9e1f42",
                          "recipe": "jiomart",
                          "query": "atta",
                          "status": "delivered",
                          "pincodes": [
                            "400001",
                            "560001"
                          ],
                          "pinCount": 2,
                          "rowsDelivered": 46,
                          "ceiling": 10,
                          "creditsCharged": 5,
                          "receiptId": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                          "createdAt": "2026-10-20T09:59:30.000Z",
                          "approvedAt": "2026-10-20T10:00:00.000Z",
                          "finishedAt": "2026-10-20T10:03:12.000Z"
                        }
                      ],
                      "page": {
                        "limit": 20,
                        "nextCursor": null
                      }
                    }
                  ]
                },
                "example": {
                  "data": [
                    {
                      "id": "9b1d6e0a-4c3f-4f7e-8a21-5d0c7b9e1f42",
                      "recipe": "jiomart",
                      "query": "atta",
                      "status": "delivered",
                      "pincodes": [
                        "400001",
                        "560001"
                      ],
                      "pinCount": 2,
                      "rowsDelivered": 46,
                      "ceiling": 10,
                      "creditsCharged": 5,
                      "receiptId": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                      "createdAt": "2026-10-20T09:59:30.000Z",
                      "approvedAt": "2026-10-20T10:00:00.000Z",
                      "finishedAt": "2026-10-20T10:03:12.000Z"
                    }
                  ],
                  "page": {
                    "limit": 20,
                    "nextCursor": null
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[1-9][0-9]{0,2}$",
              "examples": [
                "20"
              ]
            },
            "description": "Runs per page, 1 to 100 (default 20). Sent as digits in the query string."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,200}$"
            },
            "description": "page.nextCursor from the previous page."
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "examples": [
                "2026-10-01T00:00:00Z"
              ]
            },
            "description": "Only runs approved at or after this moment."
          }
        ]
      }
    },
    "/v1/runs/{id}": {
      "get": {
        "operationId": "getRun",
        "summary": "Read a fresh-read run",
        "description": "A fresh-read run: its status, each pin’s progress, the rows delivered so far and, once every pin has finished, the credits charged (never above the ceiling; 0 when nothing was delivered).",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "Run",
                  "description": "A fresh-read run: its status, each pin’s progress, the rows delivered so far and, once every pin has finished, the credits charged (never above the ceiling; 0 when nothing was delivered).",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "recipe",
                    "query",
                    "status",
                    "pins",
                    "rowsDelivered",
                    "ceiling",
                    "creditsCharged",
                    "receiptId",
                    "approvedAt",
                    "finishedAt"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "The run id: the approved quote’s id."
                    },
                    "recipe": {
                      "type": "string"
                    },
                    "query": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "running",
                        "delivered",
                        "partial",
                        "empty",
                        "failed"
                      ]
                    },
                    "pins": {
                      "type": "array",
                      "items": {
                        "title": "RunPin",
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "pincode",
                          "status",
                          "rows",
                          "error"
                        ],
                        "properties": {
                          "pincode": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "queued",
                              "running",
                              "done",
                              "failed"
                            ]
                          },
                          "rows": {
                            "type": "integer",
                            "minimum": 0,
                            "description": "Rows this pin delivered."
                          },
                          "error": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Why the pin failed; null otherwise."
                          }
                        }
                      }
                    },
                    "rowsDelivered": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "ceiling": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "The most the run can be charged."
                    },
                    "creditsCharged": {
                      "type": [
                        "null",
                        "integer"
                      ],
                      "minimum": 0,
                      "description": "Credits charged; null until every pin has finished."
                    },
                    "receiptId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "uuid"
                    },
                    "approvedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "finishedAt": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "date-time"
                    }
                  },
                  "examples": [
                    {
                      "id": "9b1d6e0a-4c3f-4f7e-8a21-5d0c7b9e1f42",
                      "recipe": "jiomart",
                      "query": "atta",
                      "status": "delivered",
                      "pins": [
                        {
                          "pincode": "400001",
                          "status": "done",
                          "rows": 24,
                          "error": null
                        },
                        {
                          "pincode": "560001",
                          "status": "done",
                          "rows": 22,
                          "error": null
                        }
                      ],
                      "rowsDelivered": 46,
                      "ceiling": 10,
                      "creditsCharged": 5,
                      "receiptId": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                      "approvedAt": "2026-10-20T10:00:00.000Z",
                      "finishedAt": "2026-10-20T10:03:12.000Z"
                    }
                  ]
                },
                "example": {
                  "id": "9b1d6e0a-4c3f-4f7e-8a21-5d0c7b9e1f42",
                  "recipe": "jiomart",
                  "query": "atta",
                  "status": "delivered",
                  "pins": [
                    {
                      "pincode": "400001",
                      "status": "done",
                      "rows": 24,
                      "error": null
                    },
                    {
                      "pincode": "560001",
                      "status": "done",
                      "rows": 22,
                      "error": null
                    }
                  ],
                  "rowsDelivered": 46,
                  "ceiling": 10,
                  "creditsCharged": 5,
                  "receiptId": "3f2a1b0c-9d8e-4f7a-8b6c-5d4e3f2a1b0c",
                  "approvedAt": "2026-10-20T10:00:00.000Z",
                  "finishedAt": "2026-10-20T10:03:12.000Z"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The run id (the approved quote’s id)."
            }
          }
        ]
      }
    },
    "/v1/runs/{id}/rows": {
      "get": {
        "operationId": "getRunRows",
        "summary": "Read the rows a fresh-read run delivered",
        "description": "Rows a fresh-read run delivered, pin by pin in the order the pins were asked. Free.",
        "tags": [
          "Runs"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "RunRows",
                  "description": "Rows a fresh-read run delivered, pin by pin in the order the pins were asked. Free.",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "runId",
                    "rows",
                    "nextCursor"
                  ],
                  "properties": {
                    "runId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "rows": {
                      "type": "array",
                      "items": {
                        "title": "RunRow",
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "pincode",
                          "type",
                          "data",
                          "sourceUrl",
                          "fetchedAt"
                        ],
                        "properties": {
                          "pincode": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string",
                            "description": "The kind of record, e.g. commerce_observation."
                          },
                          "data": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "sourceUrl": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "fetchedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "title": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "The product name of the listing the row is about, where Rewalto holds it; null when the listing is not known."
                          },
                          "brand": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "The listing’s brand as the retailer gave it; null when not known."
                          },
                          "packSizeRaw": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "The listing’s pack size as the retailer wrote it (e.g. \"100 g\"); null when not known."
                          },
                          "imageUrl": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "The listing’s product image address; null when not known."
                          }
                        }
                      }
                    },
                    "nextCursor": {
                      "type": [
                        "null",
                        "string"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid",
              "description": "The run id (the approved quote’s id)."
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{1,3}$",
              "examples": [
                "100"
              ]
            },
            "description": "Rows per page, 1 to 500 (default 100). Sent as digits in the query string."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{1,9}$"
            },
            "description": "nextCursor from the previous page."
          }
        ]
      }
    },
    "/v1/saved-searches": {
      "post": {
        "operationId": "createSavedSearch",
        "summary": "Save a search or a watch",
        "description": "Saves it as a draft and estimates its cost (free). Nothing is read for money until you activate it. A watch needs a frequency; a search must not have one.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Saved search answer",
                  "description": "One saved search.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Saved search or watch",
                      "description": "A saved search or watch, its state, cost, the one confirmation, its next refresh and its last refresh.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "name",
                        "state",
                        "pauseReason",
                        "targets",
                        "maxResults",
                        "frequency",
                        "spendingLimit",
                        "cost",
                        "confirmed",
                        "nextRefreshAt",
                        "spentThisMonthCredits",
                        "notify",
                        "lastRun",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The saved search id.",
                          "examples": [
                            "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "search",
                            "watch"
                          ],
                          "title": "Kind",
                          "description": "search or watch.",
                          "examples": [
                            "search"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "A name you will recognise.",
                          "examples": [
                            "Atta prices, Bengaluru"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "active",
                            "paused",
                            "cancelled"
                          ],
                          "title": "State",
                          "description": "draft (not yet confirmed), active, paused or cancelled.",
                          "examples": [
                            "draft"
                          ]
                        },
                        "pauseReason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            "by_user",
                            "insufficient_credits",
                            "monthly_cap",
                            null
                          ],
                          "title": "Pause reason",
                          "description": "Why it is paused; null otherwise.",
                          "examples": [
                            "by_user"
                          ]
                        },
                        "targets": {
                          "type": "array",
                          "title": "Targets",
                          "description": "What it looks up.",
                          "items": {
                            "type": "object",
                            "title": "Saved target as stored",
                            "description": "A saved target. A location is stored with the exact pins it resolved to when you confirmed it, so later refreshes read those pins, never a broader place.",
                            "additionalProperties": false,
                            "required": [
                              "q",
                              "brand",
                              "retailer",
                              "pincode",
                              "location",
                              "pins"
                            ],
                            "properties": {
                              "q": {
                                "type": "string",
                                "title": "Words",
                                "description": "The words.",
                                "examples": [
                                  "aashirvaad atta"
                                ]
                              },
                              "brand": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Brand",
                                "description": "The brand, or null.",
                                "examples": [
                                  "Aashirvaad"
                                ]
                              },
                              "retailer": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Retailer",
                                "description": "The retailer, or null.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "pincode": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Pin code",
                                "description": "The single pin, or null.",
                                "examples": [
                                  "110092"
                                ]
                              },
                              "location": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Location",
                                "description": "The Core location id, or null.",
                                "examples": [
                                  "IN:city:karnataka:bengaluru"
                                ]
                              },
                              "pins": {
                                "type": [
                                  "null",
                                  "array"
                                ],
                                "title": "Pins",
                                "description": "The pins the location resolved to when confirmed; null without a location.",
                                "items": {
                                  "type": "string",
                                  "examples": [
                                    "560001"
                                  ]
                                }
                              }
                            }
                          }
                        },
                        "maxResults": {
                          "type": "integer",
                          "title": "Rows per target",
                          "description": "The most listings one refresh reads for each target, 1 to 100. Default 50. This bounds the cost ceiling.",
                          "examples": [
                            50
                          ],
                          "minimum": 1,
                          "maximum": 100
                        },
                        "frequency": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Frequency",
                          "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                          "additionalProperties": false,
                          "required": [
                            "kind",
                            "time"
                          ],
                          "properties": {
                            "kind": {
                              "type": "string",
                              "enum": [
                                "daily",
                                "weekly",
                                "monthly"
                              ],
                              "title": "Kind",
                              "description": "daily, weekly or monthly.",
                              "examples": [
                                "daily"
                              ]
                            },
                            "time": {
                              "type": "string",
                              "title": "Time",
                              "description": "HH:MM, 24-hour, Asia/Kolkata.",
                              "examples": [
                                "07:30"
                              ],
                              "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                            },
                            "weekday": {
                              "type": "string",
                              "enum": [
                                "monday",
                                "tuesday",
                                "wednesday",
                                "thursday",
                                "friday",
                                "saturday",
                                "sunday"
                              ],
                              "title": "Weekday",
                              "description": "For weekly.",
                              "examples": [
                                "monday"
                              ]
                            },
                            "dayOfMonth": {
                              "type": "integer",
                              "title": "Day of month",
                              "description": "For monthly, 1 to 28.",
                              "examples": [
                                1
                              ],
                              "minimum": 1,
                              "maximum": 28
                            }
                          }
                        },
                        "spendingLimit": {
                          "type": "object",
                          "title": "Spending caps",
                          "description": "The most credits one refresh may charge, and the most all refreshes may charge in an IST calendar month. A refresh that would pass either is cut down to fit, or skipped and recorded; it is never charged above them.",
                          "additionalProperties": false,
                          "required": [
                            "perRefreshCredits",
                            "perMonthCredits"
                          ],
                          "properties": {
                            "perRefreshCredits": {
                              "type": "integer",
                              "title": "Per refresh",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                20
                              ],
                              "minimum": 1
                            },
                            "perMonthCredits": {
                              "type": "integer",
                              "title": "Per month",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                300
                              ],
                              "minimum": 1
                            }
                          }
                        },
                        "cost": {
                          "type": "object",
                          "title": "Cost",
                          "description": "What a refresh costs, estimated free from what the targets match now, at the published listings rate. The ceiling is the most a refresh can cost (rows per target x targets); you confirm the ceilings.",
                          "additionalProperties": false,
                          "required": [
                            "expectedListings",
                            "perRefreshExpectedCredits",
                            "perRefreshCeilingCredits",
                            "refreshesPerMonth",
                            "perMonthCeilingCredits",
                            "rateVersion",
                            "estimatedAt",
                            "fitsBalance",
                            "withinCaps"
                          ],
                          "properties": {
                            "expectedListings": {
                              "type": "integer",
                              "title": "Expected listings",
                              "description": "About how many listings a refresh reads now.",
                              "examples": [
                                120
                              ]
                            },
                            "perRefreshExpectedCredits": {
                              "type": "integer",
                              "title": "Expected per refresh",
                              "description": "Credits for the expected listings.",
                              "examples": [
                                12
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per refresh",
                              "description": "The most one refresh can cost.",
                              "examples": [
                                50
                              ]
                            },
                            "refreshesPerMonth": {
                              "type": "integer",
                              "title": "Refreshes a month",
                              "description": "At most this many (a search: 1 by hand counts as the caps allow).",
                              "examples": [
                                31
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per month",
                              "description": "Ceiling per refresh x refreshes a month.",
                              "examples": [
                                1550
                              ]
                            },
                            "rateVersion": {
                              "type": "string",
                              "title": "Rate version",
                              "description": "The listings rate card used.",
                              "examples": [
                                "2"
                              ]
                            },
                            "estimatedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Estimated at",
                              "description": "When it was estimated.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "fitsBalance": {
                              "type": "boolean",
                              "title": "Fits balance",
                              "description": "Whether the expected month fits your credits now.",
                              "examples": [
                                true
                              ]
                            },
                            "withinCaps": {
                              "type": "boolean",
                              "title": "Within caps",
                              "description": "Whether the ceilings are inside your caps; if not a refresh is cut to fit.",
                              "examples": [
                                true
                              ]
                            }
                          }
                        },
                        "confirmed": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Confirmation",
                          "description": "Your one confirmation: who, when and the ceilings and caps agreed.",
                          "additionalProperties": false,
                          "required": [
                            "by",
                            "at",
                            "perRefreshCeilingCredits",
                            "perMonthCeilingCredits",
                            "perRefreshCapCredits",
                            "perMonthCapCredits"
                          ],
                          "properties": {
                            "by": {
                              "type": "string",
                              "title": "By",
                              "description": "Who confirmed.",
                              "examples": [
                                "user:abc"
                              ]
                            },
                            "at": {
                              "type": "string",
                              "format": "date-time",
                              "title": "At",
                              "description": "When.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Per refresh ceiling",
                              "description": "Agreed.",
                              "examples": [
                                50
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Per month ceiling",
                              "description": "Agreed.",
                              "examples": [
                                1550
                              ]
                            },
                            "perRefreshCapCredits": {
                              "type": "integer",
                              "title": "Per refresh cap",
                              "description": "Agreed cap.",
                              "examples": [
                                20
                              ]
                            },
                            "perMonthCapCredits": {
                              "type": "integer",
                              "title": "Per month cap",
                              "description": "Agreed cap.",
                              "examples": [
                                300
                              ]
                            }
                          }
                        },
                        "nextRefreshAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Next refresh",
                          "description": "When a watch refreshes next; null otherwise.",
                          "examples": [
                            "2026-10-21T02:00:00Z"
                          ]
                        },
                        "spentThisMonthCredits": {
                          "type": "integer",
                          "title": "Spent this month",
                          "description": "Credits charged by refreshes this IST month.",
                          "examples": [
                            24
                          ]
                        },
                        "notify": {
                          "type": "array",
                          "title": "Notify",
                          "description": "Where this watch sends what changed. An email entry names the destination it resolved to.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "channel",
                              "destinationId"
                            ],
                            "properties": {
                              "channel": {
                                "type": "string",
                                "enum": [
                                  "in_app",
                                  "email",
                                  "slack",
                                  "telegram",
                                  "webhook"
                                ],
                                "title": "Channel",
                                "description": "The channel."
                              },
                              "destinationId": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "pattern": "^dst_[0-9a-f]{32}$",
                                "title": "Destination id",
                                "description": "The destination; null for in_app.",
                                "examples": [
                                  "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
                                ]
                              }
                            }
                          }
                        },
                        "lastRun": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Refresh",
                          "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "savedSearchId",
                            "trigger",
                            "state",
                            "skipReason",
                            "failureMessage",
                            "credits",
                            "rows",
                            "trimmed",
                            "freeReread",
                            "summary",
                            "startedAt",
                            "finishedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "title": "Id",
                              "description": "The refresh id.",
                              "examples": [
                                "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                              ]
                            },
                            "savedSearchId": {
                              "type": "string",
                              "title": "Saved search",
                              "description": "Its saved search.",
                              "examples": [
                                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "scheduled"
                              ],
                              "title": "Trigger",
                              "description": "manual or scheduled.",
                              "examples": [
                                "manual"
                              ]
                            },
                            "state": {
                              "type": "string",
                              "enum": [
                                "running",
                                "done",
                                "skipped",
                                "failed"
                              ],
                              "title": "State",
                              "description": "running, done, skipped or failed.",
                              "examples": [
                                "running"
                              ]
                            },
                            "skipReason": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "enum": [
                                "not_approved",
                                "paused",
                                "cancelled",
                                "insufficient_credits",
                                "monthly_cap",
                                "refresh_all_limit",
                                null
                              ],
                              "title": "Skip reason",
                              "description": "Why it was skipped; null otherwise.",
                              "examples": [
                                "not_approved"
                              ]
                            },
                            "failureMessage": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Failure",
                              "description": "Why it failed; null otherwise.",
                              "examples": [
                                "stopped before finishing"
                              ]
                            },
                            "credits": {
                              "type": "object",
                              "title": "Credits",
                              "description": "The cap it ran under and what it charged (never above it).",
                              "additionalProperties": false,
                              "required": [
                                "limit",
                                "charged"
                              ],
                              "properties": {
                                "limit": {
                                  "type": "integer",
                                  "title": "Limit",
                                  "description": "The most this refresh could charge.",
                                  "examples": [
                                    20
                                  ]
                                },
                                "charged": {
                                  "type": "integer",
                                  "title": "Charged",
                                  "description": "Credits charged; 0 for a free re-read.",
                                  "examples": [
                                    12
                                  ]
                                }
                              }
                            },
                            "rows": {
                              "type": "integer",
                              "title": "Rows",
                              "description": "Listings delivered.",
                              "examples": [
                                120
                              ]
                            },
                            "trimmed": {
                              "type": "boolean",
                              "title": "Trimmed",
                              "description": "True when the refresh was cut down to fit a cap.",
                              "examples": [
                                false
                              ]
                            },
                            "freeReread": {
                              "type": "boolean",
                              "title": "Free re-read",
                              "description": "True when identical data was read within 7 days (free).",
                              "examples": [
                                false
                              ]
                            },
                            "summary": {
                              "type": [
                                "null",
                                "object"
                              ],
                              "title": "Change summary",
                              "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                              "additionalProperties": false,
                              "required": [
                                "first",
                                "totalNow",
                                "totalBefore",
                                "addedCount",
                                "removedCount",
                                "changedCount",
                                "reobservedCount",
                                "added",
                                "removed"
                              ],
                              "properties": {
                                "first": {
                                  "type": "boolean",
                                  "title": "First",
                                  "description": "No earlier refresh to compare with.",
                                  "examples": [
                                    false
                                  ]
                                },
                                "totalNow": {
                                  "type": "integer",
                                  "title": "Total now",
                                  "description": "Listings in this refresh.",
                                  "examples": [
                                    120
                                  ]
                                },
                                "totalBefore": {
                                  "type": "integer",
                                  "title": "Total before",
                                  "description": "Listings in the previous refresh.",
                                  "examples": [
                                    118
                                  ]
                                },
                                "addedCount": {
                                  "type": "integer",
                                  "title": "Added",
                                  "description": "Listings that are new in the results.",
                                  "examples": [
                                    3
                                  ]
                                },
                                "removedCount": {
                                  "type": "integer",
                                  "title": "Removed",
                                  "description": "Listings no longer in the results.",
                                  "examples": [
                                    1
                                  ]
                                },
                                "changedCount": {
                                  "type": "integer",
                                  "title": "Changed",
                                  "description": "Listings whose title, brand or retailer details changed.",
                                  "examples": [
                                    2
                                  ]
                                },
                                "reobservedCount": {
                                  "type": "integer",
                                  "title": "Read again",
                                  "description": "Listings the collectors have read again since.",
                                  "examples": [
                                    40
                                  ]
                                },
                                "added": {
                                  "type": "array",
                                  "title": "Added listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "123"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Aashirvaad Atta 5kg"
                                        ]
                                      }
                                    }
                                  }
                                },
                                "removed": {
                                  "type": "array",
                                  "title": "Removed listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "99"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Old Atta 1kg"
                                        ]
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Started",
                              "description": "When it started.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "finishedAt": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "format": "date-time",
                              "title": "Finished",
                              "description": "When it ended; null while running.",
                              "examples": [
                                "2026-10-20T10:00:01Z"
                              ]
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Created",
                          "description": "When saved.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Updated",
                          "description": "When last changed.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `idempotency_conflict`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Save a search or a watch",
                "description": "Saves it as a draft and estimates its cost (free). Nothing is read for money until you activate it. A watch needs a frequency; a search must not have one.",
                "additionalProperties": false,
                "required": [
                  "idempotencyKey",
                  "kind",
                  "name",
                  "targets",
                  "spendingLimit"
                ],
                "properties": {
                  "idempotencyKey": {
                    "type": "string",
                    "title": "Idempotency key",
                    "description": "Your own unique key (8 to 128 of letters, digits . _ : -). Sending the same key with the same body again returns the same record; with a different body, idempotency_conflict.",
                    "examples": [
                      "watch-atta-2026-10-20"
                    ],
                    "pattern": "^[A-Za-z0-9._:-]{8,128}$"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "search",
                      "watch"
                    ],
                    "title": "Kind",
                    "description": "search (refreshed by hand) or watch (refreshed on a schedule).",
                    "examples": [
                      "search"
                    ]
                  },
                  "name": {
                    "type": "string",
                    "title": "Name",
                    "description": "A name you will recognise.",
                    "examples": [
                      "Atta prices, Bengaluru"
                    ],
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "targets": {
                    "type": "array",
                    "title": "Targets",
                    "description": "1 to 10 things to look up.",
                    "items": {
                      "type": "object",
                      "title": "Saved target",
                      "description": "One thing to look up: product words, optionally one brand, one retailer, and one place (a pin code, or a Core location id with your confirmPins consent).",
                      "additionalProperties": false,
                      "required": [
                        "q"
                      ],
                      "properties": {
                        "q": {
                          "type": "string",
                          "title": "Words",
                          "description": "Name, brand or retailer product id words (as in listings search).",
                          "examples": [
                            "aashirvaad atta"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "brand": {
                          "type": "string",
                          "title": "Brand",
                          "description": "Only this exact brand.",
                          "examples": [
                            "Aashirvaad"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "retailer": {
                          "type": "string",
                          "title": "Retailer",
                          "description": "Only this retailer.",
                          "examples": [
                            "blinkit"
                          ],
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "pincode": {
                          "type": "string",
                          "title": "Pin code",
                          "description": "Only listings read at this six-digit pin in the last 30 days.",
                          "examples": [
                            "110092"
                          ],
                          "pattern": "^[1-9][0-9]{5}$"
                        },
                        "location": {
                          "type": "string",
                          "title": "Location",
                          "description": "A Core location id from the free lookup (GET /v1/data/locations, /cities or /stores): a pin, a city, an area or a dark store. It resolves to an explicit list of pin codes (see GET /v1/data/locations/filter). Never combine with pincode. More than one pin needs confirmPins. A store id (IN:store:<retailer>:<store id>) means the pin codes that dark store serves (its catchment as the sweeps saw it). Readings are kept per pin code, not per store, so it reads every kept reading at those pin codes, whichever store served them; no reading is attributed to the store itself.",
                          "examples": [
                            "IN:city:karnataka:bengaluru"
                          ],
                          "pattern": "^[A-Z]{2}:(pin:[1-9][0-9]{5}|city:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}|area:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}:[a-z0-9]{1,120}|store:[a-z0-9_]{2,40}:[A-Za-z0-9_-]{1,64})$"
                        },
                        "confirmPins": {
                          "type": "string",
                          "title": "Confirm pins",
                          "description": "Your consent to a multi-pin read: the number of pins the location resolves to, as GET /v1/data/locations/filter showed it. A different number is refused with the current count, so a place is never silently broadened.",
                          "examples": [
                            "112"
                          ],
                          "pattern": "^[1-9][0-9]{0,2}$"
                        }
                      }
                    },
                    "minItems": 1,
                    "maxItems": 10
                  },
                  "maxResults": {
                    "type": "integer",
                    "title": "Rows per target",
                    "description": "The most listings one refresh reads for each target, 1 to 100. Default 50. This bounds the cost ceiling.",
                    "examples": [
                      50
                    ],
                    "minimum": 1,
                    "maximum": 100
                  },
                  "frequency": {
                    "type": "object",
                    "title": "Frequency",
                    "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                    "additionalProperties": false,
                    "required": [
                      "kind",
                      "time"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "enum": [
                          "daily",
                          "weekly",
                          "monthly"
                        ],
                        "title": "Kind",
                        "description": "daily, weekly or monthly.",
                        "examples": [
                          "daily"
                        ]
                      },
                      "time": {
                        "type": "string",
                        "title": "Time",
                        "description": "HH:MM, 24-hour, Asia/Kolkata.",
                        "examples": [
                          "07:30"
                        ],
                        "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                      },
                      "weekday": {
                        "type": "string",
                        "enum": [
                          "monday",
                          "tuesday",
                          "wednesday",
                          "thursday",
                          "friday",
                          "saturday",
                          "sunday"
                        ],
                        "title": "Weekday",
                        "description": "For weekly.",
                        "examples": [
                          "monday"
                        ]
                      },
                      "dayOfMonth": {
                        "type": "integer",
                        "title": "Day of month",
                        "description": "For monthly, 1 to 28.",
                        "examples": [
                          1
                        ],
                        "minimum": 1,
                        "maximum": 28
                      }
                    }
                  },
                  "spendingLimit": {
                    "type": "object",
                    "title": "Spending caps",
                    "description": "The most credits one refresh may charge, and the most all refreshes may charge in an IST calendar month. A refresh that would pass either is cut down to fit, or skipped and recorded; it is never charged above them.",
                    "additionalProperties": false,
                    "required": [
                      "perRefreshCredits",
                      "perMonthCredits"
                    ],
                    "properties": {
                      "perRefreshCredits": {
                        "type": "integer",
                        "title": "Per refresh",
                        "description": "Whole credits, at least 1.",
                        "examples": [
                          20
                        ],
                        "minimum": 1
                      },
                      "perMonthCredits": {
                        "type": "integer",
                        "title": "Per month",
                        "description": "Whole credits, at least 1.",
                        "examples": [
                          300
                        ],
                        "minimum": 1
                      }
                    }
                  },
                  "notify": {
                    "$ref": "#/components/schemas/WatchNotify"
                  }
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listSavedSearches",
        "summary": "List saved searches and watches",
        "description": "Your organisation's saved searches and watches, newest first, cancelled last, each with its state, cost, next refresh and last refresh (with its change summary).",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Page",
                  "description": "One page.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Data",
                      "description": "The page.",
                      "items": {
                        "type": "object",
                        "title": "Saved search or watch",
                        "description": "A saved search or watch, its state, cost, the one confirmation, its next refresh and its last refresh.",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "kind",
                          "name",
                          "state",
                          "pauseReason",
                          "targets",
                          "maxResults",
                          "frequency",
                          "spendingLimit",
                          "cost",
                          "confirmed",
                          "nextRefreshAt",
                          "spentThisMonthCredits",
                          "notify",
                          "lastRun",
                          "createdAt",
                          "updatedAt"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "title": "Id",
                            "description": "The saved search id.",
                            "examples": [
                              "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "search",
                              "watch"
                            ],
                            "title": "Kind",
                            "description": "search or watch.",
                            "examples": [
                              "search"
                            ]
                          },
                          "name": {
                            "type": "string",
                            "title": "Name",
                            "description": "A name you will recognise.",
                            "examples": [
                              "Atta prices, Bengaluru"
                            ],
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "state": {
                            "type": "string",
                            "enum": [
                              "draft",
                              "active",
                              "paused",
                              "cancelled"
                            ],
                            "title": "State",
                            "description": "draft (not yet confirmed), active, paused or cancelled.",
                            "examples": [
                              "draft"
                            ]
                          },
                          "pauseReason": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "by_user",
                              "insufficient_credits",
                              "monthly_cap",
                              null
                            ],
                            "title": "Pause reason",
                            "description": "Why it is paused; null otherwise.",
                            "examples": [
                              "by_user"
                            ]
                          },
                          "targets": {
                            "type": "array",
                            "title": "Targets",
                            "description": "What it looks up.",
                            "items": {
                              "type": "object",
                              "title": "Saved target as stored",
                              "description": "A saved target. A location is stored with the exact pins it resolved to when you confirmed it, so later refreshes read those pins, never a broader place.",
                              "additionalProperties": false,
                              "required": [
                                "q",
                                "brand",
                                "retailer",
                                "pincode",
                                "location",
                                "pins"
                              ],
                              "properties": {
                                "q": {
                                  "type": "string",
                                  "title": "Words",
                                  "description": "The words.",
                                  "examples": [
                                    "aashirvaad atta"
                                  ]
                                },
                                "brand": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "Brand",
                                  "description": "The brand, or null.",
                                  "examples": [
                                    "Aashirvaad"
                                  ]
                                },
                                "retailer": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "Retailer",
                                  "description": "The retailer, or null.",
                                  "examples": [
                                    "blinkit"
                                  ]
                                },
                                "pincode": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "Pin code",
                                  "description": "The single pin, or null.",
                                  "examples": [
                                    "110092"
                                  ]
                                },
                                "location": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "title": "Location",
                                  "description": "The Core location id, or null.",
                                  "examples": [
                                    "IN:city:karnataka:bengaluru"
                                  ]
                                },
                                "pins": {
                                  "type": [
                                    "null",
                                    "array"
                                  ],
                                  "title": "Pins",
                                  "description": "The pins the location resolved to when confirmed; null without a location.",
                                  "items": {
                                    "type": "string",
                                    "examples": [
                                      "560001"
                                    ]
                                  }
                                }
                              }
                            }
                          },
                          "maxResults": {
                            "type": "integer",
                            "title": "Rows per target",
                            "description": "The most listings one refresh reads for each target, 1 to 100. Default 50. This bounds the cost ceiling.",
                            "examples": [
                              50
                            ],
                            "minimum": 1,
                            "maximum": 100
                          },
                          "frequency": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "title": "Frequency",
                            "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                            "additionalProperties": false,
                            "required": [
                              "kind",
                              "time"
                            ],
                            "properties": {
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "daily",
                                  "weekly",
                                  "monthly"
                                ],
                                "title": "Kind",
                                "description": "daily, weekly or monthly.",
                                "examples": [
                                  "daily"
                                ]
                              },
                              "time": {
                                "type": "string",
                                "title": "Time",
                                "description": "HH:MM, 24-hour, Asia/Kolkata.",
                                "examples": [
                                  "07:30"
                                ],
                                "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                              },
                              "weekday": {
                                "type": "string",
                                "enum": [
                                  "monday",
                                  "tuesday",
                                  "wednesday",
                                  "thursday",
                                  "friday",
                                  "saturday",
                                  "sunday"
                                ],
                                "title": "Weekday",
                                "description": "For weekly.",
                                "examples": [
                                  "monday"
                                ]
                              },
                              "dayOfMonth": {
                                "type": "integer",
                                "title": "Day of month",
                                "description": "For monthly, 1 to 28.",
                                "examples": [
                                  1
                                ],
                                "minimum": 1,
                                "maximum": 28
                              }
                            }
                          },
                          "spendingLimit": {
                            "type": "object",
                            "title": "Spending caps",
                            "description": "The most credits one refresh may charge, and the most all refreshes may charge in an IST calendar month. A refresh that would pass either is cut down to fit, or skipped and recorded; it is never charged above them.",
                            "additionalProperties": false,
                            "required": [
                              "perRefreshCredits",
                              "perMonthCredits"
                            ],
                            "properties": {
                              "perRefreshCredits": {
                                "type": "integer",
                                "title": "Per refresh",
                                "description": "Whole credits, at least 1.",
                                "examples": [
                                  20
                                ],
                                "minimum": 1
                              },
                              "perMonthCredits": {
                                "type": "integer",
                                "title": "Per month",
                                "description": "Whole credits, at least 1.",
                                "examples": [
                                  300
                                ],
                                "minimum": 1
                              }
                            }
                          },
                          "cost": {
                            "type": "object",
                            "title": "Cost",
                            "description": "What a refresh costs, estimated free from what the targets match now, at the published listings rate. The ceiling is the most a refresh can cost (rows per target x targets); you confirm the ceilings.",
                            "additionalProperties": false,
                            "required": [
                              "expectedListings",
                              "perRefreshExpectedCredits",
                              "perRefreshCeilingCredits",
                              "refreshesPerMonth",
                              "perMonthCeilingCredits",
                              "rateVersion",
                              "estimatedAt",
                              "fitsBalance",
                              "withinCaps"
                            ],
                            "properties": {
                              "expectedListings": {
                                "type": "integer",
                                "title": "Expected listings",
                                "description": "About how many listings a refresh reads now.",
                                "examples": [
                                  120
                                ]
                              },
                              "perRefreshExpectedCredits": {
                                "type": "integer",
                                "title": "Expected per refresh",
                                "description": "Credits for the expected listings.",
                                "examples": [
                                  12
                                ]
                              },
                              "perRefreshCeilingCredits": {
                                "type": "integer",
                                "title": "Ceiling per refresh",
                                "description": "The most one refresh can cost.",
                                "examples": [
                                  50
                                ]
                              },
                              "refreshesPerMonth": {
                                "type": "integer",
                                "title": "Refreshes a month",
                                "description": "At most this many (a search: 1 by hand counts as the caps allow).",
                                "examples": [
                                  31
                                ]
                              },
                              "perMonthCeilingCredits": {
                                "type": "integer",
                                "title": "Ceiling per month",
                                "description": "Ceiling per refresh x refreshes a month.",
                                "examples": [
                                  1550
                                ]
                              },
                              "rateVersion": {
                                "type": "string",
                                "title": "Rate version",
                                "description": "The listings rate card used.",
                                "examples": [
                                  "2"
                                ]
                              },
                              "estimatedAt": {
                                "type": "string",
                                "format": "date-time",
                                "title": "Estimated at",
                                "description": "When it was estimated.",
                                "examples": [
                                  "2026-10-20T10:00:00Z"
                                ]
                              },
                              "fitsBalance": {
                                "type": "boolean",
                                "title": "Fits balance",
                                "description": "Whether the expected month fits your credits now.",
                                "examples": [
                                  true
                                ]
                              },
                              "withinCaps": {
                                "type": "boolean",
                                "title": "Within caps",
                                "description": "Whether the ceilings are inside your caps; if not a refresh is cut to fit.",
                                "examples": [
                                  true
                                ]
                              }
                            }
                          },
                          "confirmed": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "title": "Confirmation",
                            "description": "Your one confirmation: who, when and the ceilings and caps agreed.",
                            "additionalProperties": false,
                            "required": [
                              "by",
                              "at",
                              "perRefreshCeilingCredits",
                              "perMonthCeilingCredits",
                              "perRefreshCapCredits",
                              "perMonthCapCredits"
                            ],
                            "properties": {
                              "by": {
                                "type": "string",
                                "title": "By",
                                "description": "Who confirmed.",
                                "examples": [
                                  "user:abc"
                                ]
                              },
                              "at": {
                                "type": "string",
                                "format": "date-time",
                                "title": "At",
                                "description": "When.",
                                "examples": [
                                  "2026-10-20T10:00:00Z"
                                ]
                              },
                              "perRefreshCeilingCredits": {
                                "type": "integer",
                                "title": "Per refresh ceiling",
                                "description": "Agreed.",
                                "examples": [
                                  50
                                ]
                              },
                              "perMonthCeilingCredits": {
                                "type": "integer",
                                "title": "Per month ceiling",
                                "description": "Agreed.",
                                "examples": [
                                  1550
                                ]
                              },
                              "perRefreshCapCredits": {
                                "type": "integer",
                                "title": "Per refresh cap",
                                "description": "Agreed cap.",
                                "examples": [
                                  20
                                ]
                              },
                              "perMonthCapCredits": {
                                "type": "integer",
                                "title": "Per month cap",
                                "description": "Agreed cap.",
                                "examples": [
                                  300
                                ]
                              }
                            }
                          },
                          "nextRefreshAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "title": "Next refresh",
                            "description": "When a watch refreshes next; null otherwise.",
                            "examples": [
                              "2026-10-21T02:00:00Z"
                            ]
                          },
                          "spentThisMonthCredits": {
                            "type": "integer",
                            "title": "Spent this month",
                            "description": "Credits charged by refreshes this IST month.",
                            "examples": [
                              24
                            ]
                          },
                          "notify": {
                            "type": "array",
                            "title": "Notify",
                            "description": "Where this watch sends what changed. An email entry names the destination it resolved to.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "channel",
                                "destinationId"
                              ],
                              "properties": {
                                "channel": {
                                  "type": "string",
                                  "enum": [
                                    "in_app",
                                    "email",
                                    "slack",
                                    "telegram",
                                    "webhook"
                                  ],
                                  "title": "Channel",
                                  "description": "The channel."
                                },
                                "destinationId": {
                                  "type": [
                                    "null",
                                    "string"
                                  ],
                                  "pattern": "^dst_[0-9a-f]{32}$",
                                  "title": "Destination id",
                                  "description": "The destination; null for in_app.",
                                  "examples": [
                                    "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
                                  ]
                                }
                              }
                            }
                          },
                          "lastRun": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "title": "Refresh",
                            "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                            "additionalProperties": false,
                            "required": [
                              "id",
                              "savedSearchId",
                              "trigger",
                              "state",
                              "skipReason",
                              "failureMessage",
                              "credits",
                              "rows",
                              "trimmed",
                              "freeReread",
                              "summary",
                              "startedAt",
                              "finishedAt"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "title": "Id",
                                "description": "The refresh id.",
                                "examples": [
                                  "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                                ]
                              },
                              "savedSearchId": {
                                "type": "string",
                                "title": "Saved search",
                                "description": "Its saved search.",
                                "examples": [
                                  "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                                ]
                              },
                              "trigger": {
                                "type": "string",
                                "enum": [
                                  "manual",
                                  "scheduled"
                                ],
                                "title": "Trigger",
                                "description": "manual or scheduled.",
                                "examples": [
                                  "manual"
                                ]
                              },
                              "state": {
                                "type": "string",
                                "enum": [
                                  "running",
                                  "done",
                                  "skipped",
                                  "failed"
                                ],
                                "title": "State",
                                "description": "running, done, skipped or failed.",
                                "examples": [
                                  "running"
                                ]
                              },
                              "skipReason": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "enum": [
                                  "not_approved",
                                  "paused",
                                  "cancelled",
                                  "insufficient_credits",
                                  "monthly_cap",
                                  "refresh_all_limit",
                                  null
                                ],
                                "title": "Skip reason",
                                "description": "Why it was skipped; null otherwise.",
                                "examples": [
                                  "not_approved"
                                ]
                              },
                              "failureMessage": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Failure",
                                "description": "Why it failed; null otherwise.",
                                "examples": [
                                  "stopped before finishing"
                                ]
                              },
                              "credits": {
                                "type": "object",
                                "title": "Credits",
                                "description": "The cap it ran under and what it charged (never above it).",
                                "additionalProperties": false,
                                "required": [
                                  "limit",
                                  "charged"
                                ],
                                "properties": {
                                  "limit": {
                                    "type": "integer",
                                    "title": "Limit",
                                    "description": "The most this refresh could charge.",
                                    "examples": [
                                      20
                                    ]
                                  },
                                  "charged": {
                                    "type": "integer",
                                    "title": "Charged",
                                    "description": "Credits charged; 0 for a free re-read.",
                                    "examples": [
                                      12
                                    ]
                                  }
                                }
                              },
                              "rows": {
                                "type": "integer",
                                "title": "Rows",
                                "description": "Listings delivered.",
                                "examples": [
                                  120
                                ]
                              },
                              "trimmed": {
                                "type": "boolean",
                                "title": "Trimmed",
                                "description": "True when the refresh was cut down to fit a cap.",
                                "examples": [
                                  false
                                ]
                              },
                              "freeReread": {
                                "type": "boolean",
                                "title": "Free re-read",
                                "description": "True when identical data was read within 7 days (free).",
                                "examples": [
                                  false
                                ]
                              },
                              "summary": {
                                "type": [
                                  "null",
                                  "object"
                                ],
                                "title": "Change summary",
                                "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                                "additionalProperties": false,
                                "required": [
                                  "first",
                                  "totalNow",
                                  "totalBefore",
                                  "addedCount",
                                  "removedCount",
                                  "changedCount",
                                  "reobservedCount",
                                  "added",
                                  "removed"
                                ],
                                "properties": {
                                  "first": {
                                    "type": "boolean",
                                    "title": "First",
                                    "description": "No earlier refresh to compare with.",
                                    "examples": [
                                      false
                                    ]
                                  },
                                  "totalNow": {
                                    "type": "integer",
                                    "title": "Total now",
                                    "description": "Listings in this refresh.",
                                    "examples": [
                                      120
                                    ]
                                  },
                                  "totalBefore": {
                                    "type": "integer",
                                    "title": "Total before",
                                    "description": "Listings in the previous refresh.",
                                    "examples": [
                                      118
                                    ]
                                  },
                                  "addedCount": {
                                    "type": "integer",
                                    "title": "Added",
                                    "description": "Listings that are new in the results.",
                                    "examples": [
                                      3
                                    ]
                                  },
                                  "removedCount": {
                                    "type": "integer",
                                    "title": "Removed",
                                    "description": "Listings no longer in the results.",
                                    "examples": [
                                      1
                                    ]
                                  },
                                  "changedCount": {
                                    "type": "integer",
                                    "title": "Changed",
                                    "description": "Listings whose title, brand or retailer details changed.",
                                    "examples": [
                                      2
                                    ]
                                  },
                                  "reobservedCount": {
                                    "type": "integer",
                                    "title": "Read again",
                                    "description": "Listings the collectors have read again since.",
                                    "examples": [
                                      40
                                    ]
                                  },
                                  "added": {
                                    "type": "array",
                                    "title": "Added listings",
                                    "description": "Up to 50.",
                                    "items": {
                                      "type": "object",
                                      "additionalProperties": false,
                                      "required": [
                                        "id",
                                        "title"
                                      ],
                                      "properties": {
                                        "id": {
                                          "type": "string",
                                          "title": "Listing id",
                                          "description": "The listing.",
                                          "examples": [
                                            "123"
                                          ]
                                        },
                                        "title": {
                                          "type": [
                                            "null",
                                            "string"
                                          ],
                                          "title": "Title",
                                          "description": "Its title.",
                                          "examples": [
                                            "Aashirvaad Atta 5kg"
                                          ]
                                        }
                                      }
                                    }
                                  },
                                  "removed": {
                                    "type": "array",
                                    "title": "Removed listings",
                                    "description": "Up to 50.",
                                    "items": {
                                      "type": "object",
                                      "additionalProperties": false,
                                      "required": [
                                        "id",
                                        "title"
                                      ],
                                      "properties": {
                                        "id": {
                                          "type": "string",
                                          "title": "Listing id",
                                          "description": "The listing.",
                                          "examples": [
                                            "99"
                                          ]
                                        },
                                        "title": {
                                          "type": [
                                            "null",
                                            "string"
                                          ],
                                          "title": "Title",
                                          "description": "Its title.",
                                          "examples": [
                                            "Old Atta 1kg"
                                          ]
                                        }
                                      }
                                    }
                                  }
                                }
                              },
                              "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "title": "Started",
                                "description": "When it started.",
                                "examples": [
                                  "2026-10-20T10:00:00Z"
                                ]
                              },
                              "finishedAt": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "format": "date-time",
                                "title": "Finished",
                                "description": "When it ended; null while running.",
                                "examples": [
                                  "2026-10-20T10:00:01Z"
                                ]
                              }
                            }
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Created",
                            "description": "When saved.",
                            "examples": [
                              "2026-10-20T10:00:00Z"
                            ]
                          },
                          "updatedAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Updated",
                            "description": "When last changed.",
                            "examples": [
                              "2026-10-20T10:00:00Z"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page info",
                      "description": "Paging.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "Page size.",
                          "examples": [
                            20
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Pass as cursor; null at the end.",
                          "examples": [
                            "eyJvIjoyMH0"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "20"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "1 to 100. Default 20."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJvIjoyMH0"
              ]
            },
            "description": "From page.nextCursor."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Kind",
              "examples": [
                "watch"
              ],
              "pattern": "^(search|watch)$"
            },
            "description": "Only \"search\" or only \"watch\". Anything else is refused."
          }
        ]
      }
    },
    "/v1/saved-searches/refresh-all": {
      "post": {
        "operationId": "refreshAllSavedSearches",
        "summary": "Refresh all active saved searches",
        "description": "Refreshes your active saved searches one after another, newest confirmation first, at most maxSearches (default 10, up to 20), and never more than maxCredits charged in total: each gets the credits still left as its allowance, and one with none left is recorded as skipped (refresh_all_limit). Each also keeps to its own caps. The same idempotency key replays the same refreshes and charges nothing more.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Refresh all answer",
                  "description": "One entry per saved search considered, in order, and the total charged (never above maxCredits).",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Result",
                      "description": "The outcome.",
                      "additionalProperties": false,
                      "required": [
                        "creditsCharged",
                        "maxCredits",
                        "runs"
                      ],
                      "properties": {
                        "creditsCharged": {
                          "type": "integer",
                          "title": "Charged",
                          "description": "Total credits charged by this call.",
                          "examples": [
                            24
                          ]
                        },
                        "maxCredits": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "The limit you set.",
                          "examples": [
                            40
                          ]
                        },
                        "runs": {
                          "type": "array",
                          "title": "Runs",
                          "description": "One per saved search considered.",
                          "items": {
                            "type": "object",
                            "title": "Refresh",
                            "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                            "additionalProperties": false,
                            "required": [
                              "id",
                              "savedSearchId",
                              "trigger",
                              "state",
                              "skipReason",
                              "failureMessage",
                              "credits",
                              "rows",
                              "trimmed",
                              "freeReread",
                              "summary",
                              "startedAt",
                              "finishedAt"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "title": "Id",
                                "description": "The refresh id.",
                                "examples": [
                                  "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                                ]
                              },
                              "savedSearchId": {
                                "type": "string",
                                "title": "Saved search",
                                "description": "Its saved search.",
                                "examples": [
                                  "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                                ]
                              },
                              "trigger": {
                                "type": "string",
                                "enum": [
                                  "manual",
                                  "scheduled"
                                ],
                                "title": "Trigger",
                                "description": "manual or scheduled.",
                                "examples": [
                                  "manual"
                                ]
                              },
                              "state": {
                                "type": "string",
                                "enum": [
                                  "running",
                                  "done",
                                  "skipped",
                                  "failed"
                                ],
                                "title": "State",
                                "description": "running, done, skipped or failed.",
                                "examples": [
                                  "running"
                                ]
                              },
                              "skipReason": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "enum": [
                                  "not_approved",
                                  "paused",
                                  "cancelled",
                                  "insufficient_credits",
                                  "monthly_cap",
                                  "refresh_all_limit",
                                  null
                                ],
                                "title": "Skip reason",
                                "description": "Why it was skipped; null otherwise.",
                                "examples": [
                                  "not_approved"
                                ]
                              },
                              "failureMessage": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Failure",
                                "description": "Why it failed; null otherwise.",
                                "examples": [
                                  "stopped before finishing"
                                ]
                              },
                              "credits": {
                                "type": "object",
                                "title": "Credits",
                                "description": "The cap it ran under and what it charged (never above it).",
                                "additionalProperties": false,
                                "required": [
                                  "limit",
                                  "charged"
                                ],
                                "properties": {
                                  "limit": {
                                    "type": "integer",
                                    "title": "Limit",
                                    "description": "The most this refresh could charge.",
                                    "examples": [
                                      20
                                    ]
                                  },
                                  "charged": {
                                    "type": "integer",
                                    "title": "Charged",
                                    "description": "Credits charged; 0 for a free re-read.",
                                    "examples": [
                                      12
                                    ]
                                  }
                                }
                              },
                              "rows": {
                                "type": "integer",
                                "title": "Rows",
                                "description": "Listings delivered.",
                                "examples": [
                                  120
                                ]
                              },
                              "trimmed": {
                                "type": "boolean",
                                "title": "Trimmed",
                                "description": "True when the refresh was cut down to fit a cap.",
                                "examples": [
                                  false
                                ]
                              },
                              "freeReread": {
                                "type": "boolean",
                                "title": "Free re-read",
                                "description": "True when identical data was read within 7 days (free).",
                                "examples": [
                                  false
                                ]
                              },
                              "summary": {
                                "type": [
                                  "null",
                                  "object"
                                ],
                                "title": "Change summary",
                                "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                                "additionalProperties": false,
                                "required": [
                                  "first",
                                  "totalNow",
                                  "totalBefore",
                                  "addedCount",
                                  "removedCount",
                                  "changedCount",
                                  "reobservedCount",
                                  "added",
                                  "removed"
                                ],
                                "properties": {
                                  "first": {
                                    "type": "boolean",
                                    "title": "First",
                                    "description": "No earlier refresh to compare with.",
                                    "examples": [
                                      false
                                    ]
                                  },
                                  "totalNow": {
                                    "type": "integer",
                                    "title": "Total now",
                                    "description": "Listings in this refresh.",
                                    "examples": [
                                      120
                                    ]
                                  },
                                  "totalBefore": {
                                    "type": "integer",
                                    "title": "Total before",
                                    "description": "Listings in the previous refresh.",
                                    "examples": [
                                      118
                                    ]
                                  },
                                  "addedCount": {
                                    "type": "integer",
                                    "title": "Added",
                                    "description": "Listings that are new in the results.",
                                    "examples": [
                                      3
                                    ]
                                  },
                                  "removedCount": {
                                    "type": "integer",
                                    "title": "Removed",
                                    "description": "Listings no longer in the results.",
                                    "examples": [
                                      1
                                    ]
                                  },
                                  "changedCount": {
                                    "type": "integer",
                                    "title": "Changed",
                                    "description": "Listings whose title, brand or retailer details changed.",
                                    "examples": [
                                      2
                                    ]
                                  },
                                  "reobservedCount": {
                                    "type": "integer",
                                    "title": "Read again",
                                    "description": "Listings the collectors have read again since.",
                                    "examples": [
                                      40
                                    ]
                                  },
                                  "added": {
                                    "type": "array",
                                    "title": "Added listings",
                                    "description": "Up to 50.",
                                    "items": {
                                      "type": "object",
                                      "additionalProperties": false,
                                      "required": [
                                        "id",
                                        "title"
                                      ],
                                      "properties": {
                                        "id": {
                                          "type": "string",
                                          "title": "Listing id",
                                          "description": "The listing.",
                                          "examples": [
                                            "123"
                                          ]
                                        },
                                        "title": {
                                          "type": [
                                            "null",
                                            "string"
                                          ],
                                          "title": "Title",
                                          "description": "Its title.",
                                          "examples": [
                                            "Aashirvaad Atta 5kg"
                                          ]
                                        }
                                      }
                                    }
                                  },
                                  "removed": {
                                    "type": "array",
                                    "title": "Removed listings",
                                    "description": "Up to 50.",
                                    "items": {
                                      "type": "object",
                                      "additionalProperties": false,
                                      "required": [
                                        "id",
                                        "title"
                                      ],
                                      "properties": {
                                        "id": {
                                          "type": "string",
                                          "title": "Listing id",
                                          "description": "The listing.",
                                          "examples": [
                                            "99"
                                          ]
                                        },
                                        "title": {
                                          "type": [
                                            "null",
                                            "string"
                                          ],
                                          "title": "Title",
                                          "description": "Its title.",
                                          "examples": [
                                            "Old Atta 1kg"
                                          ]
                                        }
                                      }
                                    }
                                  }
                                }
                              },
                              "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "title": "Started",
                                "description": "When it started.",
                                "examples": [
                                  "2026-10-20T10:00:00Z"
                                ]
                              },
                              "finishedAt": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "format": "date-time",
                                "title": "Finished",
                                "description": "When it ended; null while running.",
                                "examples": [
                                  "2026-10-20T10:00:01Z"
                                ]
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Refresh all",
                "description": "Refreshes your active saved searches one after another, newest approved first, stopping at your limits. A saved search that would pass maxCredits, or beyond maxSearches, is skipped and recorded, not charged.",
                "additionalProperties": false,
                "required": [
                  "idempotencyKey",
                  "maxCredits"
                ],
                "properties": {
                  "idempotencyKey": {
                    "type": "string",
                    "title": "Idempotency key",
                    "description": "Your own unique key (8 to 128 of letters, digits . _ : -). Sending the same key with the same body again returns the same record; with a different body, idempotency_conflict.",
                    "examples": [
                      "watch-atta-2026-10-20"
                    ],
                    "pattern": "^[A-Za-z0-9._:-]{8,128}$"
                  },
                  "maxCredits": {
                    "type": "integer",
                    "title": "Most credits in total",
                    "description": "Hard stop for this call, whole credits, at least 1.",
                    "examples": [
                      40
                    ],
                    "minimum": 1
                  },
                  "maxSearches": {
                    "type": "integer",
                    "title": "Most saved searches",
                    "description": "1 to 20. Default 10.",
                    "examples": [
                      10
                    ],
                    "minimum": 1,
                    "maximum": 20
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/saved-searches/{id}": {
      "get": {
        "operationId": "getSavedSearch",
        "summary": "Read a saved search or watch",
        "description": "One saved search or watch of your organisation.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Saved search answer",
                  "description": "One saved search.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Saved search or watch",
                      "description": "A saved search or watch, its state, cost, the one confirmation, its next refresh and its last refresh.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "name",
                        "state",
                        "pauseReason",
                        "targets",
                        "maxResults",
                        "frequency",
                        "spendingLimit",
                        "cost",
                        "confirmed",
                        "nextRefreshAt",
                        "spentThisMonthCredits",
                        "notify",
                        "lastRun",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The saved search id.",
                          "examples": [
                            "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "search",
                            "watch"
                          ],
                          "title": "Kind",
                          "description": "search or watch.",
                          "examples": [
                            "search"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "A name you will recognise.",
                          "examples": [
                            "Atta prices, Bengaluru"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "active",
                            "paused",
                            "cancelled"
                          ],
                          "title": "State",
                          "description": "draft (not yet confirmed), active, paused or cancelled.",
                          "examples": [
                            "draft"
                          ]
                        },
                        "pauseReason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            "by_user",
                            "insufficient_credits",
                            "monthly_cap",
                            null
                          ],
                          "title": "Pause reason",
                          "description": "Why it is paused; null otherwise.",
                          "examples": [
                            "by_user"
                          ]
                        },
                        "targets": {
                          "type": "array",
                          "title": "Targets",
                          "description": "What it looks up.",
                          "items": {
                            "type": "object",
                            "title": "Saved target as stored",
                            "description": "A saved target. A location is stored with the exact pins it resolved to when you confirmed it, so later refreshes read those pins, never a broader place.",
                            "additionalProperties": false,
                            "required": [
                              "q",
                              "brand",
                              "retailer",
                              "pincode",
                              "location",
                              "pins"
                            ],
                            "properties": {
                              "q": {
                                "type": "string",
                                "title": "Words",
                                "description": "The words.",
                                "examples": [
                                  "aashirvaad atta"
                                ]
                              },
                              "brand": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Brand",
                                "description": "The brand, or null.",
                                "examples": [
                                  "Aashirvaad"
                                ]
                              },
                              "retailer": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Retailer",
                                "description": "The retailer, or null.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "pincode": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Pin code",
                                "description": "The single pin, or null.",
                                "examples": [
                                  "110092"
                                ]
                              },
                              "location": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Location",
                                "description": "The Core location id, or null.",
                                "examples": [
                                  "IN:city:karnataka:bengaluru"
                                ]
                              },
                              "pins": {
                                "type": [
                                  "null",
                                  "array"
                                ],
                                "title": "Pins",
                                "description": "The pins the location resolved to when confirmed; null without a location.",
                                "items": {
                                  "type": "string",
                                  "examples": [
                                    "560001"
                                  ]
                                }
                              }
                            }
                          }
                        },
                        "maxResults": {
                          "type": "integer",
                          "title": "Rows per target",
                          "description": "The most listings one refresh reads for each target, 1 to 100. Default 50. This bounds the cost ceiling.",
                          "examples": [
                            50
                          ],
                          "minimum": 1,
                          "maximum": 100
                        },
                        "frequency": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Frequency",
                          "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                          "additionalProperties": false,
                          "required": [
                            "kind",
                            "time"
                          ],
                          "properties": {
                            "kind": {
                              "type": "string",
                              "enum": [
                                "daily",
                                "weekly",
                                "monthly"
                              ],
                              "title": "Kind",
                              "description": "daily, weekly or monthly.",
                              "examples": [
                                "daily"
                              ]
                            },
                            "time": {
                              "type": "string",
                              "title": "Time",
                              "description": "HH:MM, 24-hour, Asia/Kolkata.",
                              "examples": [
                                "07:30"
                              ],
                              "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                            },
                            "weekday": {
                              "type": "string",
                              "enum": [
                                "monday",
                                "tuesday",
                                "wednesday",
                                "thursday",
                                "friday",
                                "saturday",
                                "sunday"
                              ],
                              "title": "Weekday",
                              "description": "For weekly.",
                              "examples": [
                                "monday"
                              ]
                            },
                            "dayOfMonth": {
                              "type": "integer",
                              "title": "Day of month",
                              "description": "For monthly, 1 to 28.",
                              "examples": [
                                1
                              ],
                              "minimum": 1,
                              "maximum": 28
                            }
                          }
                        },
                        "spendingLimit": {
                          "type": "object",
                          "title": "Spending caps",
                          "description": "The most credits one refresh may charge, and the most all refreshes may charge in an IST calendar month. A refresh that would pass either is cut down to fit, or skipped and recorded; it is never charged above them.",
                          "additionalProperties": false,
                          "required": [
                            "perRefreshCredits",
                            "perMonthCredits"
                          ],
                          "properties": {
                            "perRefreshCredits": {
                              "type": "integer",
                              "title": "Per refresh",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                20
                              ],
                              "minimum": 1
                            },
                            "perMonthCredits": {
                              "type": "integer",
                              "title": "Per month",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                300
                              ],
                              "minimum": 1
                            }
                          }
                        },
                        "cost": {
                          "type": "object",
                          "title": "Cost",
                          "description": "What a refresh costs, estimated free from what the targets match now, at the published listings rate. The ceiling is the most a refresh can cost (rows per target x targets); you confirm the ceilings.",
                          "additionalProperties": false,
                          "required": [
                            "expectedListings",
                            "perRefreshExpectedCredits",
                            "perRefreshCeilingCredits",
                            "refreshesPerMonth",
                            "perMonthCeilingCredits",
                            "rateVersion",
                            "estimatedAt",
                            "fitsBalance",
                            "withinCaps"
                          ],
                          "properties": {
                            "expectedListings": {
                              "type": "integer",
                              "title": "Expected listings",
                              "description": "About how many listings a refresh reads now.",
                              "examples": [
                                120
                              ]
                            },
                            "perRefreshExpectedCredits": {
                              "type": "integer",
                              "title": "Expected per refresh",
                              "description": "Credits for the expected listings.",
                              "examples": [
                                12
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per refresh",
                              "description": "The most one refresh can cost.",
                              "examples": [
                                50
                              ]
                            },
                            "refreshesPerMonth": {
                              "type": "integer",
                              "title": "Refreshes a month",
                              "description": "At most this many (a search: 1 by hand counts as the caps allow).",
                              "examples": [
                                31
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per month",
                              "description": "Ceiling per refresh x refreshes a month.",
                              "examples": [
                                1550
                              ]
                            },
                            "rateVersion": {
                              "type": "string",
                              "title": "Rate version",
                              "description": "The listings rate card used.",
                              "examples": [
                                "2"
                              ]
                            },
                            "estimatedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Estimated at",
                              "description": "When it was estimated.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "fitsBalance": {
                              "type": "boolean",
                              "title": "Fits balance",
                              "description": "Whether the expected month fits your credits now.",
                              "examples": [
                                true
                              ]
                            },
                            "withinCaps": {
                              "type": "boolean",
                              "title": "Within caps",
                              "description": "Whether the ceilings are inside your caps; if not a refresh is cut to fit.",
                              "examples": [
                                true
                              ]
                            }
                          }
                        },
                        "confirmed": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Confirmation",
                          "description": "Your one confirmation: who, when and the ceilings and caps agreed.",
                          "additionalProperties": false,
                          "required": [
                            "by",
                            "at",
                            "perRefreshCeilingCredits",
                            "perMonthCeilingCredits",
                            "perRefreshCapCredits",
                            "perMonthCapCredits"
                          ],
                          "properties": {
                            "by": {
                              "type": "string",
                              "title": "By",
                              "description": "Who confirmed.",
                              "examples": [
                                "user:abc"
                              ]
                            },
                            "at": {
                              "type": "string",
                              "format": "date-time",
                              "title": "At",
                              "description": "When.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Per refresh ceiling",
                              "description": "Agreed.",
                              "examples": [
                                50
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Per month ceiling",
                              "description": "Agreed.",
                              "examples": [
                                1550
                              ]
                            },
                            "perRefreshCapCredits": {
                              "type": "integer",
                              "title": "Per refresh cap",
                              "description": "Agreed cap.",
                              "examples": [
                                20
                              ]
                            },
                            "perMonthCapCredits": {
                              "type": "integer",
                              "title": "Per month cap",
                              "description": "Agreed cap.",
                              "examples": [
                                300
                              ]
                            }
                          }
                        },
                        "nextRefreshAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Next refresh",
                          "description": "When a watch refreshes next; null otherwise.",
                          "examples": [
                            "2026-10-21T02:00:00Z"
                          ]
                        },
                        "spentThisMonthCredits": {
                          "type": "integer",
                          "title": "Spent this month",
                          "description": "Credits charged by refreshes this IST month.",
                          "examples": [
                            24
                          ]
                        },
                        "notify": {
                          "type": "array",
                          "title": "Notify",
                          "description": "Where this watch sends what changed. An email entry names the destination it resolved to.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "channel",
                              "destinationId"
                            ],
                            "properties": {
                              "channel": {
                                "type": "string",
                                "enum": [
                                  "in_app",
                                  "email",
                                  "slack",
                                  "telegram",
                                  "webhook"
                                ],
                                "title": "Channel",
                                "description": "The channel."
                              },
                              "destinationId": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "pattern": "^dst_[0-9a-f]{32}$",
                                "title": "Destination id",
                                "description": "The destination; null for in_app.",
                                "examples": [
                                  "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
                                ]
                              }
                            }
                          }
                        },
                        "lastRun": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Refresh",
                          "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "savedSearchId",
                            "trigger",
                            "state",
                            "skipReason",
                            "failureMessage",
                            "credits",
                            "rows",
                            "trimmed",
                            "freeReread",
                            "summary",
                            "startedAt",
                            "finishedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "title": "Id",
                              "description": "The refresh id.",
                              "examples": [
                                "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                              ]
                            },
                            "savedSearchId": {
                              "type": "string",
                              "title": "Saved search",
                              "description": "Its saved search.",
                              "examples": [
                                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "scheduled"
                              ],
                              "title": "Trigger",
                              "description": "manual or scheduled.",
                              "examples": [
                                "manual"
                              ]
                            },
                            "state": {
                              "type": "string",
                              "enum": [
                                "running",
                                "done",
                                "skipped",
                                "failed"
                              ],
                              "title": "State",
                              "description": "running, done, skipped or failed.",
                              "examples": [
                                "running"
                              ]
                            },
                            "skipReason": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "enum": [
                                "not_approved",
                                "paused",
                                "cancelled",
                                "insufficient_credits",
                                "monthly_cap",
                                "refresh_all_limit",
                                null
                              ],
                              "title": "Skip reason",
                              "description": "Why it was skipped; null otherwise.",
                              "examples": [
                                "not_approved"
                              ]
                            },
                            "failureMessage": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Failure",
                              "description": "Why it failed; null otherwise.",
                              "examples": [
                                "stopped before finishing"
                              ]
                            },
                            "credits": {
                              "type": "object",
                              "title": "Credits",
                              "description": "The cap it ran under and what it charged (never above it).",
                              "additionalProperties": false,
                              "required": [
                                "limit",
                                "charged"
                              ],
                              "properties": {
                                "limit": {
                                  "type": "integer",
                                  "title": "Limit",
                                  "description": "The most this refresh could charge.",
                                  "examples": [
                                    20
                                  ]
                                },
                                "charged": {
                                  "type": "integer",
                                  "title": "Charged",
                                  "description": "Credits charged; 0 for a free re-read.",
                                  "examples": [
                                    12
                                  ]
                                }
                              }
                            },
                            "rows": {
                              "type": "integer",
                              "title": "Rows",
                              "description": "Listings delivered.",
                              "examples": [
                                120
                              ]
                            },
                            "trimmed": {
                              "type": "boolean",
                              "title": "Trimmed",
                              "description": "True when the refresh was cut down to fit a cap.",
                              "examples": [
                                false
                              ]
                            },
                            "freeReread": {
                              "type": "boolean",
                              "title": "Free re-read",
                              "description": "True when identical data was read within 7 days (free).",
                              "examples": [
                                false
                              ]
                            },
                            "summary": {
                              "type": [
                                "null",
                                "object"
                              ],
                              "title": "Change summary",
                              "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                              "additionalProperties": false,
                              "required": [
                                "first",
                                "totalNow",
                                "totalBefore",
                                "addedCount",
                                "removedCount",
                                "changedCount",
                                "reobservedCount",
                                "added",
                                "removed"
                              ],
                              "properties": {
                                "first": {
                                  "type": "boolean",
                                  "title": "First",
                                  "description": "No earlier refresh to compare with.",
                                  "examples": [
                                    false
                                  ]
                                },
                                "totalNow": {
                                  "type": "integer",
                                  "title": "Total now",
                                  "description": "Listings in this refresh.",
                                  "examples": [
                                    120
                                  ]
                                },
                                "totalBefore": {
                                  "type": "integer",
                                  "title": "Total before",
                                  "description": "Listings in the previous refresh.",
                                  "examples": [
                                    118
                                  ]
                                },
                                "addedCount": {
                                  "type": "integer",
                                  "title": "Added",
                                  "description": "Listings that are new in the results.",
                                  "examples": [
                                    3
                                  ]
                                },
                                "removedCount": {
                                  "type": "integer",
                                  "title": "Removed",
                                  "description": "Listings no longer in the results.",
                                  "examples": [
                                    1
                                  ]
                                },
                                "changedCount": {
                                  "type": "integer",
                                  "title": "Changed",
                                  "description": "Listings whose title, brand or retailer details changed.",
                                  "examples": [
                                    2
                                  ]
                                },
                                "reobservedCount": {
                                  "type": "integer",
                                  "title": "Read again",
                                  "description": "Listings the collectors have read again since.",
                                  "examples": [
                                    40
                                  ]
                                },
                                "added": {
                                  "type": "array",
                                  "title": "Added listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "123"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Aashirvaad Atta 5kg"
                                        ]
                                      }
                                    }
                                  }
                                },
                                "removed": {
                                  "type": "array",
                                  "title": "Removed listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "99"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Old Atta 1kg"
                                        ]
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Started",
                              "description": "When it started.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "finishedAt": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "format": "date-time",
                              "title": "Finished",
                              "description": "When it ended; null while running.",
                              "examples": [
                                "2026-10-20T10:00:01Z"
                              ]
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Created",
                          "description": "When saved.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Updated",
                          "description": "When last changed.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The saved search id.",
              "examples": [
                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
              ],
              "format": "uuid"
            }
          }
        ]
      },
      "patch": {
        "operationId": "updateSavedSearch",
        "summary": "Change a saved search or watch",
        "description": "Any of these. Changing targets, rows per target, frequency or caps returns an active one to draft: confirm the new cost again. A name or notify change does not.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Saved search answer",
                  "description": "One saved search.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Saved search or watch",
                      "description": "A saved search or watch, its state, cost, the one confirmation, its next refresh and its last refresh.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "name",
                        "state",
                        "pauseReason",
                        "targets",
                        "maxResults",
                        "frequency",
                        "spendingLimit",
                        "cost",
                        "confirmed",
                        "nextRefreshAt",
                        "spentThisMonthCredits",
                        "notify",
                        "lastRun",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The saved search id.",
                          "examples": [
                            "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "search",
                            "watch"
                          ],
                          "title": "Kind",
                          "description": "search or watch.",
                          "examples": [
                            "search"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "A name you will recognise.",
                          "examples": [
                            "Atta prices, Bengaluru"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "active",
                            "paused",
                            "cancelled"
                          ],
                          "title": "State",
                          "description": "draft (not yet confirmed), active, paused or cancelled.",
                          "examples": [
                            "draft"
                          ]
                        },
                        "pauseReason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            "by_user",
                            "insufficient_credits",
                            "monthly_cap",
                            null
                          ],
                          "title": "Pause reason",
                          "description": "Why it is paused; null otherwise.",
                          "examples": [
                            "by_user"
                          ]
                        },
                        "targets": {
                          "type": "array",
                          "title": "Targets",
                          "description": "What it looks up.",
                          "items": {
                            "type": "object",
                            "title": "Saved target as stored",
                            "description": "A saved target. A location is stored with the exact pins it resolved to when you confirmed it, so later refreshes read those pins, never a broader place.",
                            "additionalProperties": false,
                            "required": [
                              "q",
                              "brand",
                              "retailer",
                              "pincode",
                              "location",
                              "pins"
                            ],
                            "properties": {
                              "q": {
                                "type": "string",
                                "title": "Words",
                                "description": "The words.",
                                "examples": [
                                  "aashirvaad atta"
                                ]
                              },
                              "brand": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Brand",
                                "description": "The brand, or null.",
                                "examples": [
                                  "Aashirvaad"
                                ]
                              },
                              "retailer": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Retailer",
                                "description": "The retailer, or null.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "pincode": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Pin code",
                                "description": "The single pin, or null.",
                                "examples": [
                                  "110092"
                                ]
                              },
                              "location": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Location",
                                "description": "The Core location id, or null.",
                                "examples": [
                                  "IN:city:karnataka:bengaluru"
                                ]
                              },
                              "pins": {
                                "type": [
                                  "null",
                                  "array"
                                ],
                                "title": "Pins",
                                "description": "The pins the location resolved to when confirmed; null without a location.",
                                "items": {
                                  "type": "string",
                                  "examples": [
                                    "560001"
                                  ]
                                }
                              }
                            }
                          }
                        },
                        "maxResults": {
                          "type": "integer",
                          "title": "Rows per target",
                          "description": "The most listings one refresh reads for each target, 1 to 100. Default 50. This bounds the cost ceiling.",
                          "examples": [
                            50
                          ],
                          "minimum": 1,
                          "maximum": 100
                        },
                        "frequency": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Frequency",
                          "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                          "additionalProperties": false,
                          "required": [
                            "kind",
                            "time"
                          ],
                          "properties": {
                            "kind": {
                              "type": "string",
                              "enum": [
                                "daily",
                                "weekly",
                                "monthly"
                              ],
                              "title": "Kind",
                              "description": "daily, weekly or monthly.",
                              "examples": [
                                "daily"
                              ]
                            },
                            "time": {
                              "type": "string",
                              "title": "Time",
                              "description": "HH:MM, 24-hour, Asia/Kolkata.",
                              "examples": [
                                "07:30"
                              ],
                              "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                            },
                            "weekday": {
                              "type": "string",
                              "enum": [
                                "monday",
                                "tuesday",
                                "wednesday",
                                "thursday",
                                "friday",
                                "saturday",
                                "sunday"
                              ],
                              "title": "Weekday",
                              "description": "For weekly.",
                              "examples": [
                                "monday"
                              ]
                            },
                            "dayOfMonth": {
                              "type": "integer",
                              "title": "Day of month",
                              "description": "For monthly, 1 to 28.",
                              "examples": [
                                1
                              ],
                              "minimum": 1,
                              "maximum": 28
                            }
                          }
                        },
                        "spendingLimit": {
                          "type": "object",
                          "title": "Spending caps",
                          "description": "The most credits one refresh may charge, and the most all refreshes may charge in an IST calendar month. A refresh that would pass either is cut down to fit, or skipped and recorded; it is never charged above them.",
                          "additionalProperties": false,
                          "required": [
                            "perRefreshCredits",
                            "perMonthCredits"
                          ],
                          "properties": {
                            "perRefreshCredits": {
                              "type": "integer",
                              "title": "Per refresh",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                20
                              ],
                              "minimum": 1
                            },
                            "perMonthCredits": {
                              "type": "integer",
                              "title": "Per month",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                300
                              ],
                              "minimum": 1
                            }
                          }
                        },
                        "cost": {
                          "type": "object",
                          "title": "Cost",
                          "description": "What a refresh costs, estimated free from what the targets match now, at the published listings rate. The ceiling is the most a refresh can cost (rows per target x targets); you confirm the ceilings.",
                          "additionalProperties": false,
                          "required": [
                            "expectedListings",
                            "perRefreshExpectedCredits",
                            "perRefreshCeilingCredits",
                            "refreshesPerMonth",
                            "perMonthCeilingCredits",
                            "rateVersion",
                            "estimatedAt",
                            "fitsBalance",
                            "withinCaps"
                          ],
                          "properties": {
                            "expectedListings": {
                              "type": "integer",
                              "title": "Expected listings",
                              "description": "About how many listings a refresh reads now.",
                              "examples": [
                                120
                              ]
                            },
                            "perRefreshExpectedCredits": {
                              "type": "integer",
                              "title": "Expected per refresh",
                              "description": "Credits for the expected listings.",
                              "examples": [
                                12
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per refresh",
                              "description": "The most one refresh can cost.",
                              "examples": [
                                50
                              ]
                            },
                            "refreshesPerMonth": {
                              "type": "integer",
                              "title": "Refreshes a month",
                              "description": "At most this many (a search: 1 by hand counts as the caps allow).",
                              "examples": [
                                31
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per month",
                              "description": "Ceiling per refresh x refreshes a month.",
                              "examples": [
                                1550
                              ]
                            },
                            "rateVersion": {
                              "type": "string",
                              "title": "Rate version",
                              "description": "The listings rate card used.",
                              "examples": [
                                "2"
                              ]
                            },
                            "estimatedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Estimated at",
                              "description": "When it was estimated.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "fitsBalance": {
                              "type": "boolean",
                              "title": "Fits balance",
                              "description": "Whether the expected month fits your credits now.",
                              "examples": [
                                true
                              ]
                            },
                            "withinCaps": {
                              "type": "boolean",
                              "title": "Within caps",
                              "description": "Whether the ceilings are inside your caps; if not a refresh is cut to fit.",
                              "examples": [
                                true
                              ]
                            }
                          }
                        },
                        "confirmed": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Confirmation",
                          "description": "Your one confirmation: who, when and the ceilings and caps agreed.",
                          "additionalProperties": false,
                          "required": [
                            "by",
                            "at",
                            "perRefreshCeilingCredits",
                            "perMonthCeilingCredits",
                            "perRefreshCapCredits",
                            "perMonthCapCredits"
                          ],
                          "properties": {
                            "by": {
                              "type": "string",
                              "title": "By",
                              "description": "Who confirmed.",
                              "examples": [
                                "user:abc"
                              ]
                            },
                            "at": {
                              "type": "string",
                              "format": "date-time",
                              "title": "At",
                              "description": "When.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Per refresh ceiling",
                              "description": "Agreed.",
                              "examples": [
                                50
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Per month ceiling",
                              "description": "Agreed.",
                              "examples": [
                                1550
                              ]
                            },
                            "perRefreshCapCredits": {
                              "type": "integer",
                              "title": "Per refresh cap",
                              "description": "Agreed cap.",
                              "examples": [
                                20
                              ]
                            },
                            "perMonthCapCredits": {
                              "type": "integer",
                              "title": "Per month cap",
                              "description": "Agreed cap.",
                              "examples": [
                                300
                              ]
                            }
                          }
                        },
                        "nextRefreshAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Next refresh",
                          "description": "When a watch refreshes next; null otherwise.",
                          "examples": [
                            "2026-10-21T02:00:00Z"
                          ]
                        },
                        "spentThisMonthCredits": {
                          "type": "integer",
                          "title": "Spent this month",
                          "description": "Credits charged by refreshes this IST month.",
                          "examples": [
                            24
                          ]
                        },
                        "notify": {
                          "type": "array",
                          "title": "Notify",
                          "description": "Where this watch sends what changed. An email entry names the destination it resolved to.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "channel",
                              "destinationId"
                            ],
                            "properties": {
                              "channel": {
                                "type": "string",
                                "enum": [
                                  "in_app",
                                  "email",
                                  "slack",
                                  "telegram",
                                  "webhook"
                                ],
                                "title": "Channel",
                                "description": "The channel."
                              },
                              "destinationId": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "pattern": "^dst_[0-9a-f]{32}$",
                                "title": "Destination id",
                                "description": "The destination; null for in_app.",
                                "examples": [
                                  "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
                                ]
                              }
                            }
                          }
                        },
                        "lastRun": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Refresh",
                          "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "savedSearchId",
                            "trigger",
                            "state",
                            "skipReason",
                            "failureMessage",
                            "credits",
                            "rows",
                            "trimmed",
                            "freeReread",
                            "summary",
                            "startedAt",
                            "finishedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "title": "Id",
                              "description": "The refresh id.",
                              "examples": [
                                "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                              ]
                            },
                            "savedSearchId": {
                              "type": "string",
                              "title": "Saved search",
                              "description": "Its saved search.",
                              "examples": [
                                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "scheduled"
                              ],
                              "title": "Trigger",
                              "description": "manual or scheduled.",
                              "examples": [
                                "manual"
                              ]
                            },
                            "state": {
                              "type": "string",
                              "enum": [
                                "running",
                                "done",
                                "skipped",
                                "failed"
                              ],
                              "title": "State",
                              "description": "running, done, skipped or failed.",
                              "examples": [
                                "running"
                              ]
                            },
                            "skipReason": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "enum": [
                                "not_approved",
                                "paused",
                                "cancelled",
                                "insufficient_credits",
                                "monthly_cap",
                                "refresh_all_limit",
                                null
                              ],
                              "title": "Skip reason",
                              "description": "Why it was skipped; null otherwise.",
                              "examples": [
                                "not_approved"
                              ]
                            },
                            "failureMessage": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Failure",
                              "description": "Why it failed; null otherwise.",
                              "examples": [
                                "stopped before finishing"
                              ]
                            },
                            "credits": {
                              "type": "object",
                              "title": "Credits",
                              "description": "The cap it ran under and what it charged (never above it).",
                              "additionalProperties": false,
                              "required": [
                                "limit",
                                "charged"
                              ],
                              "properties": {
                                "limit": {
                                  "type": "integer",
                                  "title": "Limit",
                                  "description": "The most this refresh could charge.",
                                  "examples": [
                                    20
                                  ]
                                },
                                "charged": {
                                  "type": "integer",
                                  "title": "Charged",
                                  "description": "Credits charged; 0 for a free re-read.",
                                  "examples": [
                                    12
                                  ]
                                }
                              }
                            },
                            "rows": {
                              "type": "integer",
                              "title": "Rows",
                              "description": "Listings delivered.",
                              "examples": [
                                120
                              ]
                            },
                            "trimmed": {
                              "type": "boolean",
                              "title": "Trimmed",
                              "description": "True when the refresh was cut down to fit a cap.",
                              "examples": [
                                false
                              ]
                            },
                            "freeReread": {
                              "type": "boolean",
                              "title": "Free re-read",
                              "description": "True when identical data was read within 7 days (free).",
                              "examples": [
                                false
                              ]
                            },
                            "summary": {
                              "type": [
                                "null",
                                "object"
                              ],
                              "title": "Change summary",
                              "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                              "additionalProperties": false,
                              "required": [
                                "first",
                                "totalNow",
                                "totalBefore",
                                "addedCount",
                                "removedCount",
                                "changedCount",
                                "reobservedCount",
                                "added",
                                "removed"
                              ],
                              "properties": {
                                "first": {
                                  "type": "boolean",
                                  "title": "First",
                                  "description": "No earlier refresh to compare with.",
                                  "examples": [
                                    false
                                  ]
                                },
                                "totalNow": {
                                  "type": "integer",
                                  "title": "Total now",
                                  "description": "Listings in this refresh.",
                                  "examples": [
                                    120
                                  ]
                                },
                                "totalBefore": {
                                  "type": "integer",
                                  "title": "Total before",
                                  "description": "Listings in the previous refresh.",
                                  "examples": [
                                    118
                                  ]
                                },
                                "addedCount": {
                                  "type": "integer",
                                  "title": "Added",
                                  "description": "Listings that are new in the results.",
                                  "examples": [
                                    3
                                  ]
                                },
                                "removedCount": {
                                  "type": "integer",
                                  "title": "Removed",
                                  "description": "Listings no longer in the results.",
                                  "examples": [
                                    1
                                  ]
                                },
                                "changedCount": {
                                  "type": "integer",
                                  "title": "Changed",
                                  "description": "Listings whose title, brand or retailer details changed.",
                                  "examples": [
                                    2
                                  ]
                                },
                                "reobservedCount": {
                                  "type": "integer",
                                  "title": "Read again",
                                  "description": "Listings the collectors have read again since.",
                                  "examples": [
                                    40
                                  ]
                                },
                                "added": {
                                  "type": "array",
                                  "title": "Added listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "123"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Aashirvaad Atta 5kg"
                                        ]
                                      }
                                    }
                                  }
                                },
                                "removed": {
                                  "type": "array",
                                  "title": "Removed listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "99"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Old Atta 1kg"
                                        ]
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Started",
                              "description": "When it started.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "finishedAt": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "format": "date-time",
                              "title": "Finished",
                              "description": "When it ended; null while running.",
                              "examples": [
                                "2026-10-20T10:00:01Z"
                              ]
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Created",
                          "description": "When saved.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Updated",
                          "description": "When last changed.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The saved search id.",
              "examples": [
                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
              ],
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Change a saved search",
                "description": "Any of these. Changing targets, rows per target, frequency or caps returns an active one to draft: confirm the new cost again. A name or notify change does not.",
                "additionalProperties": false,
                "required": [],
                "properties": {
                  "name": {
                    "type": "string",
                    "title": "Name",
                    "description": "A name you will recognise.",
                    "examples": [
                      "Atta prices, Bengaluru"
                    ],
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "targets": {
                    "type": "array",
                    "title": "Targets",
                    "description": "1 to 10 things to look up.",
                    "items": {
                      "type": "object",
                      "title": "Saved target",
                      "description": "One thing to look up: product words, optionally one brand, one retailer, and one place (a pin code, or a Core location id with your confirmPins consent).",
                      "additionalProperties": false,
                      "required": [
                        "q"
                      ],
                      "properties": {
                        "q": {
                          "type": "string",
                          "title": "Words",
                          "description": "Name, brand or retailer product id words (as in listings search).",
                          "examples": [
                            "aashirvaad atta"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "brand": {
                          "type": "string",
                          "title": "Brand",
                          "description": "Only this exact brand.",
                          "examples": [
                            "Aashirvaad"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "retailer": {
                          "type": "string",
                          "title": "Retailer",
                          "description": "Only this retailer.",
                          "examples": [
                            "blinkit"
                          ],
                          "minLength": 1,
                          "maxLength": 100
                        },
                        "pincode": {
                          "type": "string",
                          "title": "Pin code",
                          "description": "Only listings read at this six-digit pin in the last 30 days.",
                          "examples": [
                            "110092"
                          ],
                          "pattern": "^[1-9][0-9]{5}$"
                        },
                        "location": {
                          "type": "string",
                          "title": "Location",
                          "description": "A Core location id from the free lookup (GET /v1/data/locations, /cities or /stores): a pin, a city, an area or a dark store. It resolves to an explicit list of pin codes (see GET /v1/data/locations/filter). Never combine with pincode. More than one pin needs confirmPins. A store id (IN:store:<retailer>:<store id>) means the pin codes that dark store serves (its catchment as the sweeps saw it). Readings are kept per pin code, not per store, so it reads every kept reading at those pin codes, whichever store served them; no reading is attributed to the store itself.",
                          "examples": [
                            "IN:city:karnataka:bengaluru"
                          ],
                          "pattern": "^[A-Z]{2}:(pin:[1-9][0-9]{5}|city:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}|area:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}:[a-z0-9]{1,120}|store:[a-z0-9_]{2,40}:[A-Za-z0-9_-]{1,64})$"
                        },
                        "confirmPins": {
                          "type": "string",
                          "title": "Confirm pins",
                          "description": "Your consent to a multi-pin read: the number of pins the location resolves to, as GET /v1/data/locations/filter showed it. A different number is refused with the current count, so a place is never silently broadened.",
                          "examples": [
                            "112"
                          ],
                          "pattern": "^[1-9][0-9]{0,2}$"
                        }
                      }
                    },
                    "minItems": 1,
                    "maxItems": 10
                  },
                  "maxResults": {
                    "type": "integer",
                    "title": "Rows per target",
                    "description": "The most listings one refresh reads for each target, 1 to 100. Default 50. This bounds the cost ceiling.",
                    "examples": [
                      50
                    ],
                    "minimum": 1,
                    "maximum": 100
                  },
                  "frequency": {
                    "type": "object",
                    "title": "Frequency",
                    "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                    "additionalProperties": false,
                    "required": [
                      "kind",
                      "time"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "enum": [
                          "daily",
                          "weekly",
                          "monthly"
                        ],
                        "title": "Kind",
                        "description": "daily, weekly or monthly.",
                        "examples": [
                          "daily"
                        ]
                      },
                      "time": {
                        "type": "string",
                        "title": "Time",
                        "description": "HH:MM, 24-hour, Asia/Kolkata.",
                        "examples": [
                          "07:30"
                        ],
                        "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                      },
                      "weekday": {
                        "type": "string",
                        "enum": [
                          "monday",
                          "tuesday",
                          "wednesday",
                          "thursday",
                          "friday",
                          "saturday",
                          "sunday"
                        ],
                        "title": "Weekday",
                        "description": "For weekly.",
                        "examples": [
                          "monday"
                        ]
                      },
                      "dayOfMonth": {
                        "type": "integer",
                        "title": "Day of month",
                        "description": "For monthly, 1 to 28.",
                        "examples": [
                          1
                        ],
                        "minimum": 1,
                        "maximum": 28
                      }
                    }
                  },
                  "spendingLimit": {
                    "type": "object",
                    "title": "Spending caps",
                    "description": "The most credits one refresh may charge, and the most all refreshes may charge in an IST calendar month. A refresh that would pass either is cut down to fit, or skipped and recorded; it is never charged above them.",
                    "additionalProperties": false,
                    "required": [
                      "perRefreshCredits",
                      "perMonthCredits"
                    ],
                    "properties": {
                      "perRefreshCredits": {
                        "type": "integer",
                        "title": "Per refresh",
                        "description": "Whole credits, at least 1.",
                        "examples": [
                          20
                        ],
                        "minimum": 1
                      },
                      "perMonthCredits": {
                        "type": "integer",
                        "title": "Per month",
                        "description": "Whole credits, at least 1.",
                        "examples": [
                          300
                        ],
                        "minimum": 1
                      }
                    }
                  },
                  "notify": {
                    "$ref": "#/components/schemas/WatchNotify"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/saved-searches/{id}/activate": {
      "post": {
        "operationId": "activateSavedSearch",
        "summary": "Confirm the cost once and start",
        "description": "The ceilings you were shown (cost.perRefreshCeilingCredits and cost.perMonthCeilingCredits). They must equal the current ones, otherwise cost_changed with the new cost. This is the standing approval: from now on refreshes run without asking, within the caps.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Saved search answer",
                  "description": "One saved search.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Saved search or watch",
                      "description": "A saved search or watch, its state, cost, the one confirmation, its next refresh and its last refresh.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "name",
                        "state",
                        "pauseReason",
                        "targets",
                        "maxResults",
                        "frequency",
                        "spendingLimit",
                        "cost",
                        "confirmed",
                        "nextRefreshAt",
                        "spentThisMonthCredits",
                        "notify",
                        "lastRun",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The saved search id.",
                          "examples": [
                            "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "search",
                            "watch"
                          ],
                          "title": "Kind",
                          "description": "search or watch.",
                          "examples": [
                            "search"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "A name you will recognise.",
                          "examples": [
                            "Atta prices, Bengaluru"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "active",
                            "paused",
                            "cancelled"
                          ],
                          "title": "State",
                          "description": "draft (not yet confirmed), active, paused or cancelled.",
                          "examples": [
                            "draft"
                          ]
                        },
                        "pauseReason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            "by_user",
                            "insufficient_credits",
                            "monthly_cap",
                            null
                          ],
                          "title": "Pause reason",
                          "description": "Why it is paused; null otherwise.",
                          "examples": [
                            "by_user"
                          ]
                        },
                        "targets": {
                          "type": "array",
                          "title": "Targets",
                          "description": "What it looks up.",
                          "items": {
                            "type": "object",
                            "title": "Saved target as stored",
                            "description": "A saved target. A location is stored with the exact pins it resolved to when you confirmed it, so later refreshes read those pins, never a broader place.",
                            "additionalProperties": false,
                            "required": [
                              "q",
                              "brand",
                              "retailer",
                              "pincode",
                              "location",
                              "pins"
                            ],
                            "properties": {
                              "q": {
                                "type": "string",
                                "title": "Words",
                                "description": "The words.",
                                "examples": [
                                  "aashirvaad atta"
                                ]
                              },
                              "brand": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Brand",
                                "description": "The brand, or null.",
                                "examples": [
                                  "Aashirvaad"
                                ]
                              },
                              "retailer": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Retailer",
                                "description": "The retailer, or null.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "pincode": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Pin code",
                                "description": "The single pin, or null.",
                                "examples": [
                                  "110092"
                                ]
                              },
                              "location": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Location",
                                "description": "The Core location id, or null.",
                                "examples": [
                                  "IN:city:karnataka:bengaluru"
                                ]
                              },
                              "pins": {
                                "type": [
                                  "null",
                                  "array"
                                ],
                                "title": "Pins",
                                "description": "The pins the location resolved to when confirmed; null without a location.",
                                "items": {
                                  "type": "string",
                                  "examples": [
                                    "560001"
                                  ]
                                }
                              }
                            }
                          }
                        },
                        "maxResults": {
                          "type": "integer",
                          "title": "Rows per target",
                          "description": "The most listings one refresh reads for each target, 1 to 100. Default 50. This bounds the cost ceiling.",
                          "examples": [
                            50
                          ],
                          "minimum": 1,
                          "maximum": 100
                        },
                        "frequency": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Frequency",
                          "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                          "additionalProperties": false,
                          "required": [
                            "kind",
                            "time"
                          ],
                          "properties": {
                            "kind": {
                              "type": "string",
                              "enum": [
                                "daily",
                                "weekly",
                                "monthly"
                              ],
                              "title": "Kind",
                              "description": "daily, weekly or monthly.",
                              "examples": [
                                "daily"
                              ]
                            },
                            "time": {
                              "type": "string",
                              "title": "Time",
                              "description": "HH:MM, 24-hour, Asia/Kolkata.",
                              "examples": [
                                "07:30"
                              ],
                              "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                            },
                            "weekday": {
                              "type": "string",
                              "enum": [
                                "monday",
                                "tuesday",
                                "wednesday",
                                "thursday",
                                "friday",
                                "saturday",
                                "sunday"
                              ],
                              "title": "Weekday",
                              "description": "For weekly.",
                              "examples": [
                                "monday"
                              ]
                            },
                            "dayOfMonth": {
                              "type": "integer",
                              "title": "Day of month",
                              "description": "For monthly, 1 to 28.",
                              "examples": [
                                1
                              ],
                              "minimum": 1,
                              "maximum": 28
                            }
                          }
                        },
                        "spendingLimit": {
                          "type": "object",
                          "title": "Spending caps",
                          "description": "The most credits one refresh may charge, and the most all refreshes may charge in an IST calendar month. A refresh that would pass either is cut down to fit, or skipped and recorded; it is never charged above them.",
                          "additionalProperties": false,
                          "required": [
                            "perRefreshCredits",
                            "perMonthCredits"
                          ],
                          "properties": {
                            "perRefreshCredits": {
                              "type": "integer",
                              "title": "Per refresh",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                20
                              ],
                              "minimum": 1
                            },
                            "perMonthCredits": {
                              "type": "integer",
                              "title": "Per month",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                300
                              ],
                              "minimum": 1
                            }
                          }
                        },
                        "cost": {
                          "type": "object",
                          "title": "Cost",
                          "description": "What a refresh costs, estimated free from what the targets match now, at the published listings rate. The ceiling is the most a refresh can cost (rows per target x targets); you confirm the ceilings.",
                          "additionalProperties": false,
                          "required": [
                            "expectedListings",
                            "perRefreshExpectedCredits",
                            "perRefreshCeilingCredits",
                            "refreshesPerMonth",
                            "perMonthCeilingCredits",
                            "rateVersion",
                            "estimatedAt",
                            "fitsBalance",
                            "withinCaps"
                          ],
                          "properties": {
                            "expectedListings": {
                              "type": "integer",
                              "title": "Expected listings",
                              "description": "About how many listings a refresh reads now.",
                              "examples": [
                                120
                              ]
                            },
                            "perRefreshExpectedCredits": {
                              "type": "integer",
                              "title": "Expected per refresh",
                              "description": "Credits for the expected listings.",
                              "examples": [
                                12
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per refresh",
                              "description": "The most one refresh can cost.",
                              "examples": [
                                50
                              ]
                            },
                            "refreshesPerMonth": {
                              "type": "integer",
                              "title": "Refreshes a month",
                              "description": "At most this many (a search: 1 by hand counts as the caps allow).",
                              "examples": [
                                31
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per month",
                              "description": "Ceiling per refresh x refreshes a month.",
                              "examples": [
                                1550
                              ]
                            },
                            "rateVersion": {
                              "type": "string",
                              "title": "Rate version",
                              "description": "The listings rate card used.",
                              "examples": [
                                "2"
                              ]
                            },
                            "estimatedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Estimated at",
                              "description": "When it was estimated.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "fitsBalance": {
                              "type": "boolean",
                              "title": "Fits balance",
                              "description": "Whether the expected month fits your credits now.",
                              "examples": [
                                true
                              ]
                            },
                            "withinCaps": {
                              "type": "boolean",
                              "title": "Within caps",
                              "description": "Whether the ceilings are inside your caps; if not a refresh is cut to fit.",
                              "examples": [
                                true
                              ]
                            }
                          }
                        },
                        "confirmed": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Confirmation",
                          "description": "Your one confirmation: who, when and the ceilings and caps agreed.",
                          "additionalProperties": false,
                          "required": [
                            "by",
                            "at",
                            "perRefreshCeilingCredits",
                            "perMonthCeilingCredits",
                            "perRefreshCapCredits",
                            "perMonthCapCredits"
                          ],
                          "properties": {
                            "by": {
                              "type": "string",
                              "title": "By",
                              "description": "Who confirmed.",
                              "examples": [
                                "user:abc"
                              ]
                            },
                            "at": {
                              "type": "string",
                              "format": "date-time",
                              "title": "At",
                              "description": "When.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Per refresh ceiling",
                              "description": "Agreed.",
                              "examples": [
                                50
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Per month ceiling",
                              "description": "Agreed.",
                              "examples": [
                                1550
                              ]
                            },
                            "perRefreshCapCredits": {
                              "type": "integer",
                              "title": "Per refresh cap",
                              "description": "Agreed cap.",
                              "examples": [
                                20
                              ]
                            },
                            "perMonthCapCredits": {
                              "type": "integer",
                              "title": "Per month cap",
                              "description": "Agreed cap.",
                              "examples": [
                                300
                              ]
                            }
                          }
                        },
                        "nextRefreshAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Next refresh",
                          "description": "When a watch refreshes next; null otherwise.",
                          "examples": [
                            "2026-10-21T02:00:00Z"
                          ]
                        },
                        "spentThisMonthCredits": {
                          "type": "integer",
                          "title": "Spent this month",
                          "description": "Credits charged by refreshes this IST month.",
                          "examples": [
                            24
                          ]
                        },
                        "notify": {
                          "type": "array",
                          "title": "Notify",
                          "description": "Where this watch sends what changed. An email entry names the destination it resolved to.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "channel",
                              "destinationId"
                            ],
                            "properties": {
                              "channel": {
                                "type": "string",
                                "enum": [
                                  "in_app",
                                  "email",
                                  "slack",
                                  "telegram",
                                  "webhook"
                                ],
                                "title": "Channel",
                                "description": "The channel."
                              },
                              "destinationId": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "pattern": "^dst_[0-9a-f]{32}$",
                                "title": "Destination id",
                                "description": "The destination; null for in_app.",
                                "examples": [
                                  "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
                                ]
                              }
                            }
                          }
                        },
                        "lastRun": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Refresh",
                          "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "savedSearchId",
                            "trigger",
                            "state",
                            "skipReason",
                            "failureMessage",
                            "credits",
                            "rows",
                            "trimmed",
                            "freeReread",
                            "summary",
                            "startedAt",
                            "finishedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "title": "Id",
                              "description": "The refresh id.",
                              "examples": [
                                "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                              ]
                            },
                            "savedSearchId": {
                              "type": "string",
                              "title": "Saved search",
                              "description": "Its saved search.",
                              "examples": [
                                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "scheduled"
                              ],
                              "title": "Trigger",
                              "description": "manual or scheduled.",
                              "examples": [
                                "manual"
                              ]
                            },
                            "state": {
                              "type": "string",
                              "enum": [
                                "running",
                                "done",
                                "skipped",
                                "failed"
                              ],
                              "title": "State",
                              "description": "running, done, skipped or failed.",
                              "examples": [
                                "running"
                              ]
                            },
                            "skipReason": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "enum": [
                                "not_approved",
                                "paused",
                                "cancelled",
                                "insufficient_credits",
                                "monthly_cap",
                                "refresh_all_limit",
                                null
                              ],
                              "title": "Skip reason",
                              "description": "Why it was skipped; null otherwise.",
                              "examples": [
                                "not_approved"
                              ]
                            },
                            "failureMessage": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Failure",
                              "description": "Why it failed; null otherwise.",
                              "examples": [
                                "stopped before finishing"
                              ]
                            },
                            "credits": {
                              "type": "object",
                              "title": "Credits",
                              "description": "The cap it ran under and what it charged (never above it).",
                              "additionalProperties": false,
                              "required": [
                                "limit",
                                "charged"
                              ],
                              "properties": {
                                "limit": {
                                  "type": "integer",
                                  "title": "Limit",
                                  "description": "The most this refresh could charge.",
                                  "examples": [
                                    20
                                  ]
                                },
                                "charged": {
                                  "type": "integer",
                                  "title": "Charged",
                                  "description": "Credits charged; 0 for a free re-read.",
                                  "examples": [
                                    12
                                  ]
                                }
                              }
                            },
                            "rows": {
                              "type": "integer",
                              "title": "Rows",
                              "description": "Listings delivered.",
                              "examples": [
                                120
                              ]
                            },
                            "trimmed": {
                              "type": "boolean",
                              "title": "Trimmed",
                              "description": "True when the refresh was cut down to fit a cap.",
                              "examples": [
                                false
                              ]
                            },
                            "freeReread": {
                              "type": "boolean",
                              "title": "Free re-read",
                              "description": "True when identical data was read within 7 days (free).",
                              "examples": [
                                false
                              ]
                            },
                            "summary": {
                              "type": [
                                "null",
                                "object"
                              ],
                              "title": "Change summary",
                              "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                              "additionalProperties": false,
                              "required": [
                                "first",
                                "totalNow",
                                "totalBefore",
                                "addedCount",
                                "removedCount",
                                "changedCount",
                                "reobservedCount",
                                "added",
                                "removed"
                              ],
                              "properties": {
                                "first": {
                                  "type": "boolean",
                                  "title": "First",
                                  "description": "No earlier refresh to compare with.",
                                  "examples": [
                                    false
                                  ]
                                },
                                "totalNow": {
                                  "type": "integer",
                                  "title": "Total now",
                                  "description": "Listings in this refresh.",
                                  "examples": [
                                    120
                                  ]
                                },
                                "totalBefore": {
                                  "type": "integer",
                                  "title": "Total before",
                                  "description": "Listings in the previous refresh.",
                                  "examples": [
                                    118
                                  ]
                                },
                                "addedCount": {
                                  "type": "integer",
                                  "title": "Added",
                                  "description": "Listings that are new in the results.",
                                  "examples": [
                                    3
                                  ]
                                },
                                "removedCount": {
                                  "type": "integer",
                                  "title": "Removed",
                                  "description": "Listings no longer in the results.",
                                  "examples": [
                                    1
                                  ]
                                },
                                "changedCount": {
                                  "type": "integer",
                                  "title": "Changed",
                                  "description": "Listings whose title, brand or retailer details changed.",
                                  "examples": [
                                    2
                                  ]
                                },
                                "reobservedCount": {
                                  "type": "integer",
                                  "title": "Read again",
                                  "description": "Listings the collectors have read again since.",
                                  "examples": [
                                    40
                                  ]
                                },
                                "added": {
                                  "type": "array",
                                  "title": "Added listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "123"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Aashirvaad Atta 5kg"
                                        ]
                                      }
                                    }
                                  }
                                },
                                "removed": {
                                  "type": "array",
                                  "title": "Removed listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "99"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Old Atta 1kg"
                                        ]
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Started",
                              "description": "When it started.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "finishedAt": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "format": "date-time",
                              "title": "Finished",
                              "description": "When it ended; null while running.",
                              "examples": [
                                "2026-10-20T10:00:01Z"
                              ]
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Created",
                          "description": "When saved.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Updated",
                          "description": "When last changed.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `cost_changed`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The saved search id.",
              "examples": [
                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
              ],
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Confirm the cost once",
                "description": "The ceilings you were shown (cost.perRefreshCeilingCredits and cost.perMonthCeilingCredits). They must equal the current ones, otherwise cost_changed with the new cost. This is the standing approval: from now on refreshes run without asking, within the caps.",
                "additionalProperties": false,
                "required": [
                  "perRefreshCeilingCredits",
                  "perMonthCeilingCredits"
                ],
                "properties": {
                  "perRefreshCeilingCredits": {
                    "type": "integer",
                    "title": "Per refresh ceiling",
                    "description": "The cost.perRefreshCeilingCredits being confirmed.",
                    "examples": [
                      10
                    ]
                  },
                  "perMonthCeilingCredits": {
                    "type": "integer",
                    "title": "Per month ceiling",
                    "description": "The cost.perMonthCeilingCredits being confirmed.",
                    "examples": [
                      310
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/saved-searches/{id}/cancel": {
      "post": {
        "operationId": "cancelSavedSearch",
        "summary": "Cancel a saved search or watch",
        "description": "Ends it for good. Its refresh history stays.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Saved search answer",
                  "description": "One saved search.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Saved search or watch",
                      "description": "A saved search or watch, its state, cost, the one confirmation, its next refresh and its last refresh.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "name",
                        "state",
                        "pauseReason",
                        "targets",
                        "maxResults",
                        "frequency",
                        "spendingLimit",
                        "cost",
                        "confirmed",
                        "nextRefreshAt",
                        "spentThisMonthCredits",
                        "notify",
                        "lastRun",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The saved search id.",
                          "examples": [
                            "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "search",
                            "watch"
                          ],
                          "title": "Kind",
                          "description": "search or watch.",
                          "examples": [
                            "search"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "A name you will recognise.",
                          "examples": [
                            "Atta prices, Bengaluru"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "active",
                            "paused",
                            "cancelled"
                          ],
                          "title": "State",
                          "description": "draft (not yet confirmed), active, paused or cancelled.",
                          "examples": [
                            "draft"
                          ]
                        },
                        "pauseReason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            "by_user",
                            "insufficient_credits",
                            "monthly_cap",
                            null
                          ],
                          "title": "Pause reason",
                          "description": "Why it is paused; null otherwise.",
                          "examples": [
                            "by_user"
                          ]
                        },
                        "targets": {
                          "type": "array",
                          "title": "Targets",
                          "description": "What it looks up.",
                          "items": {
                            "type": "object",
                            "title": "Saved target as stored",
                            "description": "A saved target. A location is stored with the exact pins it resolved to when you confirmed it, so later refreshes read those pins, never a broader place.",
                            "additionalProperties": false,
                            "required": [
                              "q",
                              "brand",
                              "retailer",
                              "pincode",
                              "location",
                              "pins"
                            ],
                            "properties": {
                              "q": {
                                "type": "string",
                                "title": "Words",
                                "description": "The words.",
                                "examples": [
                                  "aashirvaad atta"
                                ]
                              },
                              "brand": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Brand",
                                "description": "The brand, or null.",
                                "examples": [
                                  "Aashirvaad"
                                ]
                              },
                              "retailer": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Retailer",
                                "description": "The retailer, or null.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "pincode": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Pin code",
                                "description": "The single pin, or null.",
                                "examples": [
                                  "110092"
                                ]
                              },
                              "location": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Location",
                                "description": "The Core location id, or null.",
                                "examples": [
                                  "IN:city:karnataka:bengaluru"
                                ]
                              },
                              "pins": {
                                "type": [
                                  "null",
                                  "array"
                                ],
                                "title": "Pins",
                                "description": "The pins the location resolved to when confirmed; null without a location.",
                                "items": {
                                  "type": "string",
                                  "examples": [
                                    "560001"
                                  ]
                                }
                              }
                            }
                          }
                        },
                        "maxResults": {
                          "type": "integer",
                          "title": "Rows per target",
                          "description": "The most listings one refresh reads for each target, 1 to 100. Default 50. This bounds the cost ceiling.",
                          "examples": [
                            50
                          ],
                          "minimum": 1,
                          "maximum": 100
                        },
                        "frequency": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Frequency",
                          "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                          "additionalProperties": false,
                          "required": [
                            "kind",
                            "time"
                          ],
                          "properties": {
                            "kind": {
                              "type": "string",
                              "enum": [
                                "daily",
                                "weekly",
                                "monthly"
                              ],
                              "title": "Kind",
                              "description": "daily, weekly or monthly.",
                              "examples": [
                                "daily"
                              ]
                            },
                            "time": {
                              "type": "string",
                              "title": "Time",
                              "description": "HH:MM, 24-hour, Asia/Kolkata.",
                              "examples": [
                                "07:30"
                              ],
                              "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                            },
                            "weekday": {
                              "type": "string",
                              "enum": [
                                "monday",
                                "tuesday",
                                "wednesday",
                                "thursday",
                                "friday",
                                "saturday",
                                "sunday"
                              ],
                              "title": "Weekday",
                              "description": "For weekly.",
                              "examples": [
                                "monday"
                              ]
                            },
                            "dayOfMonth": {
                              "type": "integer",
                              "title": "Day of month",
                              "description": "For monthly, 1 to 28.",
                              "examples": [
                                1
                              ],
                              "minimum": 1,
                              "maximum": 28
                            }
                          }
                        },
                        "spendingLimit": {
                          "type": "object",
                          "title": "Spending caps",
                          "description": "The most credits one refresh may charge, and the most all refreshes may charge in an IST calendar month. A refresh that would pass either is cut down to fit, or skipped and recorded; it is never charged above them.",
                          "additionalProperties": false,
                          "required": [
                            "perRefreshCredits",
                            "perMonthCredits"
                          ],
                          "properties": {
                            "perRefreshCredits": {
                              "type": "integer",
                              "title": "Per refresh",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                20
                              ],
                              "minimum": 1
                            },
                            "perMonthCredits": {
                              "type": "integer",
                              "title": "Per month",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                300
                              ],
                              "minimum": 1
                            }
                          }
                        },
                        "cost": {
                          "type": "object",
                          "title": "Cost",
                          "description": "What a refresh costs, estimated free from what the targets match now, at the published listings rate. The ceiling is the most a refresh can cost (rows per target x targets); you confirm the ceilings.",
                          "additionalProperties": false,
                          "required": [
                            "expectedListings",
                            "perRefreshExpectedCredits",
                            "perRefreshCeilingCredits",
                            "refreshesPerMonth",
                            "perMonthCeilingCredits",
                            "rateVersion",
                            "estimatedAt",
                            "fitsBalance",
                            "withinCaps"
                          ],
                          "properties": {
                            "expectedListings": {
                              "type": "integer",
                              "title": "Expected listings",
                              "description": "About how many listings a refresh reads now.",
                              "examples": [
                                120
                              ]
                            },
                            "perRefreshExpectedCredits": {
                              "type": "integer",
                              "title": "Expected per refresh",
                              "description": "Credits for the expected listings.",
                              "examples": [
                                12
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per refresh",
                              "description": "The most one refresh can cost.",
                              "examples": [
                                50
                              ]
                            },
                            "refreshesPerMonth": {
                              "type": "integer",
                              "title": "Refreshes a month",
                              "description": "At most this many (a search: 1 by hand counts as the caps allow).",
                              "examples": [
                                31
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per month",
                              "description": "Ceiling per refresh x refreshes a month.",
                              "examples": [
                                1550
                              ]
                            },
                            "rateVersion": {
                              "type": "string",
                              "title": "Rate version",
                              "description": "The listings rate card used.",
                              "examples": [
                                "2"
                              ]
                            },
                            "estimatedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Estimated at",
                              "description": "When it was estimated.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "fitsBalance": {
                              "type": "boolean",
                              "title": "Fits balance",
                              "description": "Whether the expected month fits your credits now.",
                              "examples": [
                                true
                              ]
                            },
                            "withinCaps": {
                              "type": "boolean",
                              "title": "Within caps",
                              "description": "Whether the ceilings are inside your caps; if not a refresh is cut to fit.",
                              "examples": [
                                true
                              ]
                            }
                          }
                        },
                        "confirmed": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Confirmation",
                          "description": "Your one confirmation: who, when and the ceilings and caps agreed.",
                          "additionalProperties": false,
                          "required": [
                            "by",
                            "at",
                            "perRefreshCeilingCredits",
                            "perMonthCeilingCredits",
                            "perRefreshCapCredits",
                            "perMonthCapCredits"
                          ],
                          "properties": {
                            "by": {
                              "type": "string",
                              "title": "By",
                              "description": "Who confirmed.",
                              "examples": [
                                "user:abc"
                              ]
                            },
                            "at": {
                              "type": "string",
                              "format": "date-time",
                              "title": "At",
                              "description": "When.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Per refresh ceiling",
                              "description": "Agreed.",
                              "examples": [
                                50
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Per month ceiling",
                              "description": "Agreed.",
                              "examples": [
                                1550
                              ]
                            },
                            "perRefreshCapCredits": {
                              "type": "integer",
                              "title": "Per refresh cap",
                              "description": "Agreed cap.",
                              "examples": [
                                20
                              ]
                            },
                            "perMonthCapCredits": {
                              "type": "integer",
                              "title": "Per month cap",
                              "description": "Agreed cap.",
                              "examples": [
                                300
                              ]
                            }
                          }
                        },
                        "nextRefreshAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Next refresh",
                          "description": "When a watch refreshes next; null otherwise.",
                          "examples": [
                            "2026-10-21T02:00:00Z"
                          ]
                        },
                        "spentThisMonthCredits": {
                          "type": "integer",
                          "title": "Spent this month",
                          "description": "Credits charged by refreshes this IST month.",
                          "examples": [
                            24
                          ]
                        },
                        "notify": {
                          "type": "array",
                          "title": "Notify",
                          "description": "Where this watch sends what changed. An email entry names the destination it resolved to.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "channel",
                              "destinationId"
                            ],
                            "properties": {
                              "channel": {
                                "type": "string",
                                "enum": [
                                  "in_app",
                                  "email",
                                  "slack",
                                  "telegram",
                                  "webhook"
                                ],
                                "title": "Channel",
                                "description": "The channel."
                              },
                              "destinationId": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "pattern": "^dst_[0-9a-f]{32}$",
                                "title": "Destination id",
                                "description": "The destination; null for in_app.",
                                "examples": [
                                  "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
                                ]
                              }
                            }
                          }
                        },
                        "lastRun": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Refresh",
                          "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "savedSearchId",
                            "trigger",
                            "state",
                            "skipReason",
                            "failureMessage",
                            "credits",
                            "rows",
                            "trimmed",
                            "freeReread",
                            "summary",
                            "startedAt",
                            "finishedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "title": "Id",
                              "description": "The refresh id.",
                              "examples": [
                                "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                              ]
                            },
                            "savedSearchId": {
                              "type": "string",
                              "title": "Saved search",
                              "description": "Its saved search.",
                              "examples": [
                                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "scheduled"
                              ],
                              "title": "Trigger",
                              "description": "manual or scheduled.",
                              "examples": [
                                "manual"
                              ]
                            },
                            "state": {
                              "type": "string",
                              "enum": [
                                "running",
                                "done",
                                "skipped",
                                "failed"
                              ],
                              "title": "State",
                              "description": "running, done, skipped or failed.",
                              "examples": [
                                "running"
                              ]
                            },
                            "skipReason": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "enum": [
                                "not_approved",
                                "paused",
                                "cancelled",
                                "insufficient_credits",
                                "monthly_cap",
                                "refresh_all_limit",
                                null
                              ],
                              "title": "Skip reason",
                              "description": "Why it was skipped; null otherwise.",
                              "examples": [
                                "not_approved"
                              ]
                            },
                            "failureMessage": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Failure",
                              "description": "Why it failed; null otherwise.",
                              "examples": [
                                "stopped before finishing"
                              ]
                            },
                            "credits": {
                              "type": "object",
                              "title": "Credits",
                              "description": "The cap it ran under and what it charged (never above it).",
                              "additionalProperties": false,
                              "required": [
                                "limit",
                                "charged"
                              ],
                              "properties": {
                                "limit": {
                                  "type": "integer",
                                  "title": "Limit",
                                  "description": "The most this refresh could charge.",
                                  "examples": [
                                    20
                                  ]
                                },
                                "charged": {
                                  "type": "integer",
                                  "title": "Charged",
                                  "description": "Credits charged; 0 for a free re-read.",
                                  "examples": [
                                    12
                                  ]
                                }
                              }
                            },
                            "rows": {
                              "type": "integer",
                              "title": "Rows",
                              "description": "Listings delivered.",
                              "examples": [
                                120
                              ]
                            },
                            "trimmed": {
                              "type": "boolean",
                              "title": "Trimmed",
                              "description": "True when the refresh was cut down to fit a cap.",
                              "examples": [
                                false
                              ]
                            },
                            "freeReread": {
                              "type": "boolean",
                              "title": "Free re-read",
                              "description": "True when identical data was read within 7 days (free).",
                              "examples": [
                                false
                              ]
                            },
                            "summary": {
                              "type": [
                                "null",
                                "object"
                              ],
                              "title": "Change summary",
                              "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                              "additionalProperties": false,
                              "required": [
                                "first",
                                "totalNow",
                                "totalBefore",
                                "addedCount",
                                "removedCount",
                                "changedCount",
                                "reobservedCount",
                                "added",
                                "removed"
                              ],
                              "properties": {
                                "first": {
                                  "type": "boolean",
                                  "title": "First",
                                  "description": "No earlier refresh to compare with.",
                                  "examples": [
                                    false
                                  ]
                                },
                                "totalNow": {
                                  "type": "integer",
                                  "title": "Total now",
                                  "description": "Listings in this refresh.",
                                  "examples": [
                                    120
                                  ]
                                },
                                "totalBefore": {
                                  "type": "integer",
                                  "title": "Total before",
                                  "description": "Listings in the previous refresh.",
                                  "examples": [
                                    118
                                  ]
                                },
                                "addedCount": {
                                  "type": "integer",
                                  "title": "Added",
                                  "description": "Listings that are new in the results.",
                                  "examples": [
                                    3
                                  ]
                                },
                                "removedCount": {
                                  "type": "integer",
                                  "title": "Removed",
                                  "description": "Listings no longer in the results.",
                                  "examples": [
                                    1
                                  ]
                                },
                                "changedCount": {
                                  "type": "integer",
                                  "title": "Changed",
                                  "description": "Listings whose title, brand or retailer details changed.",
                                  "examples": [
                                    2
                                  ]
                                },
                                "reobservedCount": {
                                  "type": "integer",
                                  "title": "Read again",
                                  "description": "Listings the collectors have read again since.",
                                  "examples": [
                                    40
                                  ]
                                },
                                "added": {
                                  "type": "array",
                                  "title": "Added listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "123"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Aashirvaad Atta 5kg"
                                        ]
                                      }
                                    }
                                  }
                                },
                                "removed": {
                                  "type": "array",
                                  "title": "Removed listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "99"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Old Atta 1kg"
                                        ]
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Started",
                              "description": "When it started.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "finishedAt": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "format": "date-time",
                              "title": "Finished",
                              "description": "When it ended; null while running.",
                              "examples": [
                                "2026-10-20T10:00:01Z"
                              ]
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Created",
                          "description": "When saved.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Updated",
                          "description": "When last changed.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The saved search id.",
              "examples": [
                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
              ],
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/saved-searches/{id}/deliveries": {
      "get": {
        "operationId": "listWatchDeliveries",
        "summary": "The alert delivery log of a saved search",
        "description": "Each alert this watch sent or tried to send, newest first: the destination, sent / failed (with why) / queued (quiet hours) / skipped (a preference turned it off), and when. A failed send never stops the check. Delivery is free.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WatchDeliveriesPage"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The saved search id.",
              "examples": [
                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
              ],
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "20"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "1 to 100. Default 20."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJvIjoyMH0"
              ]
            },
            "description": "From page.nextCursor."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Kind",
              "examples": [
                "watch"
              ],
              "pattern": "^(search|watch)$"
            },
            "description": "Only \"search\" or only \"watch\". Anything else is refused."
          }
        ]
      }
    },
    "/v1/saved-searches/{id}/pause": {
      "post": {
        "operationId": "pauseSavedSearch",
        "summary": "Pause a saved search or watch",
        "description": "Stops refreshes (by hand and by schedule) until you resume. Nothing is lost; the approval stays.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Saved search answer",
                  "description": "One saved search.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Saved search or watch",
                      "description": "A saved search or watch, its state, cost, the one confirmation, its next refresh and its last refresh.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "name",
                        "state",
                        "pauseReason",
                        "targets",
                        "maxResults",
                        "frequency",
                        "spendingLimit",
                        "cost",
                        "confirmed",
                        "nextRefreshAt",
                        "spentThisMonthCredits",
                        "notify",
                        "lastRun",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The saved search id.",
                          "examples": [
                            "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "search",
                            "watch"
                          ],
                          "title": "Kind",
                          "description": "search or watch.",
                          "examples": [
                            "search"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "A name you will recognise.",
                          "examples": [
                            "Atta prices, Bengaluru"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "active",
                            "paused",
                            "cancelled"
                          ],
                          "title": "State",
                          "description": "draft (not yet confirmed), active, paused or cancelled.",
                          "examples": [
                            "draft"
                          ]
                        },
                        "pauseReason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            "by_user",
                            "insufficient_credits",
                            "monthly_cap",
                            null
                          ],
                          "title": "Pause reason",
                          "description": "Why it is paused; null otherwise.",
                          "examples": [
                            "by_user"
                          ]
                        },
                        "targets": {
                          "type": "array",
                          "title": "Targets",
                          "description": "What it looks up.",
                          "items": {
                            "type": "object",
                            "title": "Saved target as stored",
                            "description": "A saved target. A location is stored with the exact pins it resolved to when you confirmed it, so later refreshes read those pins, never a broader place.",
                            "additionalProperties": false,
                            "required": [
                              "q",
                              "brand",
                              "retailer",
                              "pincode",
                              "location",
                              "pins"
                            ],
                            "properties": {
                              "q": {
                                "type": "string",
                                "title": "Words",
                                "description": "The words.",
                                "examples": [
                                  "aashirvaad atta"
                                ]
                              },
                              "brand": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Brand",
                                "description": "The brand, or null.",
                                "examples": [
                                  "Aashirvaad"
                                ]
                              },
                              "retailer": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Retailer",
                                "description": "The retailer, or null.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "pincode": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Pin code",
                                "description": "The single pin, or null.",
                                "examples": [
                                  "110092"
                                ]
                              },
                              "location": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Location",
                                "description": "The Core location id, or null.",
                                "examples": [
                                  "IN:city:karnataka:bengaluru"
                                ]
                              },
                              "pins": {
                                "type": [
                                  "null",
                                  "array"
                                ],
                                "title": "Pins",
                                "description": "The pins the location resolved to when confirmed; null without a location.",
                                "items": {
                                  "type": "string",
                                  "examples": [
                                    "560001"
                                  ]
                                }
                              }
                            }
                          }
                        },
                        "maxResults": {
                          "type": "integer",
                          "title": "Rows per target",
                          "description": "The most listings one refresh reads for each target, 1 to 100. Default 50. This bounds the cost ceiling.",
                          "examples": [
                            50
                          ],
                          "minimum": 1,
                          "maximum": 100
                        },
                        "frequency": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Frequency",
                          "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                          "additionalProperties": false,
                          "required": [
                            "kind",
                            "time"
                          ],
                          "properties": {
                            "kind": {
                              "type": "string",
                              "enum": [
                                "daily",
                                "weekly",
                                "monthly"
                              ],
                              "title": "Kind",
                              "description": "daily, weekly or monthly.",
                              "examples": [
                                "daily"
                              ]
                            },
                            "time": {
                              "type": "string",
                              "title": "Time",
                              "description": "HH:MM, 24-hour, Asia/Kolkata.",
                              "examples": [
                                "07:30"
                              ],
                              "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                            },
                            "weekday": {
                              "type": "string",
                              "enum": [
                                "monday",
                                "tuesday",
                                "wednesday",
                                "thursday",
                                "friday",
                                "saturday",
                                "sunday"
                              ],
                              "title": "Weekday",
                              "description": "For weekly.",
                              "examples": [
                                "monday"
                              ]
                            },
                            "dayOfMonth": {
                              "type": "integer",
                              "title": "Day of month",
                              "description": "For monthly, 1 to 28.",
                              "examples": [
                                1
                              ],
                              "minimum": 1,
                              "maximum": 28
                            }
                          }
                        },
                        "spendingLimit": {
                          "type": "object",
                          "title": "Spending caps",
                          "description": "The most credits one refresh may charge, and the most all refreshes may charge in an IST calendar month. A refresh that would pass either is cut down to fit, or skipped and recorded; it is never charged above them.",
                          "additionalProperties": false,
                          "required": [
                            "perRefreshCredits",
                            "perMonthCredits"
                          ],
                          "properties": {
                            "perRefreshCredits": {
                              "type": "integer",
                              "title": "Per refresh",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                20
                              ],
                              "minimum": 1
                            },
                            "perMonthCredits": {
                              "type": "integer",
                              "title": "Per month",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                300
                              ],
                              "minimum": 1
                            }
                          }
                        },
                        "cost": {
                          "type": "object",
                          "title": "Cost",
                          "description": "What a refresh costs, estimated free from what the targets match now, at the published listings rate. The ceiling is the most a refresh can cost (rows per target x targets); you confirm the ceilings.",
                          "additionalProperties": false,
                          "required": [
                            "expectedListings",
                            "perRefreshExpectedCredits",
                            "perRefreshCeilingCredits",
                            "refreshesPerMonth",
                            "perMonthCeilingCredits",
                            "rateVersion",
                            "estimatedAt",
                            "fitsBalance",
                            "withinCaps"
                          ],
                          "properties": {
                            "expectedListings": {
                              "type": "integer",
                              "title": "Expected listings",
                              "description": "About how many listings a refresh reads now.",
                              "examples": [
                                120
                              ]
                            },
                            "perRefreshExpectedCredits": {
                              "type": "integer",
                              "title": "Expected per refresh",
                              "description": "Credits for the expected listings.",
                              "examples": [
                                12
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per refresh",
                              "description": "The most one refresh can cost.",
                              "examples": [
                                50
                              ]
                            },
                            "refreshesPerMonth": {
                              "type": "integer",
                              "title": "Refreshes a month",
                              "description": "At most this many (a search: 1 by hand counts as the caps allow).",
                              "examples": [
                                31
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per month",
                              "description": "Ceiling per refresh x refreshes a month.",
                              "examples": [
                                1550
                              ]
                            },
                            "rateVersion": {
                              "type": "string",
                              "title": "Rate version",
                              "description": "The listings rate card used.",
                              "examples": [
                                "2"
                              ]
                            },
                            "estimatedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Estimated at",
                              "description": "When it was estimated.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "fitsBalance": {
                              "type": "boolean",
                              "title": "Fits balance",
                              "description": "Whether the expected month fits your credits now.",
                              "examples": [
                                true
                              ]
                            },
                            "withinCaps": {
                              "type": "boolean",
                              "title": "Within caps",
                              "description": "Whether the ceilings are inside your caps; if not a refresh is cut to fit.",
                              "examples": [
                                true
                              ]
                            }
                          }
                        },
                        "confirmed": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Confirmation",
                          "description": "Your one confirmation: who, when and the ceilings and caps agreed.",
                          "additionalProperties": false,
                          "required": [
                            "by",
                            "at",
                            "perRefreshCeilingCredits",
                            "perMonthCeilingCredits",
                            "perRefreshCapCredits",
                            "perMonthCapCredits"
                          ],
                          "properties": {
                            "by": {
                              "type": "string",
                              "title": "By",
                              "description": "Who confirmed.",
                              "examples": [
                                "user:abc"
                              ]
                            },
                            "at": {
                              "type": "string",
                              "format": "date-time",
                              "title": "At",
                              "description": "When.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Per refresh ceiling",
                              "description": "Agreed.",
                              "examples": [
                                50
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Per month ceiling",
                              "description": "Agreed.",
                              "examples": [
                                1550
                              ]
                            },
                            "perRefreshCapCredits": {
                              "type": "integer",
                              "title": "Per refresh cap",
                              "description": "Agreed cap.",
                              "examples": [
                                20
                              ]
                            },
                            "perMonthCapCredits": {
                              "type": "integer",
                              "title": "Per month cap",
                              "description": "Agreed cap.",
                              "examples": [
                                300
                              ]
                            }
                          }
                        },
                        "nextRefreshAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Next refresh",
                          "description": "When a watch refreshes next; null otherwise.",
                          "examples": [
                            "2026-10-21T02:00:00Z"
                          ]
                        },
                        "spentThisMonthCredits": {
                          "type": "integer",
                          "title": "Spent this month",
                          "description": "Credits charged by refreshes this IST month.",
                          "examples": [
                            24
                          ]
                        },
                        "notify": {
                          "type": "array",
                          "title": "Notify",
                          "description": "Where this watch sends what changed. An email entry names the destination it resolved to.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "channel",
                              "destinationId"
                            ],
                            "properties": {
                              "channel": {
                                "type": "string",
                                "enum": [
                                  "in_app",
                                  "email",
                                  "slack",
                                  "telegram",
                                  "webhook"
                                ],
                                "title": "Channel",
                                "description": "The channel."
                              },
                              "destinationId": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "pattern": "^dst_[0-9a-f]{32}$",
                                "title": "Destination id",
                                "description": "The destination; null for in_app.",
                                "examples": [
                                  "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
                                ]
                              }
                            }
                          }
                        },
                        "lastRun": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Refresh",
                          "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "savedSearchId",
                            "trigger",
                            "state",
                            "skipReason",
                            "failureMessage",
                            "credits",
                            "rows",
                            "trimmed",
                            "freeReread",
                            "summary",
                            "startedAt",
                            "finishedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "title": "Id",
                              "description": "The refresh id.",
                              "examples": [
                                "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                              ]
                            },
                            "savedSearchId": {
                              "type": "string",
                              "title": "Saved search",
                              "description": "Its saved search.",
                              "examples": [
                                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "scheduled"
                              ],
                              "title": "Trigger",
                              "description": "manual or scheduled.",
                              "examples": [
                                "manual"
                              ]
                            },
                            "state": {
                              "type": "string",
                              "enum": [
                                "running",
                                "done",
                                "skipped",
                                "failed"
                              ],
                              "title": "State",
                              "description": "running, done, skipped or failed.",
                              "examples": [
                                "running"
                              ]
                            },
                            "skipReason": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "enum": [
                                "not_approved",
                                "paused",
                                "cancelled",
                                "insufficient_credits",
                                "monthly_cap",
                                "refresh_all_limit",
                                null
                              ],
                              "title": "Skip reason",
                              "description": "Why it was skipped; null otherwise.",
                              "examples": [
                                "not_approved"
                              ]
                            },
                            "failureMessage": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Failure",
                              "description": "Why it failed; null otherwise.",
                              "examples": [
                                "stopped before finishing"
                              ]
                            },
                            "credits": {
                              "type": "object",
                              "title": "Credits",
                              "description": "The cap it ran under and what it charged (never above it).",
                              "additionalProperties": false,
                              "required": [
                                "limit",
                                "charged"
                              ],
                              "properties": {
                                "limit": {
                                  "type": "integer",
                                  "title": "Limit",
                                  "description": "The most this refresh could charge.",
                                  "examples": [
                                    20
                                  ]
                                },
                                "charged": {
                                  "type": "integer",
                                  "title": "Charged",
                                  "description": "Credits charged; 0 for a free re-read.",
                                  "examples": [
                                    12
                                  ]
                                }
                              }
                            },
                            "rows": {
                              "type": "integer",
                              "title": "Rows",
                              "description": "Listings delivered.",
                              "examples": [
                                120
                              ]
                            },
                            "trimmed": {
                              "type": "boolean",
                              "title": "Trimmed",
                              "description": "True when the refresh was cut down to fit a cap.",
                              "examples": [
                                false
                              ]
                            },
                            "freeReread": {
                              "type": "boolean",
                              "title": "Free re-read",
                              "description": "True when identical data was read within 7 days (free).",
                              "examples": [
                                false
                              ]
                            },
                            "summary": {
                              "type": [
                                "null",
                                "object"
                              ],
                              "title": "Change summary",
                              "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                              "additionalProperties": false,
                              "required": [
                                "first",
                                "totalNow",
                                "totalBefore",
                                "addedCount",
                                "removedCount",
                                "changedCount",
                                "reobservedCount",
                                "added",
                                "removed"
                              ],
                              "properties": {
                                "first": {
                                  "type": "boolean",
                                  "title": "First",
                                  "description": "No earlier refresh to compare with.",
                                  "examples": [
                                    false
                                  ]
                                },
                                "totalNow": {
                                  "type": "integer",
                                  "title": "Total now",
                                  "description": "Listings in this refresh.",
                                  "examples": [
                                    120
                                  ]
                                },
                                "totalBefore": {
                                  "type": "integer",
                                  "title": "Total before",
                                  "description": "Listings in the previous refresh.",
                                  "examples": [
                                    118
                                  ]
                                },
                                "addedCount": {
                                  "type": "integer",
                                  "title": "Added",
                                  "description": "Listings that are new in the results.",
                                  "examples": [
                                    3
                                  ]
                                },
                                "removedCount": {
                                  "type": "integer",
                                  "title": "Removed",
                                  "description": "Listings no longer in the results.",
                                  "examples": [
                                    1
                                  ]
                                },
                                "changedCount": {
                                  "type": "integer",
                                  "title": "Changed",
                                  "description": "Listings whose title, brand or retailer details changed.",
                                  "examples": [
                                    2
                                  ]
                                },
                                "reobservedCount": {
                                  "type": "integer",
                                  "title": "Read again",
                                  "description": "Listings the collectors have read again since.",
                                  "examples": [
                                    40
                                  ]
                                },
                                "added": {
                                  "type": "array",
                                  "title": "Added listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "123"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Aashirvaad Atta 5kg"
                                        ]
                                      }
                                    }
                                  }
                                },
                                "removed": {
                                  "type": "array",
                                  "title": "Removed listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "99"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Old Atta 1kg"
                                        ]
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Started",
                              "description": "When it started.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "finishedAt": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "format": "date-time",
                              "title": "Finished",
                              "description": "When it ended; null while running.",
                              "examples": [
                                "2026-10-20T10:00:01Z"
                              ]
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Created",
                          "description": "When saved.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Updated",
                          "description": "When last changed.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The saved search id.",
              "examples": [
                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
              ],
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/saved-searches/{id}/refresh": {
      "post": {
        "operationId": "refreshSavedSearch",
        "summary": "Refresh a saved search now",
        "description": "Reads the Library for each target and charges like a listings read, never above the per-refresh cap or what is left of the monthly cap (the rows are cut to fit, trimmed = true). Runs only when the saved search is active with your confirmation; otherwise it is recorded as skipped and nothing is charged. The same idempotency key is the same refresh and settles once. The answer carries the change summary since the previous refresh.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Refresh answer",
                  "description": "One refresh.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Refresh",
                      "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "savedSearchId",
                        "trigger",
                        "state",
                        "skipReason",
                        "failureMessage",
                        "credits",
                        "rows",
                        "trimmed",
                        "freeReread",
                        "summary",
                        "startedAt",
                        "finishedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The refresh id.",
                          "examples": [
                            "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                          ]
                        },
                        "savedSearchId": {
                          "type": "string",
                          "title": "Saved search",
                          "description": "Its saved search.",
                          "examples": [
                            "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                          ]
                        },
                        "trigger": {
                          "type": "string",
                          "enum": [
                            "manual",
                            "scheduled"
                          ],
                          "title": "Trigger",
                          "description": "manual or scheduled.",
                          "examples": [
                            "manual"
                          ]
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "running",
                            "done",
                            "skipped",
                            "failed"
                          ],
                          "title": "State",
                          "description": "running, done, skipped or failed.",
                          "examples": [
                            "running"
                          ]
                        },
                        "skipReason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            "not_approved",
                            "paused",
                            "cancelled",
                            "insufficient_credits",
                            "monthly_cap",
                            "refresh_all_limit",
                            null
                          ],
                          "title": "Skip reason",
                          "description": "Why it was skipped; null otherwise.",
                          "examples": [
                            "not_approved"
                          ]
                        },
                        "failureMessage": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Failure",
                          "description": "Why it failed; null otherwise.",
                          "examples": [
                            "stopped before finishing"
                          ]
                        },
                        "credits": {
                          "type": "object",
                          "title": "Credits",
                          "description": "The cap it ran under and what it charged (never above it).",
                          "additionalProperties": false,
                          "required": [
                            "limit",
                            "charged"
                          ],
                          "properties": {
                            "limit": {
                              "type": "integer",
                              "title": "Limit",
                              "description": "The most this refresh could charge.",
                              "examples": [
                                20
                              ]
                            },
                            "charged": {
                              "type": "integer",
                              "title": "Charged",
                              "description": "Credits charged; 0 for a free re-read.",
                              "examples": [
                                12
                              ]
                            }
                          }
                        },
                        "rows": {
                          "type": "integer",
                          "title": "Rows",
                          "description": "Listings delivered.",
                          "examples": [
                            120
                          ]
                        },
                        "trimmed": {
                          "type": "boolean",
                          "title": "Trimmed",
                          "description": "True when the refresh was cut down to fit a cap.",
                          "examples": [
                            false
                          ]
                        },
                        "freeReread": {
                          "type": "boolean",
                          "title": "Free re-read",
                          "description": "True when identical data was read within 7 days (free).",
                          "examples": [
                            false
                          ]
                        },
                        "summary": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Change summary",
                          "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                          "additionalProperties": false,
                          "required": [
                            "first",
                            "totalNow",
                            "totalBefore",
                            "addedCount",
                            "removedCount",
                            "changedCount",
                            "reobservedCount",
                            "added",
                            "removed"
                          ],
                          "properties": {
                            "first": {
                              "type": "boolean",
                              "title": "First",
                              "description": "No earlier refresh to compare with.",
                              "examples": [
                                false
                              ]
                            },
                            "totalNow": {
                              "type": "integer",
                              "title": "Total now",
                              "description": "Listings in this refresh.",
                              "examples": [
                                120
                              ]
                            },
                            "totalBefore": {
                              "type": "integer",
                              "title": "Total before",
                              "description": "Listings in the previous refresh.",
                              "examples": [
                                118
                              ]
                            },
                            "addedCount": {
                              "type": "integer",
                              "title": "Added",
                              "description": "Listings that are new in the results.",
                              "examples": [
                                3
                              ]
                            },
                            "removedCount": {
                              "type": "integer",
                              "title": "Removed",
                              "description": "Listings no longer in the results.",
                              "examples": [
                                1
                              ]
                            },
                            "changedCount": {
                              "type": "integer",
                              "title": "Changed",
                              "description": "Listings whose title, brand or retailer details changed.",
                              "examples": [
                                2
                              ]
                            },
                            "reobservedCount": {
                              "type": "integer",
                              "title": "Read again",
                              "description": "Listings the collectors have read again since.",
                              "examples": [
                                40
                              ]
                            },
                            "added": {
                              "type": "array",
                              "title": "Added listings",
                              "description": "Up to 50.",
                              "items": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                  "id",
                                  "title"
                                ],
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "title": "Listing id",
                                    "description": "The listing.",
                                    "examples": [
                                      "123"
                                    ]
                                  },
                                  "title": {
                                    "type": [
                                      "null",
                                      "string"
                                    ],
                                    "title": "Title",
                                    "description": "Its title.",
                                    "examples": [
                                      "Aashirvaad Atta 5kg"
                                    ]
                                  }
                                }
                              }
                            },
                            "removed": {
                              "type": "array",
                              "title": "Removed listings",
                              "description": "Up to 50.",
                              "items": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                  "id",
                                  "title"
                                ],
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "title": "Listing id",
                                    "description": "The listing.",
                                    "examples": [
                                      "99"
                                    ]
                                  },
                                  "title": {
                                    "type": [
                                      "null",
                                      "string"
                                    ],
                                    "title": "Title",
                                    "description": "Its title.",
                                    "examples": [
                                      "Old Atta 1kg"
                                    ]
                                  }
                                }
                              }
                            }
                          }
                        },
                        "startedAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Started",
                          "description": "When it started.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        },
                        "finishedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Finished",
                          "description": "When it ended; null while running.",
                          "examples": [
                            "2026-10-20T10:00:01Z"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `plan_required`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The saved search id.",
              "examples": [
                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
              ],
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Refresh now",
                "description": "Refreshes one active saved search now. The same idempotency key is the same refresh: it settles once.",
                "additionalProperties": false,
                "required": [
                  "idempotencyKey"
                ],
                "properties": {
                  "idempotencyKey": {
                    "type": "string",
                    "title": "Idempotency key",
                    "description": "Your own unique key (8 to 128 of letters, digits . _ : -). Sending the same key with the same body again returns the same record; with a different body, idempotency_conflict.",
                    "examples": [
                      "watch-atta-2026-10-20"
                    ],
                    "pattern": "^[A-Za-z0-9._:-]{8,128}$"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/saved-searches/{id}/resume": {
      "post": {
        "operationId": "resumeSavedSearch",
        "summary": "Resume a paused saved search or watch",
        "description": "Starts again within the same approval. If the cost or caps have changed since you confirmed, it stays paused and says so: activate it again.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Saved search answer",
                  "description": "One saved search.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Saved search or watch",
                      "description": "A saved search or watch, its state, cost, the one confirmation, its next refresh and its last refresh.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "kind",
                        "name",
                        "state",
                        "pauseReason",
                        "targets",
                        "maxResults",
                        "frequency",
                        "spendingLimit",
                        "cost",
                        "confirmed",
                        "nextRefreshAt",
                        "spentThisMonthCredits",
                        "notify",
                        "lastRun",
                        "createdAt",
                        "updatedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The saved search id.",
                          "examples": [
                            "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "search",
                            "watch"
                          ],
                          "title": "Kind",
                          "description": "search or watch.",
                          "examples": [
                            "search"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "A name you will recognise.",
                          "examples": [
                            "Atta prices, Bengaluru"
                          ],
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "active",
                            "paused",
                            "cancelled"
                          ],
                          "title": "State",
                          "description": "draft (not yet confirmed), active, paused or cancelled.",
                          "examples": [
                            "draft"
                          ]
                        },
                        "pauseReason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            "by_user",
                            "insufficient_credits",
                            "monthly_cap",
                            null
                          ],
                          "title": "Pause reason",
                          "description": "Why it is paused; null otherwise.",
                          "examples": [
                            "by_user"
                          ]
                        },
                        "targets": {
                          "type": "array",
                          "title": "Targets",
                          "description": "What it looks up.",
                          "items": {
                            "type": "object",
                            "title": "Saved target as stored",
                            "description": "A saved target. A location is stored with the exact pins it resolved to when you confirmed it, so later refreshes read those pins, never a broader place.",
                            "additionalProperties": false,
                            "required": [
                              "q",
                              "brand",
                              "retailer",
                              "pincode",
                              "location",
                              "pins"
                            ],
                            "properties": {
                              "q": {
                                "type": "string",
                                "title": "Words",
                                "description": "The words.",
                                "examples": [
                                  "aashirvaad atta"
                                ]
                              },
                              "brand": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Brand",
                                "description": "The brand, or null.",
                                "examples": [
                                  "Aashirvaad"
                                ]
                              },
                              "retailer": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Retailer",
                                "description": "The retailer, or null.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "pincode": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Pin code",
                                "description": "The single pin, or null.",
                                "examples": [
                                  "110092"
                                ]
                              },
                              "location": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Location",
                                "description": "The Core location id, or null.",
                                "examples": [
                                  "IN:city:karnataka:bengaluru"
                                ]
                              },
                              "pins": {
                                "type": [
                                  "null",
                                  "array"
                                ],
                                "title": "Pins",
                                "description": "The pins the location resolved to when confirmed; null without a location.",
                                "items": {
                                  "type": "string",
                                  "examples": [
                                    "560001"
                                  ]
                                }
                              }
                            }
                          }
                        },
                        "maxResults": {
                          "type": "integer",
                          "title": "Rows per target",
                          "description": "The most listings one refresh reads for each target, 1 to 100. Default 50. This bounds the cost ceiling.",
                          "examples": [
                            50
                          ],
                          "minimum": 1,
                          "maximum": 100
                        },
                        "frequency": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Frequency",
                          "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                          "additionalProperties": false,
                          "required": [
                            "kind",
                            "time"
                          ],
                          "properties": {
                            "kind": {
                              "type": "string",
                              "enum": [
                                "daily",
                                "weekly",
                                "monthly"
                              ],
                              "title": "Kind",
                              "description": "daily, weekly or monthly.",
                              "examples": [
                                "daily"
                              ]
                            },
                            "time": {
                              "type": "string",
                              "title": "Time",
                              "description": "HH:MM, 24-hour, Asia/Kolkata.",
                              "examples": [
                                "07:30"
                              ],
                              "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                            },
                            "weekday": {
                              "type": "string",
                              "enum": [
                                "monday",
                                "tuesday",
                                "wednesday",
                                "thursday",
                                "friday",
                                "saturday",
                                "sunday"
                              ],
                              "title": "Weekday",
                              "description": "For weekly.",
                              "examples": [
                                "monday"
                              ]
                            },
                            "dayOfMonth": {
                              "type": "integer",
                              "title": "Day of month",
                              "description": "For monthly, 1 to 28.",
                              "examples": [
                                1
                              ],
                              "minimum": 1,
                              "maximum": 28
                            }
                          }
                        },
                        "spendingLimit": {
                          "type": "object",
                          "title": "Spending caps",
                          "description": "The most credits one refresh may charge, and the most all refreshes may charge in an IST calendar month. A refresh that would pass either is cut down to fit, or skipped and recorded; it is never charged above them.",
                          "additionalProperties": false,
                          "required": [
                            "perRefreshCredits",
                            "perMonthCredits"
                          ],
                          "properties": {
                            "perRefreshCredits": {
                              "type": "integer",
                              "title": "Per refresh",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                20
                              ],
                              "minimum": 1
                            },
                            "perMonthCredits": {
                              "type": "integer",
                              "title": "Per month",
                              "description": "Whole credits, at least 1.",
                              "examples": [
                                300
                              ],
                              "minimum": 1
                            }
                          }
                        },
                        "cost": {
                          "type": "object",
                          "title": "Cost",
                          "description": "What a refresh costs, estimated free from what the targets match now, at the published listings rate. The ceiling is the most a refresh can cost (rows per target x targets); you confirm the ceilings.",
                          "additionalProperties": false,
                          "required": [
                            "expectedListings",
                            "perRefreshExpectedCredits",
                            "perRefreshCeilingCredits",
                            "refreshesPerMonth",
                            "perMonthCeilingCredits",
                            "rateVersion",
                            "estimatedAt",
                            "fitsBalance",
                            "withinCaps"
                          ],
                          "properties": {
                            "expectedListings": {
                              "type": "integer",
                              "title": "Expected listings",
                              "description": "About how many listings a refresh reads now.",
                              "examples": [
                                120
                              ]
                            },
                            "perRefreshExpectedCredits": {
                              "type": "integer",
                              "title": "Expected per refresh",
                              "description": "Credits for the expected listings.",
                              "examples": [
                                12
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per refresh",
                              "description": "The most one refresh can cost.",
                              "examples": [
                                50
                              ]
                            },
                            "refreshesPerMonth": {
                              "type": "integer",
                              "title": "Refreshes a month",
                              "description": "At most this many (a search: 1 by hand counts as the caps allow).",
                              "examples": [
                                31
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Ceiling per month",
                              "description": "Ceiling per refresh x refreshes a month.",
                              "examples": [
                                1550
                              ]
                            },
                            "rateVersion": {
                              "type": "string",
                              "title": "Rate version",
                              "description": "The listings rate card used.",
                              "examples": [
                                "2"
                              ]
                            },
                            "estimatedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Estimated at",
                              "description": "When it was estimated.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "fitsBalance": {
                              "type": "boolean",
                              "title": "Fits balance",
                              "description": "Whether the expected month fits your credits now.",
                              "examples": [
                                true
                              ]
                            },
                            "withinCaps": {
                              "type": "boolean",
                              "title": "Within caps",
                              "description": "Whether the ceilings are inside your caps; if not a refresh is cut to fit.",
                              "examples": [
                                true
                              ]
                            }
                          }
                        },
                        "confirmed": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Confirmation",
                          "description": "Your one confirmation: who, when and the ceilings and caps agreed.",
                          "additionalProperties": false,
                          "required": [
                            "by",
                            "at",
                            "perRefreshCeilingCredits",
                            "perMonthCeilingCredits",
                            "perRefreshCapCredits",
                            "perMonthCapCredits"
                          ],
                          "properties": {
                            "by": {
                              "type": "string",
                              "title": "By",
                              "description": "Who confirmed.",
                              "examples": [
                                "user:abc"
                              ]
                            },
                            "at": {
                              "type": "string",
                              "format": "date-time",
                              "title": "At",
                              "description": "When.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "perRefreshCeilingCredits": {
                              "type": "integer",
                              "title": "Per refresh ceiling",
                              "description": "Agreed.",
                              "examples": [
                                50
                              ]
                            },
                            "perMonthCeilingCredits": {
                              "type": "integer",
                              "title": "Per month ceiling",
                              "description": "Agreed.",
                              "examples": [
                                1550
                              ]
                            },
                            "perRefreshCapCredits": {
                              "type": "integer",
                              "title": "Per refresh cap",
                              "description": "Agreed cap.",
                              "examples": [
                                20
                              ]
                            },
                            "perMonthCapCredits": {
                              "type": "integer",
                              "title": "Per month cap",
                              "description": "Agreed cap.",
                              "examples": [
                                300
                              ]
                            }
                          }
                        },
                        "nextRefreshAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Next refresh",
                          "description": "When a watch refreshes next; null otherwise.",
                          "examples": [
                            "2026-10-21T02:00:00Z"
                          ]
                        },
                        "spentThisMonthCredits": {
                          "type": "integer",
                          "title": "Spent this month",
                          "description": "Credits charged by refreshes this IST month.",
                          "examples": [
                            24
                          ]
                        },
                        "notify": {
                          "type": "array",
                          "title": "Notify",
                          "description": "Where this watch sends what changed. An email entry names the destination it resolved to.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "channel",
                              "destinationId"
                            ],
                            "properties": {
                              "channel": {
                                "type": "string",
                                "enum": [
                                  "in_app",
                                  "email",
                                  "slack",
                                  "telegram",
                                  "webhook"
                                ],
                                "title": "Channel",
                                "description": "The channel."
                              },
                              "destinationId": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "pattern": "^dst_[0-9a-f]{32}$",
                                "title": "Destination id",
                                "description": "The destination; null for in_app.",
                                "examples": [
                                  "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
                                ]
                              }
                            }
                          }
                        },
                        "lastRun": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Refresh",
                          "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                          "additionalProperties": false,
                          "required": [
                            "id",
                            "savedSearchId",
                            "trigger",
                            "state",
                            "skipReason",
                            "failureMessage",
                            "credits",
                            "rows",
                            "trimmed",
                            "freeReread",
                            "summary",
                            "startedAt",
                            "finishedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string",
                              "title": "Id",
                              "description": "The refresh id.",
                              "examples": [
                                "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                              ]
                            },
                            "savedSearchId": {
                              "type": "string",
                              "title": "Saved search",
                              "description": "Its saved search.",
                              "examples": [
                                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                              ]
                            },
                            "trigger": {
                              "type": "string",
                              "enum": [
                                "manual",
                                "scheduled"
                              ],
                              "title": "Trigger",
                              "description": "manual or scheduled.",
                              "examples": [
                                "manual"
                              ]
                            },
                            "state": {
                              "type": "string",
                              "enum": [
                                "running",
                                "done",
                                "skipped",
                                "failed"
                              ],
                              "title": "State",
                              "description": "running, done, skipped or failed.",
                              "examples": [
                                "running"
                              ]
                            },
                            "skipReason": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "enum": [
                                "not_approved",
                                "paused",
                                "cancelled",
                                "insufficient_credits",
                                "monthly_cap",
                                "refresh_all_limit",
                                null
                              ],
                              "title": "Skip reason",
                              "description": "Why it was skipped; null otherwise.",
                              "examples": [
                                "not_approved"
                              ]
                            },
                            "failureMessage": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Failure",
                              "description": "Why it failed; null otherwise.",
                              "examples": [
                                "stopped before finishing"
                              ]
                            },
                            "credits": {
                              "type": "object",
                              "title": "Credits",
                              "description": "The cap it ran under and what it charged (never above it).",
                              "additionalProperties": false,
                              "required": [
                                "limit",
                                "charged"
                              ],
                              "properties": {
                                "limit": {
                                  "type": "integer",
                                  "title": "Limit",
                                  "description": "The most this refresh could charge.",
                                  "examples": [
                                    20
                                  ]
                                },
                                "charged": {
                                  "type": "integer",
                                  "title": "Charged",
                                  "description": "Credits charged; 0 for a free re-read.",
                                  "examples": [
                                    12
                                  ]
                                }
                              }
                            },
                            "rows": {
                              "type": "integer",
                              "title": "Rows",
                              "description": "Listings delivered.",
                              "examples": [
                                120
                              ]
                            },
                            "trimmed": {
                              "type": "boolean",
                              "title": "Trimmed",
                              "description": "True when the refresh was cut down to fit a cap.",
                              "examples": [
                                false
                              ]
                            },
                            "freeReread": {
                              "type": "boolean",
                              "title": "Free re-read",
                              "description": "True when identical data was read within 7 days (free).",
                              "examples": [
                                false
                              ]
                            },
                            "summary": {
                              "type": [
                                "null",
                                "object"
                              ],
                              "title": "Change summary",
                              "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                              "additionalProperties": false,
                              "required": [
                                "first",
                                "totalNow",
                                "totalBefore",
                                "addedCount",
                                "removedCount",
                                "changedCount",
                                "reobservedCount",
                                "added",
                                "removed"
                              ],
                              "properties": {
                                "first": {
                                  "type": "boolean",
                                  "title": "First",
                                  "description": "No earlier refresh to compare with.",
                                  "examples": [
                                    false
                                  ]
                                },
                                "totalNow": {
                                  "type": "integer",
                                  "title": "Total now",
                                  "description": "Listings in this refresh.",
                                  "examples": [
                                    120
                                  ]
                                },
                                "totalBefore": {
                                  "type": "integer",
                                  "title": "Total before",
                                  "description": "Listings in the previous refresh.",
                                  "examples": [
                                    118
                                  ]
                                },
                                "addedCount": {
                                  "type": "integer",
                                  "title": "Added",
                                  "description": "Listings that are new in the results.",
                                  "examples": [
                                    3
                                  ]
                                },
                                "removedCount": {
                                  "type": "integer",
                                  "title": "Removed",
                                  "description": "Listings no longer in the results.",
                                  "examples": [
                                    1
                                  ]
                                },
                                "changedCount": {
                                  "type": "integer",
                                  "title": "Changed",
                                  "description": "Listings whose title, brand or retailer details changed.",
                                  "examples": [
                                    2
                                  ]
                                },
                                "reobservedCount": {
                                  "type": "integer",
                                  "title": "Read again",
                                  "description": "Listings the collectors have read again since.",
                                  "examples": [
                                    40
                                  ]
                                },
                                "added": {
                                  "type": "array",
                                  "title": "Added listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "123"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Aashirvaad Atta 5kg"
                                        ]
                                      }
                                    }
                                  }
                                },
                                "removed": {
                                  "type": "array",
                                  "title": "Removed listings",
                                  "description": "Up to 50.",
                                  "items": {
                                    "type": "object",
                                    "additionalProperties": false,
                                    "required": [
                                      "id",
                                      "title"
                                    ],
                                    "properties": {
                                      "id": {
                                        "type": "string",
                                        "title": "Listing id",
                                        "description": "The listing.",
                                        "examples": [
                                          "99"
                                        ]
                                      },
                                      "title": {
                                        "type": [
                                          "null",
                                          "string"
                                        ],
                                        "title": "Title",
                                        "description": "Its title.",
                                        "examples": [
                                          "Old Atta 1kg"
                                        ]
                                      }
                                    }
                                  }
                                }
                              }
                            },
                            "startedAt": {
                              "type": "string",
                              "format": "date-time",
                              "title": "Started",
                              "description": "When it started.",
                              "examples": [
                                "2026-10-20T10:00:00Z"
                              ]
                            },
                            "finishedAt": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "format": "date-time",
                              "title": "Finished",
                              "description": "When it ended; null while running.",
                              "examples": [
                                "2026-10-20T10:00:01Z"
                              ]
                            }
                          }
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Created",
                          "description": "When saved.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        },
                        "updatedAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Updated",
                          "description": "When last changed.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The saved search id.",
              "examples": [
                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
              ],
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/saved-searches/{id}/runs": {
      "get": {
        "operationId": "listSavedSearchRuns",
        "summary": "The refreshes of a saved search",
        "description": "Its refreshes, newest first, each with what it charged and what changed since the one before.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Page",
                  "description": "One page.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Data",
                      "description": "The page.",
                      "items": {
                        "type": "object",
                        "title": "Refresh",
                        "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "savedSearchId",
                          "trigger",
                          "state",
                          "skipReason",
                          "failureMessage",
                          "credits",
                          "rows",
                          "trimmed",
                          "freeReread",
                          "summary",
                          "startedAt",
                          "finishedAt"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "title": "Id",
                            "description": "The refresh id.",
                            "examples": [
                              "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                            ]
                          },
                          "savedSearchId": {
                            "type": "string",
                            "title": "Saved search",
                            "description": "Its saved search.",
                            "examples": [
                              "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                            ]
                          },
                          "trigger": {
                            "type": "string",
                            "enum": [
                              "manual",
                              "scheduled"
                            ],
                            "title": "Trigger",
                            "description": "manual or scheduled.",
                            "examples": [
                              "manual"
                            ]
                          },
                          "state": {
                            "type": "string",
                            "enum": [
                              "running",
                              "done",
                              "skipped",
                              "failed"
                            ],
                            "title": "State",
                            "description": "running, done, skipped or failed.",
                            "examples": [
                              "running"
                            ]
                          },
                          "skipReason": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "not_approved",
                              "paused",
                              "cancelled",
                              "insufficient_credits",
                              "monthly_cap",
                              "refresh_all_limit",
                              null
                            ],
                            "title": "Skip reason",
                            "description": "Why it was skipped; null otherwise.",
                            "examples": [
                              "not_approved"
                            ]
                          },
                          "failureMessage": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Failure",
                            "description": "Why it failed; null otherwise.",
                            "examples": [
                              "stopped before finishing"
                            ]
                          },
                          "credits": {
                            "type": "object",
                            "title": "Credits",
                            "description": "The cap it ran under and what it charged (never above it).",
                            "additionalProperties": false,
                            "required": [
                              "limit",
                              "charged"
                            ],
                            "properties": {
                              "limit": {
                                "type": "integer",
                                "title": "Limit",
                                "description": "The most this refresh could charge.",
                                "examples": [
                                  20
                                ]
                              },
                              "charged": {
                                "type": "integer",
                                "title": "Charged",
                                "description": "Credits charged; 0 for a free re-read.",
                                "examples": [
                                  12
                                ]
                              }
                            }
                          },
                          "rows": {
                            "type": "integer",
                            "title": "Rows",
                            "description": "Listings delivered.",
                            "examples": [
                              120
                            ]
                          },
                          "trimmed": {
                            "type": "boolean",
                            "title": "Trimmed",
                            "description": "True when the refresh was cut down to fit a cap.",
                            "examples": [
                              false
                            ]
                          },
                          "freeReread": {
                            "type": "boolean",
                            "title": "Free re-read",
                            "description": "True when identical data was read within 7 days (free).",
                            "examples": [
                              false
                            ]
                          },
                          "summary": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "title": "Change summary",
                            "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                            "additionalProperties": false,
                            "required": [
                              "first",
                              "totalNow",
                              "totalBefore",
                              "addedCount",
                              "removedCount",
                              "changedCount",
                              "reobservedCount",
                              "added",
                              "removed"
                            ],
                            "properties": {
                              "first": {
                                "type": "boolean",
                                "title": "First",
                                "description": "No earlier refresh to compare with.",
                                "examples": [
                                  false
                                ]
                              },
                              "totalNow": {
                                "type": "integer",
                                "title": "Total now",
                                "description": "Listings in this refresh.",
                                "examples": [
                                  120
                                ]
                              },
                              "totalBefore": {
                                "type": "integer",
                                "title": "Total before",
                                "description": "Listings in the previous refresh.",
                                "examples": [
                                  118
                                ]
                              },
                              "addedCount": {
                                "type": "integer",
                                "title": "Added",
                                "description": "Listings that are new in the results.",
                                "examples": [
                                  3
                                ]
                              },
                              "removedCount": {
                                "type": "integer",
                                "title": "Removed",
                                "description": "Listings no longer in the results.",
                                "examples": [
                                  1
                                ]
                              },
                              "changedCount": {
                                "type": "integer",
                                "title": "Changed",
                                "description": "Listings whose title, brand or retailer details changed.",
                                "examples": [
                                  2
                                ]
                              },
                              "reobservedCount": {
                                "type": "integer",
                                "title": "Read again",
                                "description": "Listings the collectors have read again since.",
                                "examples": [
                                  40
                                ]
                              },
                              "added": {
                                "type": "array",
                                "title": "Added listings",
                                "description": "Up to 50.",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": false,
                                  "required": [
                                    "id",
                                    "title"
                                  ],
                                  "properties": {
                                    "id": {
                                      "type": "string",
                                      "title": "Listing id",
                                      "description": "The listing.",
                                      "examples": [
                                        "123"
                                      ]
                                    },
                                    "title": {
                                      "type": [
                                        "null",
                                        "string"
                                      ],
                                      "title": "Title",
                                      "description": "Its title.",
                                      "examples": [
                                        "Aashirvaad Atta 5kg"
                                      ]
                                    }
                                  }
                                }
                              },
                              "removed": {
                                "type": "array",
                                "title": "Removed listings",
                                "description": "Up to 50.",
                                "items": {
                                  "type": "object",
                                  "additionalProperties": false,
                                  "required": [
                                    "id",
                                    "title"
                                  ],
                                  "properties": {
                                    "id": {
                                      "type": "string",
                                      "title": "Listing id",
                                      "description": "The listing.",
                                      "examples": [
                                        "99"
                                      ]
                                    },
                                    "title": {
                                      "type": [
                                        "null",
                                        "string"
                                      ],
                                      "title": "Title",
                                      "description": "Its title.",
                                      "examples": [
                                        "Old Atta 1kg"
                                      ]
                                    }
                                  }
                                }
                              }
                            }
                          },
                          "startedAt": {
                            "type": "string",
                            "format": "date-time",
                            "title": "Started",
                            "description": "When it started.",
                            "examples": [
                              "2026-10-20T10:00:00Z"
                            ]
                          },
                          "finishedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "title": "Finished",
                            "description": "When it ended; null while running.",
                            "examples": [
                              "2026-10-20T10:00:01Z"
                            ]
                          }
                        }
                      }
                    },
                    "page": {
                      "type": "object",
                      "title": "Page info",
                      "description": "Paging.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "title": "Limit",
                          "description": "Page size.",
                          "examples": [
                            20
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Pass as cursor; null at the end.",
                          "examples": [
                            "eyJvIjoyMH0"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The saved search id.",
              "examples": [
                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
              ],
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Page size",
              "examples": [
                "20"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "1 to 100. Default 20."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJvIjoyMH0"
              ]
            },
            "description": "From page.nextCursor."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Kind",
              "examples": [
                "watch"
              ],
              "pattern": "^(search|watch)$"
            },
            "description": "Only \"search\" or only \"watch\". Anything else is refused."
          }
        ]
      }
    },
    "/v1/saved-searches/{id}/runs/{runId}": {
      "get": {
        "operationId": "getSavedSearchRun",
        "summary": "One refresh of a saved search",
        "description": "One refresh, with its change summary.",
        "tags": [
          "Saved searches"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Refresh answer",
                  "description": "One refresh.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Refresh",
                      "description": "One refresh: exactly one per saved search and run key, so a duplicate start is the same refresh and settles once.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "savedSearchId",
                        "trigger",
                        "state",
                        "skipReason",
                        "failureMessage",
                        "credits",
                        "rows",
                        "trimmed",
                        "freeReread",
                        "summary",
                        "startedAt",
                        "finishedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The refresh id.",
                          "examples": [
                            "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
                          ]
                        },
                        "savedSearchId": {
                          "type": "string",
                          "title": "Saved search",
                          "description": "Its saved search.",
                          "examples": [
                            "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
                          ]
                        },
                        "trigger": {
                          "type": "string",
                          "enum": [
                            "manual",
                            "scheduled"
                          ],
                          "title": "Trigger",
                          "description": "manual or scheduled.",
                          "examples": [
                            "manual"
                          ]
                        },
                        "state": {
                          "type": "string",
                          "enum": [
                            "running",
                            "done",
                            "skipped",
                            "failed"
                          ],
                          "title": "State",
                          "description": "running, done, skipped or failed.",
                          "examples": [
                            "running"
                          ]
                        },
                        "skipReason": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "enum": [
                            "not_approved",
                            "paused",
                            "cancelled",
                            "insufficient_credits",
                            "monthly_cap",
                            "refresh_all_limit",
                            null
                          ],
                          "title": "Skip reason",
                          "description": "Why it was skipped; null otherwise.",
                          "examples": [
                            "not_approved"
                          ]
                        },
                        "failureMessage": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Failure",
                          "description": "Why it failed; null otherwise.",
                          "examples": [
                            "stopped before finishing"
                          ]
                        },
                        "credits": {
                          "type": "object",
                          "title": "Credits",
                          "description": "The cap it ran under and what it charged (never above it).",
                          "additionalProperties": false,
                          "required": [
                            "limit",
                            "charged"
                          ],
                          "properties": {
                            "limit": {
                              "type": "integer",
                              "title": "Limit",
                              "description": "The most this refresh could charge.",
                              "examples": [
                                20
                              ]
                            },
                            "charged": {
                              "type": "integer",
                              "title": "Charged",
                              "description": "Credits charged; 0 for a free re-read.",
                              "examples": [
                                12
                              ]
                            }
                          }
                        },
                        "rows": {
                          "type": "integer",
                          "title": "Rows",
                          "description": "Listings delivered.",
                          "examples": [
                            120
                          ]
                        },
                        "trimmed": {
                          "type": "boolean",
                          "title": "Trimmed",
                          "description": "True when the refresh was cut down to fit a cap.",
                          "examples": [
                            false
                          ]
                        },
                        "freeReread": {
                          "type": "boolean",
                          "title": "Free re-read",
                          "description": "True when identical data was read within 7 days (free).",
                          "examples": [
                            false
                          ]
                        },
                        "summary": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Change summary",
                          "description": "What changed since the previous refresh. The first refresh has first = true and everything is new.",
                          "additionalProperties": false,
                          "required": [
                            "first",
                            "totalNow",
                            "totalBefore",
                            "addedCount",
                            "removedCount",
                            "changedCount",
                            "reobservedCount",
                            "added",
                            "removed"
                          ],
                          "properties": {
                            "first": {
                              "type": "boolean",
                              "title": "First",
                              "description": "No earlier refresh to compare with.",
                              "examples": [
                                false
                              ]
                            },
                            "totalNow": {
                              "type": "integer",
                              "title": "Total now",
                              "description": "Listings in this refresh.",
                              "examples": [
                                120
                              ]
                            },
                            "totalBefore": {
                              "type": "integer",
                              "title": "Total before",
                              "description": "Listings in the previous refresh.",
                              "examples": [
                                118
                              ]
                            },
                            "addedCount": {
                              "type": "integer",
                              "title": "Added",
                              "description": "Listings that are new in the results.",
                              "examples": [
                                3
                              ]
                            },
                            "removedCount": {
                              "type": "integer",
                              "title": "Removed",
                              "description": "Listings no longer in the results.",
                              "examples": [
                                1
                              ]
                            },
                            "changedCount": {
                              "type": "integer",
                              "title": "Changed",
                              "description": "Listings whose title, brand or retailer details changed.",
                              "examples": [
                                2
                              ]
                            },
                            "reobservedCount": {
                              "type": "integer",
                              "title": "Read again",
                              "description": "Listings the collectors have read again since.",
                              "examples": [
                                40
                              ]
                            },
                            "added": {
                              "type": "array",
                              "title": "Added listings",
                              "description": "Up to 50.",
                              "items": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                  "id",
                                  "title"
                                ],
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "title": "Listing id",
                                    "description": "The listing.",
                                    "examples": [
                                      "123"
                                    ]
                                  },
                                  "title": {
                                    "type": [
                                      "null",
                                      "string"
                                    ],
                                    "title": "Title",
                                    "description": "Its title.",
                                    "examples": [
                                      "Aashirvaad Atta 5kg"
                                    ]
                                  }
                                }
                              }
                            },
                            "removed": {
                              "type": "array",
                              "title": "Removed listings",
                              "description": "Up to 50.",
                              "items": {
                                "type": "object",
                                "additionalProperties": false,
                                "required": [
                                  "id",
                                  "title"
                                ],
                                "properties": {
                                  "id": {
                                    "type": "string",
                                    "title": "Listing id",
                                    "description": "The listing.",
                                    "examples": [
                                      "99"
                                    ]
                                  },
                                  "title": {
                                    "type": [
                                      "null",
                                      "string"
                                    ],
                                    "title": "Title",
                                    "description": "Its title.",
                                    "examples": [
                                      "Old Atta 1kg"
                                    ]
                                  }
                                }
                              }
                            }
                          }
                        },
                        "startedAt": {
                          "type": "string",
                          "format": "date-time",
                          "title": "Started",
                          "description": "When it started.",
                          "examples": [
                            "2026-10-20T10:00:00Z"
                          ]
                        },
                        "finishedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "title": "Finished",
                          "description": "When it ended; null while running.",
                          "examples": [
                            "2026-10-20T10:00:01Z"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The saved search id.",
              "examples": [
                "0d6b6d44-3bb7-4d52-9b3e-0d2f4f7f1a10"
              ],
              "format": "uuid"
            }
          },
          {
            "name": "runId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Run id",
              "description": "The refresh id.",
              "examples": [
                "7c1f0f0e-45c7-4f9c-8a42-cb3f9e3a2a01"
              ],
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/search": {
      "get": {
        "operationId": "globalSearch",
        "summary": "Search everything of yours",
        "description": "One free, read-only search over your reports, saved items (scheduled reports and your data requests), products and brands. Returns a few best matches per group with the route that opens each; it shows no prices and never starts a paid read. A group you cannot see answers not_available.",
        "tags": [
          "Search"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GlobalSearchAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Words",
              "examples": [
                "love co"
              ],
              "minLength": 2,
              "maxLength": 100
            },
            "description": "What to look for: 2 to 100 characters."
          },
          {
            "name": "groups",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Groups",
              "examples": [
                "reports,products"
              ],
              "pattern": "^(reports|saved|products|brands)(,(reports|saved|products|brands)){0,3}$"
            },
            "description": "Comma-separated groups to search (reports, saved, products, brands). Default all."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Per group",
              "examples": [
                "5"
              ],
              "pattern": "^([1-9]|10)$"
            },
            "description": "Results per group, 1 to 10. Default 5."
          }
        ]
      }
    },
    "/v1/service/intake/enquiries": {
      "post": {
        "operationId": "createServiceIntakeEnquiry",
        "summary": "Store a /contact enquiry, for the site's form action",
        "description": "Server to server only: needs a Rewalto service key (`Authorization: Bearer rws_...`) with the scope `intake:write`; a session, an API key or an MCP token is refused. Stores one enquiry (partnership, press, method, other) and answers a receipt: its id and time, never a submitted field. Run the honeypot first; send the mail after, with the receipt id. The personal fields are scrubbed 180 days after sending and the row is kept (D-1921, C-010). At most 5 submissions an hour and 20 a day per visitor (`visitorHash`) and per work email, shared by the enquiry and every lead door (`rate_limited`). Every call is recorded in the staff audit (caller kind `service_key`). Free.",
        "tags": [
          "Service (server to server)"
        ],
        "security": [
          {
            "serviceKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntakeReceipt"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntakeEnquiryCreate"
              }
            }
          }
        }
      }
    },
    "/v1/service/intake/leads": {
      "post": {
        "operationId": "createServiceIntakeLead",
        "summary": "Store a lead from a lead door, for the site's form action",
        "description": "Server to server only: needs a Rewalto service key with the scope `intake:write`. Stores one lead from /talk, /site-audit or /for-startups (`source` scan, portfolio, data or services) with the same fields and limits as the old form. Send `consent` only when a consent box was shown and ticked: Core stamps the consent time with its own clock, in the same insert; a double opt-in token's hash rides with it (redeem with `confirmServiceIntakeLead`). Answers a receipt: the id (the old lead id: /site-audit's report and claim links) and time, never a submitted field. The personal fields are scrubbed 180 days after sending and the row is kept (D-1921, C-010). At most 5 submissions an hour and 20 a day per visitor (`visitorHash`) and per work email, shared by the enquiry and every lead door (`rate_limited`). Every call is recorded in the staff audit. Free.",
        "tags": [
          "Service (server to server)"
        ],
        "security": [
          {
            "serviceKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntakeReceipt"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntakeLeadCreate"
              }
            }
          }
        }
      }
    },
    "/v1/service/intake/leads/confirm": {
      "post": {
        "operationId": "confirmServiceIntakeLead",
        "summary": "Redeem a lead's double opt-in link, for the site's confirm page",
        "description": "Server to server only: needs a Rewalto service key with the scope `intake:write`. Send the token from the confirmation link (from the confirm page's button, a POST: never redeem on a GET, which mail scanners follow). Single use, within 7 days of the consent: `confirmed` once, then `invalid`; unknown, used, expired and scrubbed links all answer `invalid`. Every call is recorded in the staff audit. Free.",
        "tags": [
          "Service (server to server)"
        ],
        "security": [
          {
            "serviceKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/IntakeLeadConfirmAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/IntakeLeadConfirm"
              }
            }
          }
        }
      }
    },
    "/v1/service/notification-preferences": {
      "get": {
        "operationId": "getServiceNotificationPreferences",
        "summary": "A user's notification preferences, for Rewalto's email sender",
        "description": "Server to server only: needs a Rewalto service key (`Authorization: Bearer rws_...`) with the scope `notification-preferences:read`; a session, an API key or an MCP token is refused. Returns the same shape as `getNotificationPreferences` for the user named, in the organisation named (Clerk `org_...` or Core uuid; leave `orgId` out for a personal workspace). A user who never saved, or an organisation Core does not hold yet, reads `version: 0` and the launch defaults. Read only. Every call is recorded in the staff audit (caller kind `service_key`). Free.",
        "tags": [
          "Service (server to server)"
        ],
        "security": [
          {
            "serviceKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NotificationPreferences"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "userId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^user_[A-Za-z0-9]{1,64}$",
              "examples": [
                "user_2abcDEF"
              ]
            },
            "description": "The Clerk user id (`user_...`) whose preferences to read."
          },
          {
            "name": "orgId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|org_[A-Za-z0-9]{1,64})$",
              "examples": [
                "org_2xyzABC"
              ]
            },
            "description": "The organisation the preferences were saved in: the Clerk organisation id (`org_...`) or the Core organisation id (uuid, `whoami`'s `organisation.id`). Leave it out for a user with no Clerk organisation (their personal workspace)."
          }
        ]
      }
    },
    "/v1/snapshots": {
      "get": {
        "operationId": "listSnapshots",
        "summary": "List dataset snapshots for sale",
        "description": "Ready dataset snapshots (D-1547): each with its scope, newest edition (as-of date, record count, fields, coverage), price in credits from the rate card (D-1553), licence summary, the 12-month download window and whether it is on sale. A snapshot below its coverage floor is listed and cannot be bought. Filter by family, kind or category. Public and free.",
        "tags": [
          "Snapshots"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Snapshots",
                  "description": "The snapshots matching the filters, by family then name.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "total"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "title": "Snapshots",
                      "description": "The snapshots.",
                      "items": {
                        "type": "object",
                        "title": "Snapshot",
                        "description": "A ready dataset snapshot: scope, newest edition, price in credits, licence and sale state.",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "family",
                          "categoryId",
                          "kind",
                          "scope",
                          "name",
                          "summary",
                          "format",
                          "minRecords",
                          "downloadMonths",
                          "licence",
                          "edition",
                          "pricing",
                          "saleState"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "title": "Id",
                            "description": "The snapshot id.",
                            "examples": [
                              "listings_blinkit_in"
                            ],
                            "pattern": "^[a-z][a-z0-9_]{1,63}$"
                          },
                          "family": {
                            "type": "string",
                            "enum": [
                              "commerce",
                              "investors",
                              "startups",
                              "companies",
                              "public_records"
                            ],
                            "title": "Family",
                            "description": "The Data library family.",
                            "examples": [
                              "commerce"
                            ]
                          },
                          "categoryId": {
                            "type": "string",
                            "title": "Category",
                            "description": "The catalogue category.",
                            "examples": [
                              "quick_commerce"
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "listings_app",
                              "listings_app_city",
                              "dark_store_map",
                              "category_history",
                              "investors",
                              "startups",
                              "companies"
                            ],
                            "title": "Kind",
                            "description": "What kind of snapshot it is (D-1558).",
                            "examples": [
                              "listings_app"
                            ]
                          },
                          "scope": {
                            "type": "object",
                            "title": "Scope",
                            "description": "What the snapshot holds. listings_app: one retailer, all India. listings_app_city: one retailer in one city. dark_store_map: one platform. category_history: one category over the last `days` days. investors, startups, companies: the whole list, no scope.",
                            "additionalProperties": false,
                            "required": [],
                            "properties": {
                              "retailer": {
                                "type": "string",
                                "title": "Retailer",
                                "description": "The retailer slug.",
                                "examples": [
                                  "blinkit"
                                ]
                              },
                              "city": {
                                "type": "string",
                                "title": "City",
                                "description": "The city, as the dark-store map names it.",
                                "examples": [
                                  "Bengaluru"
                                ]
                              },
                              "platform": {
                                "type": "string",
                                "title": "Platform",
                                "description": "The quick-commerce platform.",
                                "examples": [
                                  "zepto"
                                ]
                              },
                              "category": {
                                "type": "string",
                                "title": "Category",
                                "description": "The category.",
                                "examples": [
                                  "dairy"
                                ]
                              },
                              "days": {
                                "type": "integer",
                                "minimum": 1,
                                "title": "Days",
                                "description": "How many days of history.",
                                "examples": [
                                  90
                                ]
                              }
                            }
                          },
                          "name": {
                            "type": "string",
                            "title": "Name",
                            "description": "The snapshot name.",
                            "examples": [
                              "Blinkit listings, all India"
                            ]
                          },
                          "summary": {
                            "type": "string",
                            "title": "Summary",
                            "description": "What you get.",
                            "examples": [
                              "Every Blinkit listing Rewalto holds, as of one date."
                            ]
                          },
                          "format": {
                            "type": "string",
                            "const": "jsonl",
                            "title": "Format",
                            "description": "JSON Lines (D-1307)."
                          },
                          "minRecords": {
                            "type": "integer",
                            "minimum": 1,
                            "title": "Coverage floor",
                            "description": "An edition with fewer records is not for sale.",
                            "examples": [
                              1000
                            ]
                          },
                          "downloadMonths": {
                            "type": "integer",
                            "minimum": 1,
                            "title": "Download months",
                            "description": "How long a purchase can be downloaded (D-1555).",
                            "examples": [
                              12
                            ]
                          },
                          "licence": {
                            "type": "object",
                            "title": "Licence",
                            "description": "The licence a purchase is sold under (D-1556).",
                            "additionalProperties": false,
                            "required": [
                              "version",
                              "title",
                              "summary"
                            ],
                            "properties": {
                              "version": {
                                "type": "integer",
                                "minimum": 1,
                                "title": "Version",
                                "description": "The licence version, stored with each purchase.",
                                "examples": [
                                  1
                                ]
                              },
                              "title": {
                                "type": "string",
                                "title": "Title",
                                "description": "The licence title.",
                                "examples": [
                                  "Rewalto dataset licence, version 1"
                                ]
                              },
                              "summary": {
                                "type": "string",
                                "title": "Summary",
                                "description": "One line.",
                                "examples": [
                                  "Use it inside your own organisation, including in your own products and analysis. Do not resell or redistribute the raw records. Cite Rewalto for figures you publish."
                                ]
                              }
                            }
                          },
                          "edition": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "title": "Edition",
                            "description": "The snapshot as of one date.",
                            "additionalProperties": false,
                            "required": [
                              "asOf",
                              "recordCount",
                              "fields",
                              "coverage",
                              "computedAt"
                            ],
                            "properties": {
                              "asOf": {
                                "type": "string",
                                "title": "As of",
                                "description": "The date the edition describes (IST).",
                                "examples": [
                                  "2026-10-16"
                                ],
                                "format": "date"
                              },
                              "recordCount": {
                                "type": "integer",
                                "minimum": 0,
                                "title": "Records",
                                "description": "How many records the edition holds.",
                                "examples": [
                                  648142
                                ]
                              },
                              "fields": {
                                "type": "array",
                                "title": "Fields",
                                "description": "The fields of each record.",
                                "items": {
                                  "type": "object",
                                  "title": "Field",
                                  "description": "One field every record carries.",
                                  "additionalProperties": false,
                                  "required": [
                                    "name",
                                    "type",
                                    "description"
                                  ],
                                  "properties": {
                                    "name": {
                                      "type": "string",
                                      "title": "Name",
                                      "description": "The field name in each JSON Lines record.",
                                      "examples": [
                                        "priceMinor"
                                      ]
                                    },
                                    "type": {
                                      "type": "string",
                                      "title": "Type",
                                      "description": "Its JSON type.",
                                      "examples": [
                                        "integer"
                                      ]
                                    },
                                    "description": {
                                      "type": "string",
                                      "title": "Description",
                                      "description": "What it holds.",
                                      "examples": [
                                        "Selling price in paise."
                                      ]
                                    }
                                  }
                                }
                              },
                              "coverage": {
                                "type": "object",
                                "title": "Coverage",
                                "description": "What the edition covers and how that was measured.",
                                "additionalProperties": false,
                                "required": [
                                  "label",
                                  "basis"
                                ],
                                "properties": {
                                  "label": {
                                    "type": "string",
                                    "title": "Coverage",
                                    "description": "One line.",
                                    "examples": [
                                      "All listings seen on Blinkit, all India"
                                    ]
                                  },
                                  "basis": {
                                    "type": "string",
                                    "title": "Basis",
                                    "description": "How the figure was measured.",
                                    "examples": [
                                      "Distinct listings seen in the last 30 days"
                                    ]
                                  }
                                }
                              },
                              "computedAt": {
                                "type": "string",
                                "title": "Computed at",
                                "description": "When the edition was counted.",
                                "examples": [
                                  "2026-10-16T02:00:00Z"
                                ],
                                "format": "date-time"
                              }
                            }
                          },
                          "pricing": {
                            "type": "object",
                            "title": "Pricing",
                            "description": "The price in credits, from the newest rate card that carries the unit (D-1553). Credits are bought as packs; there is no rupee price per dataset.",
                            "additionalProperties": false,
                            "required": [
                              "unit",
                              "credits",
                              "perUnits",
                              "rateVersion",
                              "totalCredits"
                            ],
                            "properties": {
                              "unit": {
                                "type": "string",
                                "title": "Unit",
                                "description": "The rate-card unit.",
                                "examples": [
                                  "listings"
                                ]
                              },
                              "credits": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 0,
                                "title": "Credits",
                                "description": "Credits per `perUnits` units; null when no rate card carries the unit.",
                                "examples": [
                                  1
                                ]
                              },
                              "perUnits": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 0,
                                "title": "Per units",
                                "description": "How many units the credits buy; null when not priced.",
                                "examples": [
                                  10
                                ]
                              },
                              "rateVersion": {
                                "type": [
                                  "null",
                                  "string"
                                ],
                                "title": "Rate version",
                                "description": "The rate card the price comes from, for example c3; null when not priced.",
                                "examples": [
                                  "c3"
                                ]
                              },
                              "totalCredits": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 0,
                                "title": "Total credits",
                                "description": "The newest edition in full: ceil(records x credits / perUnits). Null when not computed or not priced.",
                                "examples": [
                                  64815
                                ]
                              }
                            }
                          },
                          "saleState": {
                            "type": "string",
                            "enum": [
                              "on_sale",
                              "below_coverage_floor",
                              "not_computed",
                              "not_priced"
                            ],
                            "title": "Sale state",
                            "description": "on_sale: can be bought. below_coverage_floor: the newest edition holds fewer than minRecords records. not_computed: no edition counted yet. not_priced: no rate card carries the unit.",
                            "examples": [
                              "on_sale"
                            ]
                          }
                        }
                      }
                    },
                    "total": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Total",
                      "description": "How many matched.",
                      "examples": [
                        4
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "family",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Family",
              "examples": [
                "commerce"
              ],
              "pattern": "^(commerce|investors|startups|companies|public_records)$"
            },
            "description": "Only this family: commerce, investors, startups, companies, public_records."
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Kind",
              "examples": [
                "listings_app"
              ],
              "pattern": "^(listings_app|listings_app_city|dark_store_map|category_history|investors|startups|companies)$"
            },
            "description": "Only this kind: listings_app, listings_app_city, dark_store_map, category_history, investors, startups, companies."
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Category",
              "examples": [
                "quick_commerce"
              ],
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            },
            "description": "Only this catalogue category."
          }
        ]
      }
    },
    "/v1/snapshots/{id}": {
      "get": {
        "operationId": "getSnapshot",
        "summary": "Get a dataset snapshot",
        "description": "One snapshot in full: everything in the list, plus up to 100 free sample records of the newest edition and the licence text, shown before buying (D-1556). Public and free.",
        "tags": [
          "Snapshots"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Snapshot answer",
                  "description": "One snapshot in full.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Snapshot detail",
                      "description": "A snapshot with its free sample and the licence in full.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "family",
                        "categoryId",
                        "kind",
                        "scope",
                        "name",
                        "summary",
                        "format",
                        "minRecords",
                        "downloadMonths",
                        "licence",
                        "edition",
                        "pricing",
                        "saleState",
                        "licenceBody",
                        "sample"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The snapshot id.",
                          "examples": [
                            "listings_blinkit_in"
                          ],
                          "pattern": "^[a-z][a-z0-9_]{1,63}$"
                        },
                        "family": {
                          "type": "string",
                          "enum": [
                            "commerce",
                            "investors",
                            "startups",
                            "companies",
                            "public_records"
                          ],
                          "title": "Family",
                          "description": "The Data library family.",
                          "examples": [
                            "commerce"
                          ]
                        },
                        "categoryId": {
                          "type": "string",
                          "title": "Category",
                          "description": "The catalogue category.",
                          "examples": [
                            "quick_commerce"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "listings_app",
                            "listings_app_city",
                            "dark_store_map",
                            "category_history",
                            "investors",
                            "startups",
                            "companies"
                          ],
                          "title": "Kind",
                          "description": "What kind of snapshot it is (D-1558).",
                          "examples": [
                            "listings_app"
                          ]
                        },
                        "scope": {
                          "type": "object",
                          "title": "Scope",
                          "description": "What the snapshot holds. listings_app: one retailer, all India. listings_app_city: one retailer in one city. dark_store_map: one platform. category_history: one category over the last `days` days. investors, startups, companies: the whole list, no scope.",
                          "additionalProperties": false,
                          "required": [],
                          "properties": {
                            "retailer": {
                              "type": "string",
                              "title": "Retailer",
                              "description": "The retailer slug.",
                              "examples": [
                                "blinkit"
                              ]
                            },
                            "city": {
                              "type": "string",
                              "title": "City",
                              "description": "The city, as the dark-store map names it.",
                              "examples": [
                                "Bengaluru"
                              ]
                            },
                            "platform": {
                              "type": "string",
                              "title": "Platform",
                              "description": "The quick-commerce platform.",
                              "examples": [
                                "zepto"
                              ]
                            },
                            "category": {
                              "type": "string",
                              "title": "Category",
                              "description": "The category.",
                              "examples": [
                                "dairy"
                              ]
                            },
                            "days": {
                              "type": "integer",
                              "minimum": 1,
                              "title": "Days",
                              "description": "How many days of history.",
                              "examples": [
                                90
                              ]
                            }
                          }
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "The snapshot name.",
                          "examples": [
                            "Blinkit listings, all India"
                          ]
                        },
                        "summary": {
                          "type": "string",
                          "title": "Summary",
                          "description": "What you get.",
                          "examples": [
                            "Every Blinkit listing Rewalto holds, as of one date."
                          ]
                        },
                        "format": {
                          "type": "string",
                          "const": "jsonl",
                          "title": "Format",
                          "description": "JSON Lines (D-1307)."
                        },
                        "minRecords": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Coverage floor",
                          "description": "An edition with fewer records is not for sale.",
                          "examples": [
                            1000
                          ]
                        },
                        "downloadMonths": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Download months",
                          "description": "How long a purchase can be downloaded (D-1555).",
                          "examples": [
                            12
                          ]
                        },
                        "licence": {
                          "type": "object",
                          "title": "Licence",
                          "description": "The licence a purchase is sold under (D-1556).",
                          "additionalProperties": false,
                          "required": [
                            "version",
                            "title",
                            "summary"
                          ],
                          "properties": {
                            "version": {
                              "type": "integer",
                              "minimum": 1,
                              "title": "Version",
                              "description": "The licence version, stored with each purchase.",
                              "examples": [
                                1
                              ]
                            },
                            "title": {
                              "type": "string",
                              "title": "Title",
                              "description": "The licence title.",
                              "examples": [
                                "Rewalto dataset licence, version 1"
                              ]
                            },
                            "summary": {
                              "type": "string",
                              "title": "Summary",
                              "description": "One line.",
                              "examples": [
                                "Use it inside your own organisation, including in your own products and analysis. Do not resell or redistribute the raw records. Cite Rewalto for figures you publish."
                              ]
                            }
                          }
                        },
                        "edition": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Edition",
                          "description": "The snapshot as of one date.",
                          "additionalProperties": false,
                          "required": [
                            "asOf",
                            "recordCount",
                            "fields",
                            "coverage",
                            "computedAt"
                          ],
                          "properties": {
                            "asOf": {
                              "type": "string",
                              "title": "As of",
                              "description": "The date the edition describes (IST).",
                              "examples": [
                                "2026-10-16"
                              ],
                              "format": "date"
                            },
                            "recordCount": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "Records",
                              "description": "How many records the edition holds.",
                              "examples": [
                                648142
                              ]
                            },
                            "fields": {
                              "type": "array",
                              "title": "Fields",
                              "description": "The fields of each record.",
                              "items": {
                                "type": "object",
                                "title": "Field",
                                "description": "One field every record carries.",
                                "additionalProperties": false,
                                "required": [
                                  "name",
                                  "type",
                                  "description"
                                ],
                                "properties": {
                                  "name": {
                                    "type": "string",
                                    "title": "Name",
                                    "description": "The field name in each JSON Lines record.",
                                    "examples": [
                                      "priceMinor"
                                    ]
                                  },
                                  "type": {
                                    "type": "string",
                                    "title": "Type",
                                    "description": "Its JSON type.",
                                    "examples": [
                                      "integer"
                                    ]
                                  },
                                  "description": {
                                    "type": "string",
                                    "title": "Description",
                                    "description": "What it holds.",
                                    "examples": [
                                      "Selling price in paise."
                                    ]
                                  }
                                }
                              }
                            },
                            "coverage": {
                              "type": "object",
                              "title": "Coverage",
                              "description": "What the edition covers and how that was measured.",
                              "additionalProperties": false,
                              "required": [
                                "label",
                                "basis"
                              ],
                              "properties": {
                                "label": {
                                  "type": "string",
                                  "title": "Coverage",
                                  "description": "One line.",
                                  "examples": [
                                    "All listings seen on Blinkit, all India"
                                  ]
                                },
                                "basis": {
                                  "type": "string",
                                  "title": "Basis",
                                  "description": "How the figure was measured.",
                                  "examples": [
                                    "Distinct listings seen in the last 30 days"
                                  ]
                                }
                              }
                            },
                            "computedAt": {
                              "type": "string",
                              "title": "Computed at",
                              "description": "When the edition was counted.",
                              "examples": [
                                "2026-10-16T02:00:00Z"
                              ],
                              "format": "date-time"
                            }
                          }
                        },
                        "pricing": {
                          "type": "object",
                          "title": "Pricing",
                          "description": "The price in credits, from the newest rate card that carries the unit (D-1553). Credits are bought as packs; there is no rupee price per dataset.",
                          "additionalProperties": false,
                          "required": [
                            "unit",
                            "credits",
                            "perUnits",
                            "rateVersion",
                            "totalCredits"
                          ],
                          "properties": {
                            "unit": {
                              "type": "string",
                              "title": "Unit",
                              "description": "The rate-card unit.",
                              "examples": [
                                "listings"
                              ]
                            },
                            "credits": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 0,
                              "title": "Credits",
                              "description": "Credits per `perUnits` units; null when no rate card carries the unit.",
                              "examples": [
                                1
                              ]
                            },
                            "perUnits": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 0,
                              "title": "Per units",
                              "description": "How many units the credits buy; null when not priced.",
                              "examples": [
                                10
                              ]
                            },
                            "rateVersion": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Rate version",
                              "description": "The rate card the price comes from, for example c3; null when not priced.",
                              "examples": [
                                "c3"
                              ]
                            },
                            "totalCredits": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 0,
                              "title": "Total credits",
                              "description": "The newest edition in full: ceil(records x credits / perUnits). Null when not computed or not priced.",
                              "examples": [
                                64815
                              ]
                            }
                          }
                        },
                        "saleState": {
                          "type": "string",
                          "enum": [
                            "on_sale",
                            "below_coverage_floor",
                            "not_computed",
                            "not_priced"
                          ],
                          "title": "Sale state",
                          "description": "on_sale: can be bought. below_coverage_floor: the newest edition holds fewer than minRecords records. not_computed: no edition counted yet. not_priced: no rate card carries the unit.",
                          "examples": [
                            "on_sale"
                          ]
                        },
                        "licenceBody": {
                          "type": "string",
                          "title": "Licence text",
                          "description": "The licence in full, shown before buying.",
                          "examples": [
                            "This licence covers a dataset snapshot bought from Rewalto."
                          ]
                        },
                        "sample": {
                          "type": "array",
                          "title": "Sample",
                          "description": "Up to 100 records of the newest edition, free. Empty when no edition is counted.",
                          "maxItems": 100,
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The snapshot id.",
              "examples": [
                "listings_blinkit_in"
              ],
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          }
        ]
      }
    },
    "/v1/snapshots/{id}/quote": {
      "post": {
        "operationId": "quoteSnapshot",
        "summary": "Quote a dataset snapshot",
        "description": "Prices the newest edition of a snapshot in full, in credits from the rate card (D-1553), and returns the quote with the licence it is sold under, in full (D-1556). Approve it with POST /v1/quotes/{id}/approve: that holds the credits and accepts that licence version. Any member of the organisation may buy (D-1557). A snapshot below its coverage floor, not counted or not priced is refused with `not_for_sale`.",
        "tags": [
          "Snapshots"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Snapshot quote",
                  "description": "A quote for the newest edition of a snapshot in full, in credits (D-1553), with the licence it is sold under. Approve it with POST /v1/quotes/{id}/approve: that holds the credits and accepts the licence version shown here. Nothing is charged until the export is delivered, and never more than the quote.",
                  "additionalProperties": false,
                  "required": [
                    "quote",
                    "snapshot",
                    "licence"
                  ],
                  "properties": {
                    "quote": {
                      "$ref": "#/components/schemas/Quote"
                    },
                    "snapshot": {
                      "type": "object",
                      "title": "Snapshot quoted",
                      "description": "The edition the quote is for.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "name",
                        "asOf",
                        "recordCount",
                        "format",
                        "downloadMonths"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The snapshot id.",
                          "examples": [
                            "listings_blinkit_in"
                          ],
                          "pattern": "^[a-z][a-z0-9_]{1,63}$"
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "The snapshot name.",
                          "examples": [
                            "Blinkit listings, all India"
                          ]
                        },
                        "asOf": {
                          "type": "string",
                          "title": "As of",
                          "description": "The edition date (IST).",
                          "examples": [
                            "2026-10-16"
                          ],
                          "format": "date"
                        },
                        "recordCount": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Records",
                          "description": "Records in the edition: what is quoted.",
                          "examples": [
                            648142
                          ]
                        },
                        "format": {
                          "type": "string",
                          "const": "jsonl",
                          "title": "Format",
                          "description": "JSON Lines."
                        },
                        "downloadMonths": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Download months",
                          "description": "How long it can be downloaded (D-1555).",
                          "examples": [
                            12
                          ]
                        }
                      }
                    },
                    "licence": {
                      "type": "object",
                      "title": "Licence",
                      "description": "The licence in full, shown before approval (D-1556).",
                      "additionalProperties": false,
                      "required": [
                        "version",
                        "title",
                        "summary",
                        "body"
                      ],
                      "properties": {
                        "version": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Version",
                          "description": "Stored with the purchase.",
                          "examples": [
                            1
                          ]
                        },
                        "title": {
                          "type": "string",
                          "title": "Title",
                          "description": "The licence title.",
                          "examples": [
                            "Rewalto dataset licence, version 1"
                          ]
                        },
                        "summary": {
                          "type": "string",
                          "title": "Summary",
                          "description": "One line.",
                          "examples": [
                            "Use it inside your own organisation."
                          ]
                        },
                        "body": {
                          "type": "string",
                          "title": "Text",
                          "description": "The licence in full.",
                          "examples": [
                            "This licence covers a dataset snapshot bought from Rewalto."
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`\n- `scope_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `not_for_sale`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The snapshot id.",
              "examples": [
                "listings_blinkit_in"
              ],
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          }
        ]
      }
    },
    "/v1/staff/audit": {
      "get": {
        "operationId": "listStaffAudit",
        "summary": "Read the audit of privileged calls",
        "description": "One row per privileged call, newest first: every staff route call (done, no change, read, refused, denied or failed, with who, the role it needed, what, on what and the reason) and every staff operation run in the database (partition moves, promotional grants, collector and lane controls). Exact filters narrow it; `before` pages to older rows. Rewalto staff holding the audit_reader role only, with a signed-in session; an API key is always refused (`forbidden`). Reading is itself recorded.",
        "tags": [
          "Staff: audit"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "StaffAuditPage",
                  "description": "A page of the audit of privileged calls, newest first.",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "entries",
                    "nextBefore"
                  ],
                  "properties": {
                    "entries": {
                      "type": "array",
                      "items": {
                        "title": "StaffAuditEntry",
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "at",
                          "requestId",
                          "callerKind",
                          "callerId",
                          "role",
                          "action",
                          "target",
                          "outcome",
                          "refusal",
                          "reason",
                          "detail"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The row id (digits); rows are numbered in the order written."
                          },
                          "at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "requestId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "The API request id; null for a database operation."
                          },
                          "callerKind": {
                            "type": "string",
                            "enum": [
                              "session",
                              "api_key",
                              "database",
                              "service_key"
                            ]
                          },
                          "callerId": {
                            "type": "string",
                            "description": "Clerk user id, API key id, service key id (`service_key`), or the name given."
                          },
                          "role": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "The staff role the call needed; null for a database operation or a service key call."
                          },
                          "action": {
                            "type": "string",
                            "pattern": "^[a-z][a-z_]{1,40}\\.[a-z][a-z_]{1,40}$"
                          },
                          "target": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "outcome": {
                            "type": "string",
                            "enum": [
                              "done",
                              "no_change",
                              "read",
                              "refused",
                              "denied",
                              "failed"
                            ]
                          },
                          "refusal": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "The error code of a refused, denied or failed call."
                          },
                          "reason": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "The staff member's reason, where given."
                          },
                          "detail": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "Small facts about the call (status before and after, counts, the database login)."
                          }
                        }
                      }
                    },
                    "nextBefore": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "description": "Pass as `before` for the next (older) page; null when this is the last."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "action",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z_]{1,40}\\.[a-z][a-z_]{1,40}$",
              "examples": [
                "recipe.publish"
              ]
            },
            "description": "Only this action, e.g. `recipe.publish`, `promo.grant`, `partition.move`."
          },
          {
            "name": "target",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 300,
              "examples": [
                "blinkit@6.0.0"
              ]
            },
            "description": "Only this target, exactly, e.g. `blinkit@6.0.0`."
          },
          {
            "name": "callerId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "examples": [
                "user_2abc"
              ]
            },
            "description": "Only this caller: a Clerk user id, an API key id, or the name a database operation gave."
          },
          {
            "name": "outcome",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(done|no_change|read|refused|denied|failed)$",
              "examples": [
                "denied"
              ]
            },
            "description": "Only this outcome."
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time",
              "examples": [
                "2026-10-16T00:00:00Z"
              ]
            },
            "description": "Only rows at or after this time."
          },
          {
            "name": "before",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[1-9][0-9]{0,18}$"
            },
            "description": "The nextBefore of the previous page. Omit for the newest rows."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]{1,3}$",
              "examples": [
                "50"
              ]
            },
            "description": "Rows per page, 1 to 200 (default 50). Sent as digits in the query string."
          }
        ]
      }
    },
    "/v1/staff/data-requests": {
      "get": {
        "operationId": "listStaffDataRequests",
        "summary": "The data request queue (staff)",
        "description": "Tracked data requests, soonest `respondBy` first: by default the open ones (`received` and `in_review`), or one status, or `all`. Each has the requester’s verified email (`replyTo`), organisation and user, whether it is overdue, and the replies so far; `overdue` counts the overdue ones listed. Rewalto staff only: a signed-in session whose user holds the staff role `data_request_responder` (Varun, as super-admin, holds it); an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: data requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "StaffDataRequestQueue",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "overdue"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "description": "Soonest respondBy first.",
                      "items": {
                        "title": "StaffDataRequest",
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "reference",
                          "kind",
                          "text",
                          "query",
                          "subject",
                          "surface",
                          "status",
                          "createdAt",
                          "inReviewAt",
                          "answeredAt",
                          "closedAt",
                          "respondBy",
                          "respondByLocal",
                          "timeZone",
                          "overdue",
                          "respondedInTime",
                          "owner",
                          "replyTo",
                          "emailErasedAt",
                          "orgId",
                          "userId",
                          "replies"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reference": {
                            "type": "string",
                            "pattern": "^DR-[0-9]{6,}$",
                            "description": "The reference to quote, e.g. DR-000123."
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "missing_data",
                              "not_held"
                            ]
                          },
                          "text": {
                            "type": "string"
                          },
                          "query": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "subject": {
                            "type": "string"
                          },
                          "surface": {
                            "type": "string",
                            "enum": [
                              "catalogue_page",
                              "search",
                              "intake",
                              "api",
                              "cli",
                              "mcp"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "received",
                              "in_review",
                              "answered",
                              "closed"
                            ],
                            "description": "received: recorded, not looked at yet. in_review: staff are on it. answered: staff replied. closed: finished. Treat an unknown value as in progress."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "When it was received."
                          },
                          "inReviewAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "answeredAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "description": "The first reply: the first human response."
                          },
                          "closedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "respondBy": {
                            "type": "string",
                            "format": "date-time",
                            "description": "The promised time of the first human response, computed by the server when the request was made from the commitment then in force (business days, working days, holidays, time zone). It never moves. Show this; never compute a deadline in the frontend."
                          },
                          "respondByLocal": {
                            "type": "string",
                            "description": "respondBy as local wall time in `timeZone` with its offset, e.g. 2026-10-20T18:00:00+05:30."
                          },
                          "timeZone": {
                            "type": "string",
                            "description": "The commitment’s time zone, e.g. Asia/Kolkata."
                          },
                          "overdue": {
                            "type": "boolean",
                            "description": "No reply yet, not closed, and respondBy has passed (at the time of this answer)."
                          },
                          "respondedInTime": {
                            "type": [
                              "null",
                              "boolean"
                            ],
                            "description": "Whether the first reply came by respondBy; null until there is a reply."
                          },
                          "owner": {
                            "type": "string",
                            "description": "Who answers for the request (a name)."
                          },
                          "replyTo": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "Where the reply goes: the requester’s verified account email, as it was when asked. null once erased, 90 days after the request was closed (D-1832)."
                          },
                          "emailErasedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "description": "When replyTo was erased (90 days after closing); null while it is kept."
                          },
                          "orgId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "userId": {
                            "type": "string",
                            "description": "The requester’s Clerk user id."
                          },
                          "replies": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "body",
                                "at",
                                "by"
                              ],
                              "properties": {
                                "body": {
                                  "type": "string"
                                },
                                "at": {
                                  "type": "string",
                                  "format": "date-time"
                                },
                                "by": {
                                  "type": "string",
                                  "description": "staff:<Clerk user id>"
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    "overdue": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "How many of `data` are overdue."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(open|all|received|in_review|answered|closed)$"
            },
            "description": "open (default): received and in_review. all: every status. Or one of received, in_review, answered, closed."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([1-9]|[1-9][0-9]|1[0-9]{2}|200)$"
            },
            "description": "At most this many (1-200, default 100)."
          }
        ]
      }
    },
    "/v1/staff/data-requests/{reference}/reply": {
      "post": {
        "operationId": "replyToDataRequest",
        "summary": "Record a reply to a data request (staff)",
        "description": "Records Rewalto’s reply on a tracked request and sets it `answered`; the first reply is the first human response that `respondBy` is measured against (`firstReply`). The requester sees it in GET /v1/data-requests. A closed request takes no reply (`catalogue_refused`). Core has no email sender yet, so nothing is emailed: `acknowledgmentEmail` and `delivery` say `not_sent` until one exists. Until then, send the same reply to `replyTo` by hand from vm@rewalto.com (D-1832). Rewalto staff only: a signed-in session whose user holds the staff role `data_request_responder` (Varun, as super-admin, holds it); an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: data requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "DataRequestReplyAnswer",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "request",
                    "firstReply",
                    "delivery",
                    "message"
                  ],
                  "properties": {
                    "request": {
                      "title": "StaffDataRequest",
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "reference",
                        "kind",
                        "text",
                        "query",
                        "subject",
                        "surface",
                        "status",
                        "createdAt",
                        "inReviewAt",
                        "answeredAt",
                        "closedAt",
                        "respondBy",
                        "respondByLocal",
                        "timeZone",
                        "overdue",
                        "respondedInTime",
                        "owner",
                        "replyTo",
                        "emailErasedAt",
                        "orgId",
                        "userId",
                        "replies"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "reference": {
                          "type": "string",
                          "pattern": "^DR-[0-9]{6,}$",
                          "description": "The reference to quote, e.g. DR-000123."
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "missing_data",
                            "not_held"
                          ]
                        },
                        "text": {
                          "type": "string"
                        },
                        "query": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "subject": {
                          "type": "string"
                        },
                        "surface": {
                          "type": "string",
                          "enum": [
                            "catalogue_page",
                            "search",
                            "intake",
                            "api",
                            "cli",
                            "mcp"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "answered",
                            "closed"
                          ],
                          "description": "received: recorded, not looked at yet. in_review: staff are on it. answered: staff replied. closed: finished. Treat an unknown value as in progress."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "When it was received."
                        },
                        "inReviewAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "answeredAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "The first reply: the first human response."
                        },
                        "closedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "respondBy": {
                          "type": "string",
                          "format": "date-time",
                          "description": "The promised time of the first human response, computed by the server when the request was made from the commitment then in force (business days, working days, holidays, time zone). It never moves. Show this; never compute a deadline in the frontend."
                        },
                        "respondByLocal": {
                          "type": "string",
                          "description": "respondBy as local wall time in `timeZone` with its offset, e.g. 2026-10-20T18:00:00+05:30."
                        },
                        "timeZone": {
                          "type": "string",
                          "description": "The commitment’s time zone, e.g. Asia/Kolkata."
                        },
                        "overdue": {
                          "type": "boolean",
                          "description": "No reply yet, not closed, and respondBy has passed (at the time of this answer)."
                        },
                        "respondedInTime": {
                          "type": [
                            "null",
                            "boolean"
                          ],
                          "description": "Whether the first reply came by respondBy; null until there is a reply."
                        },
                        "owner": {
                          "type": "string",
                          "description": "Who answers for the request (a name)."
                        },
                        "replyTo": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "description": "Where the reply goes: the requester’s verified account email, as it was when asked. null once erased, 90 days after the request was closed (D-1832)."
                        },
                        "emailErasedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "When replyTo was erased (90 days after closing); null while it is kept."
                        },
                        "orgId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "userId": {
                          "type": "string",
                          "description": "The requester’s Clerk user id."
                        },
                        "replies": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "body",
                              "at",
                              "by"
                            ],
                            "properties": {
                              "body": {
                                "type": "string"
                              },
                              "at": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "by": {
                                "type": "string",
                                "description": "staff:<Clerk user id>"
                              }
                            }
                          }
                        }
                      }
                    },
                    "firstReply": {
                      "type": "boolean",
                      "description": "This was the first human response (the one respondBy is measured against)."
                    },
                    "delivery": {
                      "type": "string",
                      "enum": [
                        "sent",
                        "not_sent"
                      ],
                      "description": "`not_sent`: Core has no email sender yet, so the reply is recorded but not emailed; send it to replyTo yourself."
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `catalogue_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^DR-[0-9]{6,}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "title": "DataRequestReply",
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "body"
                ],
                "properties": {
                  "body": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 10000
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/staff/data-requests/{reference}/status": {
      "post": {
        "operationId": "setDataRequestStatus",
        "summary": "Set a data request’s status (staff)",
        "description": "Moves a tracked request to `in_review` (from `received`) or `closed` (from any open or answered state), with an optional reason. `answered` comes only from a reply; `closed` is final. Asking for the status it already has changes nothing (`changed: false`). A move the database does not allow is `catalogue_refused` with its reason. Rewalto staff only: a signed-in session whose user holds the staff role `data_request_responder` (Varun, as super-admin, holds it); an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: data requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "SetDataRequestStatusAnswer",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "request",
                    "changed"
                  ],
                  "properties": {
                    "request": {
                      "title": "StaffDataRequest",
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "reference",
                        "kind",
                        "text",
                        "query",
                        "subject",
                        "surface",
                        "status",
                        "createdAt",
                        "inReviewAt",
                        "answeredAt",
                        "closedAt",
                        "respondBy",
                        "respondByLocal",
                        "timeZone",
                        "overdue",
                        "respondedInTime",
                        "owner",
                        "replyTo",
                        "emailErasedAt",
                        "orgId",
                        "userId",
                        "replies"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "reference": {
                          "type": "string",
                          "pattern": "^DR-[0-9]{6,}$",
                          "description": "The reference to quote, e.g. DR-000123."
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "missing_data",
                            "not_held"
                          ]
                        },
                        "text": {
                          "type": "string"
                        },
                        "query": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "subject": {
                          "type": "string"
                        },
                        "surface": {
                          "type": "string",
                          "enum": [
                            "catalogue_page",
                            "search",
                            "intake",
                            "api",
                            "cli",
                            "mcp"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "answered",
                            "closed"
                          ],
                          "description": "received: recorded, not looked at yet. in_review: staff are on it. answered: staff replied. closed: finished. Treat an unknown value as in progress."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "When it was received."
                        },
                        "inReviewAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "answeredAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "The first reply: the first human response."
                        },
                        "closedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "respondBy": {
                          "type": "string",
                          "format": "date-time",
                          "description": "The promised time of the first human response, computed by the server when the request was made from the commitment then in force (business days, working days, holidays, time zone). It never moves. Show this; never compute a deadline in the frontend."
                        },
                        "respondByLocal": {
                          "type": "string",
                          "description": "respondBy as local wall time in `timeZone` with its offset, e.g. 2026-10-20T18:00:00+05:30."
                        },
                        "timeZone": {
                          "type": "string",
                          "description": "The commitment’s time zone, e.g. Asia/Kolkata."
                        },
                        "overdue": {
                          "type": "boolean",
                          "description": "No reply yet, not closed, and respondBy has passed (at the time of this answer)."
                        },
                        "respondedInTime": {
                          "type": [
                            "null",
                            "boolean"
                          ],
                          "description": "Whether the first reply came by respondBy; null until there is a reply."
                        },
                        "owner": {
                          "type": "string",
                          "description": "Who answers for the request (a name)."
                        },
                        "replyTo": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "description": "Where the reply goes: the requester’s verified account email, as it was when asked. null once erased, 90 days after the request was closed (D-1832)."
                        },
                        "emailErasedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "When replyTo was erased (90 days after closing); null while it is kept."
                        },
                        "orgId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "userId": {
                          "type": "string",
                          "description": "The requester’s Clerk user id."
                        },
                        "replies": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "body",
                              "at",
                              "by"
                            ],
                            "properties": {
                              "body": {
                                "type": "string"
                              },
                              "at": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "by": {
                                "type": "string",
                                "description": "staff:<Clerk user id>"
                              }
                            }
                          }
                        }
                      }
                    },
                    "changed": {
                      "type": "boolean",
                      "description": "false when it already had that status."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `catalogue_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^DR-[0-9]{6,}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "title": "SetDataRequestStatus",
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "in_review",
                      "closed"
                    ],
                    "description": "received -> in_review; received, in_review or answered -> closed. answered comes from a reply. closed is final."
                  },
                  "reason": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 500
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/staff/finder-requests": {
      "get": {
        "operationId": "listFinderDemand",
        "summary": "The most-asked missing data (staff)",
        "description": "Data requests over the last `days` days (default 30): the most-asked subjects, most requests first, with how many organisations and anonymous askers asked and up to three example texts, and the latest requests. This is the demand plan 21 ranks new datasets by. Rewalto staff only: a signed-in session whose user holds the staff role `demand_reader`; an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: data requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/FinderDemand"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([1-9]|[1-9][0-9]|[1-2][0-9]{2}|3[0-5][0-9]|36[0-5])$"
            },
            "description": "Look back this many days (1-365, default 30)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([1-9]|[1-9][0-9]|100)$"
            },
            "description": "At most this many subjects and recent requests (1-100, default 20)."
          }
        ]
      }
    },
    "/v1/staff/order-requests": {
      "get": {
        "operationId": "listStaffOrderRequests",
        "summary": "The order request queue (staff)",
        "description": "Every organisation's order requests, oldest open first: by default the open ones (received and in_review), or one status, or all. Rewalto staff only: a signed-in session whose user holds the staff role `data_request_responder`; an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: order requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "title": "Order request (staff)",
                        "additionalProperties": false,
                        "required": [
                          "reference",
                          "kind",
                          "offerKey",
                          "offerVersion",
                          "offerName",
                          "addOns",
                          "quantity",
                          "billing",
                          "note",
                          "status",
                          "statusNote",
                          "statusAt",
                          "createdAt",
                          "paidAt",
                          "paymentOrderId",
                          "setup",
                          "deliveries",
                          "orgId",
                          "userId",
                          "replyTo"
                        ],
                        "properties": {
                          "reference": {
                            "type": "string",
                            "pattern": "^OR-[0-9]{6,}$",
                            "examples": [
                              "OR-000001"
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "enum": [
                              "pilot",
                              "order"
                            ]
                          },
                          "offerKey": {
                            "type": "string"
                          },
                          "offerVersion": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "offerName": {
                            "type": "string"
                          },
                          "addOns": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "key",
                                "quantity"
                              ],
                              "properties": {
                                "key": {
                                  "type": "string",
                                  "pattern": "^[a-z][a-zA-Z0-9_]{0,40}$",
                                  "description": "One of the offer’s addOns keys (cities, darkStores, ...)."
                                },
                                "quantity": {
                                  "type": "integer",
                                  "minimum": 1,
                                  "maximum": 100
                                }
                              }
                            }
                          },
                          "quantity": {
                            "type": "integer",
                            "minimum": 1
                          },
                          "billing": {
                            "type": "string",
                            "enum": [
                              "one_off",
                              "month",
                              "year"
                            ]
                          },
                          "note": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "received",
                              "in_review",
                              "paid",
                              "fulfilled",
                              "declined"
                            ],
                            "description": "received, then paid (a basket checkout) or in_review; fulfilled when Rewalto has delivered it (or entitled the pilot), declined otherwise."
                          },
                          "statusNote": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "statusAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "paidAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time",
                            "description": "When its basket was paid; null when not paid online."
                          },
                          "paymentOrderId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "uuid",
                            "description": "The basket order it was paid with (the paid value the payment page returns to), or null."
                          },
                          "setup": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "description": "The buyer’s choices in force (POST /v1/order-requests/{reference}/setup), or null.",
                            "additionalProperties": false,
                            "required": [
                              "choices",
                              "note",
                              "setAt"
                            ],
                            "properties": {
                              "choices": {
                                "type": "object",
                                "additionalProperties": true
                              },
                              "note": {
                                "type": [
                                  "null",
                                  "string"
                                ]
                              },
                              "setAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          },
                          "deliveries": {
                            "type": "array",
                            "description": "Files Rewalto delivered, ready to download: POST /v1/order-requests/{reference}/deliveries/{downloadId}/link.",
                            "items": {
                              "type": "object",
                              "additionalProperties": false,
                              "required": [
                                "downloadId",
                                "label",
                                "kind",
                                "fileName",
                                "bytes",
                                "readyAt"
                              ],
                              "properties": {
                                "downloadId": {
                                  "type": "string",
                                  "format": "uuid"
                                },
                                "label": {
                                  "type": "string"
                                },
                                "kind": {
                                  "type": "string",
                                  "enum": [
                                    "file",
                                    "report"
                                  ]
                                },
                                "fileName": {
                                  "type": "string"
                                },
                                "bytes": {
                                  "type": "integer",
                                  "minimum": 1
                                },
                                "readyAt": {
                                  "type": "string",
                                  "format": "date-time"
                                }
                              }
                            }
                          },
                          "orgId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "userId": {
                            "type": "string"
                          },
                          "replyTo": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "description": "The requester’s verified email, when the session had one."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(open|all|received|in_review|paid|fulfilled|declined)$"
            },
            "description": "open (default): received and in_review. all: every status. Or one status."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([1-9]|[1-9][0-9]|1[0-9]{2}|200)$"
            },
            "description": "At most this many (1-200, default 100)."
          }
        ]
      }
    },
    "/v1/staff/order-requests/{reference}/deliveries": {
      "post": {
        "operationId": "addOrderRequestDelivery",
        "summary": "Deliver a file for an order request (staff)",
        "description": "Declares a file delivered for an order request (a dataset pack's file, a report) and answers a signed PUT to upload it: send exactly the headers given, a body of exactly bytes with that SHA-256. Then mark it ready (markOrderDeliveryReady); the buyer sees it and downloads it from then on. Rewalto staff only: a signed-in session whose user holds the staff role `data_request_responder`; an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: order requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "downloadId",
                        "upload"
                      ],
                      "properties": {
                        "downloadId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "upload": {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "url",
                            "headers",
                            "expiresAt"
                          ],
                          "description": "PUT the file here with exactly these headers; then mark it ready.",
                          "properties": {
                            "url": {
                              "type": "string",
                              "format": "uri"
                            },
                            "headers": {
                              "type": "object",
                              "additionalProperties": {
                                "type": "string"
                              }
                            },
                            "expiresAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^OR-[0-9]{6,}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "label",
                  "kind",
                  "fileName",
                  "bytes",
                  "sha256",
                  "contentType"
                ],
                "properties": {
                  "label": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "file",
                      "report"
                    ]
                  },
                  "fileName": {
                    "type": "string",
                    "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]{0,150}$"
                  },
                  "bytes": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 5000000000
                  },
                  "sha256": {
                    "type": "string",
                    "pattern": "^[0-9a-f]{64}$"
                  },
                  "contentType": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 120
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/staff/order-requests/{reference}/deliveries/{downloadId}/ready": {
      "post": {
        "operationId": "markOrderDeliveryReady",
        "summary": "Mark a delivered file ready (staff)",
        "description": "Checks the uploaded file's size and SHA-256 against what was declared and, when they match, makes it visible and downloadable to the buyer (deliveries on GET /v1/order-requests). A file that is missing or differs is invalid_request, and stays hidden. Marking it again changes nothing. Rewalto staff only: a signed-in session whose user holds the staff role `data_request_responder`; an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: order requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Order request (staff)",
                      "additionalProperties": false,
                      "required": [
                        "reference",
                        "kind",
                        "offerKey",
                        "offerVersion",
                        "offerName",
                        "addOns",
                        "quantity",
                        "billing",
                        "note",
                        "status",
                        "statusNote",
                        "statusAt",
                        "createdAt",
                        "paidAt",
                        "paymentOrderId",
                        "setup",
                        "deliveries",
                        "orgId",
                        "userId",
                        "replyTo"
                      ],
                      "properties": {
                        "reference": {
                          "type": "string",
                          "pattern": "^OR-[0-9]{6,}$",
                          "examples": [
                            "OR-000001"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "pilot",
                            "order"
                          ]
                        },
                        "offerKey": {
                          "type": "string"
                        },
                        "offerVersion": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "offerName": {
                          "type": "string"
                        },
                        "addOns": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "key",
                              "quantity"
                            ],
                            "properties": {
                              "key": {
                                "type": "string",
                                "pattern": "^[a-z][a-zA-Z0-9_]{0,40}$",
                                "description": "One of the offer’s addOns keys (cities, darkStores, ...)."
                              },
                              "quantity": {
                                "type": "integer",
                                "minimum": 1,
                                "maximum": 100
                              }
                            }
                          }
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "billing": {
                          "type": "string",
                          "enum": [
                            "one_off",
                            "month",
                            "year"
                          ]
                        },
                        "note": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "paid",
                            "fulfilled",
                            "declined"
                          ],
                          "description": "received, then paid (a basket checkout) or in_review; fulfilled when Rewalto has delivered it (or entitled the pilot), declined otherwise."
                        },
                        "statusNote": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "statusAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "paidAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "When its basket was paid; null when not paid online."
                        },
                        "paymentOrderId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid",
                          "description": "The basket order it was paid with (the paid value the payment page returns to), or null."
                        },
                        "setup": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "description": "The buyer’s choices in force (POST /v1/order-requests/{reference}/setup), or null.",
                          "additionalProperties": false,
                          "required": [
                            "choices",
                            "note",
                            "setAt"
                          ],
                          "properties": {
                            "choices": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "note": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "setAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        },
                        "deliveries": {
                          "type": "array",
                          "description": "Files Rewalto delivered, ready to download: POST /v1/order-requests/{reference}/deliveries/{downloadId}/link.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "downloadId",
                              "label",
                              "kind",
                              "fileName",
                              "bytes",
                              "readyAt"
                            ],
                            "properties": {
                              "downloadId": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "label": {
                                "type": "string"
                              },
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "file",
                                  "report"
                                ]
                              },
                              "fileName": {
                                "type": "string"
                              },
                              "bytes": {
                                "type": "integer",
                                "minimum": 1
                              },
                              "readyAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        },
                        "orgId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "userId": {
                          "type": "string"
                        },
                        "replyTo": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "description": "The requester’s verified email, when the session had one."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^OR-[0-9]{6,}$"
            }
          },
          {
            "name": "downloadId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ]
      }
    },
    "/v1/staff/order-requests/{reference}/status": {
      "post": {
        "operationId": "setOrderRequestStatus",
        "summary": "Set an order request’s status (staff)",
        "description": "Moves an order request to in_review, fulfilled or declined, with an optional note the requester sees. Fulfilled and declined are final. A pilot is fulfilled after entitling the organisation (ledger.grant_plan_entitlement). Rewalto staff only: a signed-in session whose user holds the staff role `data_request_responder`; an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: order requests"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Order request (staff)",
                      "additionalProperties": false,
                      "required": [
                        "reference",
                        "kind",
                        "offerKey",
                        "offerVersion",
                        "offerName",
                        "addOns",
                        "quantity",
                        "billing",
                        "note",
                        "status",
                        "statusNote",
                        "statusAt",
                        "createdAt",
                        "paidAt",
                        "paymentOrderId",
                        "setup",
                        "deliveries",
                        "orgId",
                        "userId",
                        "replyTo"
                      ],
                      "properties": {
                        "reference": {
                          "type": "string",
                          "pattern": "^OR-[0-9]{6,}$",
                          "examples": [
                            "OR-000001"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "pilot",
                            "order"
                          ]
                        },
                        "offerKey": {
                          "type": "string"
                        },
                        "offerVersion": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "offerName": {
                          "type": "string"
                        },
                        "addOns": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "key",
                              "quantity"
                            ],
                            "properties": {
                              "key": {
                                "type": "string",
                                "pattern": "^[a-z][a-zA-Z0-9_]{0,40}$",
                                "description": "One of the offer’s addOns keys (cities, darkStores, ...)."
                              },
                              "quantity": {
                                "type": "integer",
                                "minimum": 1,
                                "maximum": 100
                              }
                            }
                          }
                        },
                        "quantity": {
                          "type": "integer",
                          "minimum": 1
                        },
                        "billing": {
                          "type": "string",
                          "enum": [
                            "one_off",
                            "month",
                            "year"
                          ]
                        },
                        "note": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "paid",
                            "fulfilled",
                            "declined"
                          ],
                          "description": "received, then paid (a basket checkout) or in_review; fulfilled when Rewalto has delivered it (or entitled the pilot), declined otherwise."
                        },
                        "statusNote": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "statusAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "paidAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time",
                          "description": "When its basket was paid; null when not paid online."
                        },
                        "paymentOrderId": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "uuid",
                          "description": "The basket order it was paid with (the paid value the payment page returns to), or null."
                        },
                        "setup": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "description": "The buyer’s choices in force (POST /v1/order-requests/{reference}/setup), or null.",
                          "additionalProperties": false,
                          "required": [
                            "choices",
                            "note",
                            "setAt"
                          ],
                          "properties": {
                            "choices": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "note": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "setAt": {
                              "type": "string",
                              "format": "date-time"
                            }
                          }
                        },
                        "deliveries": {
                          "type": "array",
                          "description": "Files Rewalto delivered, ready to download: POST /v1/order-requests/{reference}/deliveries/{downloadId}/link.",
                          "items": {
                            "type": "object",
                            "additionalProperties": false,
                            "required": [
                              "downloadId",
                              "label",
                              "kind",
                              "fileName",
                              "bytes",
                              "readyAt"
                            ],
                            "properties": {
                              "downloadId": {
                                "type": "string",
                                "format": "uuid"
                              },
                              "label": {
                                "type": "string"
                              },
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "file",
                                  "report"
                                ]
                              },
                              "fileName": {
                                "type": "string"
                              },
                              "bytes": {
                                "type": "integer",
                                "minimum": 1
                              },
                              "readyAt": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        },
                        "orgId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "userId": {
                          "type": "string"
                        },
                        "replyTo": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "description": "The requester’s verified email, when the session had one."
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `catalogue_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^OR-[0-9]{6,}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "in_review",
                      "fulfilled",
                      "declined"
                    ]
                  },
                  "note": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 2000
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/staff/problem-reports": {
      "get": {
        "operationId": "listStaffProblemReports",
        "summary": "The problem report queue (staff)",
        "description": "Problem reports across organisations, oldest first: by default the open ones (`received`, `in_review`), or one status, or `all`. Rewalto staff only: a signed-in session whose user holds the staff role `problem_responder` (Varun, as super-admin, holds it; nobody else at launch); an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: problem reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "StaffProblemReportQueue",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "description": "Oldest first.",
                      "items": {
                        "title": "StaffProblemReport",
                        "type": "object",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "reference",
                          "status",
                          "rowKind",
                          "rowId",
                          "evidenceSha256",
                          "category",
                          "note",
                          "receiptId",
                          "createdAt",
                          "inReviewAt",
                          "resolvedAt",
                          "resolutionNote",
                          "refund",
                          "orgId",
                          "reportedBy"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reference": {
                            "type": "string",
                            "pattern": "^PR-[0-9]{6,}$",
                            "description": "The receipt reference to quote, e.g. PR-000123."
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "received",
                              "in_review",
                              "confirmed",
                              "rejected"
                            ],
                            "description": "received: recorded. in_review: staff are checking. confirmed: the problem is real (see refund). rejected: not a problem (see resolutionNote). Treat an unknown value as in progress."
                          },
                          "rowKind": {
                            "type": "string",
                            "enum": [
                              "listing",
                              "observation"
                            ]
                          },
                          "rowId": {
                            "type": "string"
                          },
                          "evidenceSha256": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "category": {
                            "type": "string",
                            "enum": [
                              "wrong_price",
                              "wrong_availability",
                              "wrong_product_details",
                              "broken_evidence",
                              "duplicate_row",
                              "other"
                            ]
                          },
                          "note": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "receiptId": {
                            "type": "string",
                            "description": "The read receipt (rcp_…) that delivered the row; a confirmed problem refunds it."
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "inReviewAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "resolvedAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "format": "date-time"
                          },
                          "resolutionNote": {
                            "type": [
                              "null",
                              "string"
                            ]
                          },
                          "refund": {
                            "type": [
                              "null",
                              "object"
                            ],
                            "additionalProperties": false,
                            "required": [
                              "status",
                              "credits",
                              "refundId",
                              "reason"
                            ],
                            "description": "Set when confirmed: what the refund of the receipt did. refunded: credits returned. already_refunded: the receipt was refunded before. refused: the refund rules refused it (reason). not_requested: confirmed without a refund.",
                            "properties": {
                              "status": {
                                "type": "string",
                                "enum": [
                                  "refunded",
                                  "already_refunded",
                                  "refused",
                                  "not_requested"
                                ]
                              },
                              "credits": {
                                "type": [
                                  "null",
                                  "integer"
                                ],
                                "minimum": 0
                              },
                              "refundId": {
                                "type": [
                                  "null",
                                  "string"
                                ]
                              },
                              "reason": {
                                "type": [
                                  "null",
                                  "string"
                                ]
                              }
                            }
                          },
                          "orgId": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "reportedBy": {
                            "type": "string",
                            "description": "The reporter’s Clerk user id."
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(open|all|received|in_review|confirmed|rejected)$"
            },
            "description": "open (default): received and in_review. all, or one status."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([1-9]|[1-9][0-9]|1[0-9]{2}|200)$"
            },
            "description": "At most this many (1-200, default 100)."
          }
        ]
      }
    },
    "/v1/staff/problem-reports/{reference}/resolve": {
      "post": {
        "operationId": "resolveProblemReport",
        "summary": "Confirm or reject a problem report (staff)",
        "description": "Resolves an open report, finally. `confirmed` refunds the read receipt that delivered the row through the existing refund (POST /v1/credits/refunds’ own logic and rules: once per receipt; refused when nothing was charged, the same data was read again, or under unlimited credits), unless `refund: false`; the answer’s `refund` says what happened. `rejected` refunds nothing. The note is shown to the customer. A resolved report is refused (`invalid_request`). Rewalto staff only: a signed-in session whose user holds the staff role `problem_responder` (Varun, as super-admin, holds it; nobody else at launch); an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: problem reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "StaffProblemReportChange",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "report",
                    "changed"
                  ],
                  "properties": {
                    "report": {
                      "title": "StaffProblemReport",
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "reference",
                        "status",
                        "rowKind",
                        "rowId",
                        "evidenceSha256",
                        "category",
                        "note",
                        "receiptId",
                        "createdAt",
                        "inReviewAt",
                        "resolvedAt",
                        "resolutionNote",
                        "refund",
                        "orgId",
                        "reportedBy"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "reference": {
                          "type": "string",
                          "pattern": "^PR-[0-9]{6,}$",
                          "description": "The receipt reference to quote, e.g. PR-000123."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "confirmed",
                            "rejected"
                          ],
                          "description": "received: recorded. in_review: staff are checking. confirmed: the problem is real (see refund). rejected: not a problem (see resolutionNote). Treat an unknown value as in progress."
                        },
                        "rowKind": {
                          "type": "string",
                          "enum": [
                            "listing",
                            "observation"
                          ]
                        },
                        "rowId": {
                          "type": "string"
                        },
                        "evidenceSha256": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "category": {
                          "type": "string",
                          "enum": [
                            "wrong_price",
                            "wrong_availability",
                            "wrong_product_details",
                            "broken_evidence",
                            "duplicate_row",
                            "other"
                          ]
                        },
                        "note": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "receiptId": {
                          "type": "string",
                          "description": "The read receipt (rcp_…) that delivered the row; a confirmed problem refunds it."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "inReviewAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "resolvedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "resolutionNote": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "refund": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": false,
                          "required": [
                            "status",
                            "credits",
                            "refundId",
                            "reason"
                          ],
                          "description": "Set when confirmed: what the refund of the receipt did. refunded: credits returned. already_refunded: the receipt was refunded before. refused: the refund rules refused it (reason). not_requested: confirmed without a refund.",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "refunded",
                                "already_refunded",
                                "refused",
                                "not_requested"
                              ]
                            },
                            "credits": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 0
                            },
                            "refundId": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "reason": {
                              "type": [
                                "null",
                                "string"
                              ]
                            }
                          }
                        },
                        "orgId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "reportedBy": {
                          "type": "string",
                          "description": "The reporter’s Clerk user id."
                        }
                      }
                    },
                    "changed": {
                      "type": "boolean",
                      "description": "false when it already had that status."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^PR-[0-9]{6,}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "title": "ResolveProblemReport",
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "outcome",
                  "note"
                ],
                "properties": {
                  "outcome": {
                    "type": "string",
                    "enum": [
                      "confirmed",
                      "rejected"
                    ]
                  },
                  "note": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 400,
                    "description": "Why; shown to the customer, and the refund’s reason when confirmed."
                  },
                  "refund": {
                    "type": "boolean",
                    "description": "Confirmed only: refund the receipt that delivered the row (default true), through the existing refund and its rules. false: confirm without a refund."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/staff/problem-reports/{reference}/status": {
      "post": {
        "operationId": "setProblemReportStatus",
        "summary": "Mark a problem report in review (staff)",
        "description": "Moves a `received` report to `in_review`, with an optional note. Asking again changes nothing (`changed: false`); a resolved report is refused (`invalid_request`). Rewalto staff only: a signed-in session whose user holds the staff role `problem_responder` (Varun, as super-admin, holds it; nobody else at launch); an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: problem reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "title": "StaffProblemReportChange",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "report",
                    "changed"
                  ],
                  "properties": {
                    "report": {
                      "title": "StaffProblemReport",
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "reference",
                        "status",
                        "rowKind",
                        "rowId",
                        "evidenceSha256",
                        "category",
                        "note",
                        "receiptId",
                        "createdAt",
                        "inReviewAt",
                        "resolvedAt",
                        "resolutionNote",
                        "refund",
                        "orgId",
                        "reportedBy"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "reference": {
                          "type": "string",
                          "pattern": "^PR-[0-9]{6,}$",
                          "description": "The receipt reference to quote, e.g. PR-000123."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "received",
                            "in_review",
                            "confirmed",
                            "rejected"
                          ],
                          "description": "received: recorded. in_review: staff are checking. confirmed: the problem is real (see refund). rejected: not a problem (see resolutionNote). Treat an unknown value as in progress."
                        },
                        "rowKind": {
                          "type": "string",
                          "enum": [
                            "listing",
                            "observation"
                          ]
                        },
                        "rowId": {
                          "type": "string"
                        },
                        "evidenceSha256": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "category": {
                          "type": "string",
                          "enum": [
                            "wrong_price",
                            "wrong_availability",
                            "wrong_product_details",
                            "broken_evidence",
                            "duplicate_row",
                            "other"
                          ]
                        },
                        "note": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "receiptId": {
                          "type": "string",
                          "description": "The read receipt (rcp_…) that delivered the row; a confirmed problem refunds it."
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "inReviewAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "resolvedAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "format": "date-time"
                        },
                        "resolutionNote": {
                          "type": [
                            "null",
                            "string"
                          ]
                        },
                        "refund": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "additionalProperties": false,
                          "required": [
                            "status",
                            "credits",
                            "refundId",
                            "reason"
                          ],
                          "description": "Set when confirmed: what the refund of the receipt did. refunded: credits returned. already_refunded: the receipt was refunded before. refused: the refund rules refused it (reason). not_requested: confirmed without a refund.",
                          "properties": {
                            "status": {
                              "type": "string",
                              "enum": [
                                "refunded",
                                "already_refunded",
                                "refused",
                                "not_requested"
                              ]
                            },
                            "credits": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 0
                            },
                            "refundId": {
                              "type": [
                                "null",
                                "string"
                              ]
                            },
                            "reason": {
                              "type": [
                                "null",
                                "string"
                              ]
                            }
                          }
                        },
                        "orgId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "reportedBy": {
                          "type": "string",
                          "description": "The reporter’s Clerk user id."
                        }
                      }
                    },
                    "changed": {
                      "type": "boolean",
                      "description": "false when it already had that status."
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "reference",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^PR-[0-9]{6,}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "title": "SetProblemReportStatus",
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "status"
                ],
                "properties": {
                  "status": {
                    "type": "string",
                    "enum": [
                      "in_review"
                    ]
                  },
                  "note": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1000
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/staff/recipes/{recipeId}/versions": {
      "post": {
        "operationId": "createRecipeDraft",
        "summary": "Create a draft recipe version",
        "description": "Registers a new version of a recipe as a draft, from its full recipe entry. Its version must be higher (semver) than every version before it. A recipe’s first version also names its provider and, for a keep recipe, its collection. A draft runs nothing and is visible only here until it is published. Rewalto staff only: a signed-in session whose user is on the staff list; an API key is always refused (`forbidden`).",
        "tags": [
          "Staff: recipe publishing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipeVersionAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `catalogue_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "recipeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateRecipeDraftRequest"
              }
            }
          }
        }
      }
    },
    "/v1/staff/recipes/{recipeId}/versions/{version}": {
      "get": {
        "operationId": "getRecipeVersion",
        "summary": "Read a recipe version, drafts included",
        "description": "Its status, when its tests and smoke check last passed, its last smoke run (with the keys that went missing or appeared since the run before), and its entry. Rewalto staff only: a signed-in session whose user is on the staff list; an API key is always refused (`forbidden`).",
        "tags": [
          "Staff: recipe publishing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipeVersionAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "recipeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(0|[1-9][0-9]{0,8})\\.(0|[1-9][0-9]{0,8})\\.(0|[1-9][0-9]{0,8})$"
            }
          }
        ]
      }
    },
    "/v1/staff/recipes/{recipeId}/versions/{version}/publish": {
      "post": {
        "operationId": "publishRecipeVersion",
        "summary": "Publish a recipe version",
        "description": "The database decides: publishing needs passing tests, a passing smoke check, an offered provider (and keep collection) and a rate row; a degraded version needs a smoke pass since it degraded. Otherwise `catalogue_refused` with the reason. A tested version is normally published by its first passing smoke check, which the daily schedule queues. Publishing a published version changes nothing. Rewalto staff only: a signed-in session whose user is on the staff list; an API key is always refused (`forbidden`).",
        "tags": [
          "Staff: recipe publishing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipeVersionAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `catalogue_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "recipeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(0|[1-9][0-9]{0,8})\\.(0|[1-9][0-9]{0,8})\\.(0|[1-9][0-9]{0,8})$"
            }
          }
        ]
      }
    },
    "/v1/staff/recipes/{recipeId}/versions/{version}/retire": {
      "post": {
        "operationId": "retireRecipeVersion",
        "summary": "Retire a recipe version",
        "description": "Takes a version out of use for good, from any status; nothing is deleted and a retired version never comes back (publish a new version instead). The reason is recorded. Retiring a retired version changes nothing. Rewalto staff only: a signed-in session whose user is on the staff list; an API key is always refused (`forbidden`).",
        "tags": [
          "Staff: recipe publishing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipeVersionAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `catalogue_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "recipeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(0|[1-9][0-9]{0,8})\\.(0|[1-9][0-9]{0,8})\\.(0|[1-9][0-9]{0,8})$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RetireRecipeRequest"
              }
            }
          }
        }
      }
    },
    "/v1/staff/recipes/{recipeId}/versions/{version}/test": {
      "post": {
        "operationId": "testRecipeVersion",
        "summary": "Run a recipe version’s fixture and output-schema tests",
        "description": "Runs the trimmed page samples its entry names through the recipe engine, offline, and checks each sample’s pinned SHA-256, that rows come out with their key fields, and that every row fits the entry’s output schema. A pass moves a draft to `tested`; a failure moves a tested version back to `draft`. Only drafts and tested versions are tested. The report is returned either way. A host without the recipe engine answers `unavailable`. Rewalto staff only: a signed-in session whose user is on the staff list; an API key is always refused (`forbidden`).",
        "tags": [
          "Staff: recipe publishing"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RecipeTestAnswer"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `catalogue_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "recipeId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          },
          {
            "name": "version",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^(0|[1-9][0-9]{0,8})\\.(0|[1-9][0-9]{0,8})\\.(0|[1-9][0-9]{0,8})$"
            }
          }
        ]
      }
    },
    "/v1/staff/reports": {
      "get": {
        "operationId": "listStaffReports",
        "summary": "List every organisation's reports (staff)",
        "description": "Every organisation's report editions, newest first, each with the organisation it is attached to and its files; org narrows to one organisation. Needs the staff role report_operator (D-1761); API keys and plain members are refused (`forbidden`). Reading is itself recorded.",
        "tags": [
          "Staff: reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Staff reports page",
                  "description": "Every organisation's report editions, newest first.",
                  "additionalProperties": false,
                  "required": [
                    "data",
                    "page"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "title": "Report edition (staff)",
                        "description": "One report edition of any organisation, with the organisation that holds it and every file, each marked customer or internal.",
                        "additionalProperties": false,
                        "required": [
                          "id",
                          "kind",
                          "title",
                          "subject",
                          "window",
                          "forOrganisationId",
                          "requestedBy",
                          "formats",
                          "files",
                          "fileCount",
                          "totalBytes",
                          "manifestSha256",
                          "createdAt",
                          "expiresAt",
                          "state",
                          "supersededBy",
                          "supersededAt",
                          "organisation"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "title": "Id",
                            "description": "The edition id.",
                            "examples": [
                              "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                            ],
                            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                          },
                          "kind": {
                            "type": "string",
                            "title": "Kind",
                            "description": "The report type.",
                            "examples": [
                              "brand_shelf"
                            ]
                          },
                          "title": {
                            "type": "string",
                            "title": "Title",
                            "description": "The report title.",
                            "examples": [
                              "The Love Co. — Shelf Watch report"
                            ]
                          },
                          "subject": {
                            "type": "object",
                            "title": "Subject",
                            "description": "What the report is about.",
                            "additionalProperties": false,
                            "required": [
                              "kind",
                              "name",
                              "slug"
                            ],
                            "properties": {
                              "kind": {
                                "type": "string",
                                "enum": [
                                  "brand",
                                  "category",
                                  "retailer",
                                  "dataset"
                                ],
                                "title": "Kind",
                                "description": "brand, category, retailer or dataset.",
                                "examples": [
                                  "brand"
                                ]
                              },
                              "name": {
                                "type": "string",
                                "title": "Name",
                                "description": "The subject as the report names it.",
                                "examples": [
                                  "The Love Co."
                                ]
                              },
                              "slug": {
                                "type": "string",
                                "title": "Slug",
                                "description": "A short URL-safe name.",
                                "examples": [
                                  "the-love-co"
                                ]
                              }
                            }
                          },
                          "window": {
                            "type": "object",
                            "title": "Window",
                            "description": "The data window, IST dates, inclusive.",
                            "additionalProperties": false,
                            "required": [
                              "from",
                              "to"
                            ],
                            "properties": {
                              "from": {
                                "type": "string",
                                "title": "From",
                                "description": "First day.",
                                "examples": [
                                  "2026-08-26"
                                ],
                                "format": "date"
                              },
                              "to": {
                                "type": "string",
                                "title": "To",
                                "description": "Last day.",
                                "examples": [
                                  "2026-10-16"
                                ],
                                "format": "date"
                              }
                            }
                          },
                          "forOrganisationId": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Made for",
                            "description": "On the Rewalto organisation's copy of a report made for a customer: that customer's organisation id (C-017). Null otherwise.",
                            "examples": [
                              "3f2a8c1e-6b4d-4e8a-9c0f-1d7b5a2e9f10"
                            ],
                            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                          },
                          "requestedBy": {
                            "type": "string",
                            "title": "Requested by",
                            "description": "Who asked for it.",
                            "examples": [
                              "vm@rewalto.com"
                            ]
                          },
                          "formats": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "enum": [
                                "markdown",
                                "html",
                                "json",
                                "jsonl",
                                "csv",
                                "text",
                                "pdf"
                              ],
                              "title": "Format",
                              "description": "A file format present.",
                              "examples": [
                                "markdown"
                              ]
                            },
                            "title": "Formats",
                            "description": "The formats among its files.",
                            "examples": [
                              [
                                "csv",
                                "html",
                                "markdown"
                              ]
                            ]
                          },
                          "files": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "title": "Report file (staff)",
                              "description": "One file of a report edition.",
                              "additionalProperties": false,
                              "required": [
                                "name",
                                "format",
                                "role",
                                "contentType",
                                "bytes",
                                "sha256",
                                "audience",
                                "rank"
                              ],
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "title": "Name",
                                  "description": "The file, relative to the edition (e.g. summary.md, sections/listings.csv).",
                                  "examples": [
                                    "summary.md"
                                  ],
                                  "pattern": "^[A-Za-z0-9_][A-Za-z0-9._-]*(/[A-Za-z0-9_][A-Za-z0-9._-]*)*$"
                                },
                                "format": {
                                  "type": "string",
                                  "enum": [
                                    "markdown",
                                    "html",
                                    "json",
                                    "jsonl",
                                    "csv",
                                    "text",
                                    "pdf"
                                  ],
                                  "title": "Format",
                                  "description": "markdown, html, json, jsonl, csv, text (plain text: .txt, .log, .sql) or pdf.",
                                  "examples": [
                                    "markdown"
                                  ]
                                },
                                "role": {
                                  "type": "string",
                                  "enum": [
                                    "report",
                                    "data"
                                  ],
                                  "title": "Role",
                                  "description": "report: a readable report; data: a table or data file.",
                                  "examples": [
                                    "report"
                                  ]
                                },
                                "contentType": {
                                  "type": "string",
                                  "title": "Content type",
                                  "description": "The MIME type the link serves.",
                                  "examples": [
                                    "text/markdown; charset=utf-8"
                                  ]
                                },
                                "bytes": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "Bytes",
                                  "description": "File size.",
                                  "examples": [
                                    32674
                                  ]
                                },
                                "sha256": {
                                  "type": "string",
                                  "title": "SHA-256",
                                  "description": "Of the file; check the download against it.",
                                  "examples": [
                                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                                  ],
                                  "pattern": "^[0-9a-f]{64}$"
                                },
                                "audience": {
                                  "type": "string",
                                  "enum": [
                                    "customer",
                                    "internal"
                                  ],
                                  "title": "Audience",
                                  "description": "customer: customers may download it; internal: kept, never linked on the customer routes.",
                                  "examples": [
                                    "customer"
                                  ]
                                },
                                "rank": {
                                  "type": [
                                    "null",
                                    "integer"
                                  ],
                                  "minimum": 1,
                                  "title": "Rank",
                                  "description": "Display order (1 = the primary report); null when not ranked.",
                                  "examples": [
                                    1
                                  ]
                                }
                              }
                            },
                            "title": "Files",
                            "description": "Every file of the edition, customer and internal, in display order."
                          },
                          "fileCount": {
                            "type": "integer",
                            "minimum": 0,
                            "title": "Files",
                            "description": "How many files you may download (the length of files).",
                            "examples": [
                              84
                            ]
                          },
                          "totalBytes": {
                            "type": "integer",
                            "minimum": 0,
                            "title": "Bytes",
                            "description": "The files you may download, together.",
                            "examples": [
                              4500000
                            ]
                          },
                          "manifestSha256": {
                            "type": "string",
                            "title": "Manifest SHA-256",
                            "description": "SHA-256 of the sorted \"name sha256 bytes\" lines of every file: one fingerprint for the whole edition.",
                            "examples": [
                              "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
                            ],
                            "pattern": "^[0-9a-f]{64}$"
                          },
                          "createdAt": {
                            "type": "string",
                            "title": "Created at",
                            "description": "When the report was made.",
                            "examples": [
                              "2026-10-17T12:00:00Z"
                            ],
                            "format": "date-time"
                          },
                          "expiresAt": {
                            "type": "string",
                            "title": "Expires at",
                            "description": "Files are deleted after this (12 months, D-1764).",
                            "examples": [
                              "2027-10-17T12:00:00Z"
                            ],
                            "format": "date-time"
                          },
                          "state": {
                            "type": "string",
                            "enum": [
                              "available",
                              "superseded",
                              "expired"
                            ],
                            "title": "State",
                            "description": "available; superseded when a corrected edition replaced it (its customer files stay downloadable until expiresAt); expired after expiresAt.",
                            "examples": [
                              "available"
                            ]
                          },
                          "supersededBy": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Superseded by",
                            "description": "The corrected edition that replaced this one (GET /v1/reports/{id}); null while this is the current edition.",
                            "examples": [
                              "3f2a8c1e-6b4d-4e8a-9c0f-1d7b5a2e9f10"
                            ],
                            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                          },
                          "supersededAt": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Superseded at",
                            "description": "When the correction replaced this edition; null while this is the current edition.",
                            "examples": [
                              "2026-10-20T12:00:00Z"
                            ],
                            "format": "date-time"
                          },
                          "organisation": {
                            "type": "object",
                            "title": "Organisation",
                            "description": "The organisation the edition is attached to.",
                            "additionalProperties": false,
                            "required": [
                              "id",
                              "name"
                            ],
                            "properties": {
                              "id": {
                                "type": "string",
                                "title": "Id",
                                "description": "Its core id.",
                                "examples": [
                                  "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                                ],
                                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                              },
                              "name": {
                                "type": "string",
                                "title": "Name",
                                "description": "Its name.",
                                "examples": [
                                  "Rewalto"
                                ]
                              }
                            }
                          }
                        }
                      },
                      "title": "Reports",
                      "description": "Newest first."
                    },
                    "page": {
                      "type": "object",
                      "title": "Page",
                      "description": "Paging.",
                      "additionalProperties": false,
                      "required": [
                        "limit",
                        "nextCursor"
                      ],
                      "properties": {
                        "limit": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Limit",
                          "description": "The page size used.",
                          "examples": [
                            20
                          ]
                        },
                        "nextCursor": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Next cursor",
                          "description": "Pass as cursor for the next page; null at the end.",
                          "examples": [
                            "eyJ0Ijoi"
                          ],
                          "pattern": "^[A-Za-z0-9_-]{1,200}$"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "org",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Organisation",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "description": "Only this organisation (its core id)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Limit",
              "examples": [
                "20"
              ],
              "pattern": "^[1-9][0-9]{0,2}$"
            },
            "description": "How many, 1 to 100 (default 20)."
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "title": "Cursor",
              "examples": [
                "eyJ0IjoiMjAyNi0xMC0xNyJ9"
              ],
              "pattern": "^[A-Za-z0-9_-]{1,200}$"
            },
            "description": "page.nextCursor from the previous page."
          }
        ]
      }
    },
    "/v1/staff/reports/preview": {
      "post": {
        "operationId": "previewStaffReport",
        "summary": "Run a brand report (staff)",
        "description": "Builds a brand report on the server from core data (catalogue footprint; price, MRP and discount with plan 20's floors; every number cited) and returns it with its Markdown. Nothing is kept. Needs the staff role report_operator (D-1761) and a session in the Rewalto organisation (D-1763: the house pays); its reads are charged at the published rates like /v1/data (D-1760), under Rewalto's unlimited credits.",
        "tags": [
          "Staff: reports"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Report preview",
                  "description": "The report, built on the server from core data and returned; nothing is kept. Making a kept edition, attached to the Rewalto organisation (C-017), is plan 27 T4.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Preview",
                      "description": "The report and its readable rendering.",
                      "additionalProperties": false,
                      "required": [
                        "report",
                        "markdown"
                      ],
                      "properties": {
                        "report": {
                          "type": "object",
                          "additionalProperties": true,
                          "title": "Report",
                          "description": "report.json: findings per section with record citations (D-1313), absences, method, floors, limits, and the reads it made with the credits charged at published rates (D-1760)."
                        },
                        "markdown": {
                          "type": "string",
                          "title": "Markdown",
                          "description": "The report rendered from report.json only.",
                          "examples": [
                            "# The Love Co. — shelf report\n…"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "402": {
            "description": "Error. The `error.code` is one of:\n- `credits_exhausted`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Report request",
                "description": "A brand report request (plan 27 §5): subject, IST date window, optional retailers, sections and formats. Checked again in full by the server; every problem is listed at once.",
                "additionalProperties": false,
                "required": [
                  "subject",
                  "window"
                ],
                "properties": {
                  "subject": {
                    "type": "object",
                    "title": "Subject",
                    "description": "What the report is about. Only brand for now.",
                    "additionalProperties": false,
                    "required": [
                      "kind",
                      "name"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "enum": [
                          "brand"
                        ],
                        "title": "Kind",
                        "description": "brand."
                      },
                      "name": {
                        "type": "string",
                        "title": "Name",
                        "description": "The brand as its profile names it (case-insensitive).",
                        "examples": [
                          "The Love Co."
                        ]
                      },
                      "asWritten": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "minLength": 1,
                          "maxLength": 200
                        },
                        "maxItems": 10,
                        "title": "As written",
                        "description": "The exact spellings retailers use (the data filters are exact). Default: the name.",
                        "examples": [
                          [
                            "The Love Co.",
                            "The Love Co"
                          ]
                        ]
                      }
                    }
                  },
                  "window": {
                    "type": "object",
                    "title": "Window",
                    "description": "IST dates, inclusive; at most 366 days.",
                    "additionalProperties": false,
                    "required": [
                      "from",
                      "to"
                    ],
                    "properties": {
                      "from": {
                        "type": "string",
                        "title": "From",
                        "description": "First day.",
                        "examples": [
                          "2026-08-26"
                        ],
                        "format": "date"
                      },
                      "to": {
                        "type": "string",
                        "title": "To",
                        "description": "Last day.",
                        "examples": [
                          "2026-10-16"
                        ],
                        "format": "date"
                      },
                      "tz": {
                        "type": "string",
                        "enum": [
                          "Asia/Kolkata"
                        ],
                        "title": "Time zone",
                        "description": "Asia/Kolkata."
                      }
                    }
                  },
                  "filters": {
                    "type": "object",
                    "title": "Filters",
                    "description": "Narrow the subject.",
                    "additionalProperties": false,
                    "required": [],
                    "properties": {
                      "retailers": {
                        "type": "array",
                        "items": {
                          "type": "string",
                          "pattern": "^[a-z0-9_]{1,40}$"
                        },
                        "maxItems": 40,
                        "title": "Retailers",
                        "description": "Only these retailers.",
                        "examples": [
                          [
                            "blinkit",
                            "zepto"
                          ]
                        ]
                      }
                    }
                  },
                  "sections": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "pattern": "^[a-z][a-z_]{1,40}$"
                    },
                    "maxItems": 20,
                    "title": "Sections",
                    "description": "Default: every section (catalogue_footprint, price_mrp_discount).",
                    "examples": [
                      [
                        "catalogue_footprint",
                        "price_mrp_discount"
                      ]
                    ]
                  },
                  "format": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "json",
                        "markdown",
                        "csv"
                      ]
                    },
                    "title": "Formats",
                    "description": "json is always included (D-1762).",
                    "examples": [
                      [
                        "json",
                        "markdown"
                      ]
                    ]
                  },
                  "title": {
                    "type": "string",
                    "title": "Title",
                    "description": "A title; default \"<brand> — shelf report\".",
                    "examples": [
                      "The Love Co. — Shelf Watch report"
                    ],
                    "maxLength": 300
                  },
                  "maxRecords": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100000,
                    "title": "Record cap",
                    "description": "The most records read, listings and readings together (default 20000).",
                    "examples": [
                      20000
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/staff/snapshots": {
      "post": {
        "operationId": "defineSnapshot",
        "summary": "Define a dataset snapshot for sale",
        "description": "Adds a ready snapshot to the catalogue: family, category, kind, scope, name, summary and coverage floor. Its unit follows its kind and it is sold under the newest licence. It is not on sale until an edition is counted at or above its floor. A snapshot never changes; a different scope is a new id. Rewalto staff only: a signed-in session whose user holds the catalogue editing role (`recipe_publisher`); an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: snapshots"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "201": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Snapshot answer",
                  "description": "One snapshot in full.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Snapshot detail",
                      "description": "A snapshot with its free sample and the licence in full.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "family",
                        "categoryId",
                        "kind",
                        "scope",
                        "name",
                        "summary",
                        "format",
                        "minRecords",
                        "downloadMonths",
                        "licence",
                        "edition",
                        "pricing",
                        "saleState",
                        "licenceBody",
                        "sample"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "The snapshot id.",
                          "examples": [
                            "listings_blinkit_in"
                          ],
                          "pattern": "^[a-z][a-z0-9_]{1,63}$"
                        },
                        "family": {
                          "type": "string",
                          "enum": [
                            "commerce",
                            "investors",
                            "startups",
                            "companies",
                            "public_records"
                          ],
                          "title": "Family",
                          "description": "The Data library family.",
                          "examples": [
                            "commerce"
                          ]
                        },
                        "categoryId": {
                          "type": "string",
                          "title": "Category",
                          "description": "The catalogue category.",
                          "examples": [
                            "quick_commerce"
                          ]
                        },
                        "kind": {
                          "type": "string",
                          "enum": [
                            "listings_app",
                            "listings_app_city",
                            "dark_store_map",
                            "category_history",
                            "investors",
                            "startups",
                            "companies"
                          ],
                          "title": "Kind",
                          "description": "What kind of snapshot it is (D-1558).",
                          "examples": [
                            "listings_app"
                          ]
                        },
                        "scope": {
                          "type": "object",
                          "title": "Scope",
                          "description": "What the snapshot holds. listings_app: one retailer, all India. listings_app_city: one retailer in one city. dark_store_map: one platform. category_history: one category over the last `days` days. investors, startups, companies: the whole list, no scope.",
                          "additionalProperties": false,
                          "required": [],
                          "properties": {
                            "retailer": {
                              "type": "string",
                              "title": "Retailer",
                              "description": "The retailer slug.",
                              "examples": [
                                "blinkit"
                              ]
                            },
                            "city": {
                              "type": "string",
                              "title": "City",
                              "description": "The city, as the dark-store map names it.",
                              "examples": [
                                "Bengaluru"
                              ]
                            },
                            "platform": {
                              "type": "string",
                              "title": "Platform",
                              "description": "The quick-commerce platform.",
                              "examples": [
                                "zepto"
                              ]
                            },
                            "category": {
                              "type": "string",
                              "title": "Category",
                              "description": "The category.",
                              "examples": [
                                "dairy"
                              ]
                            },
                            "days": {
                              "type": "integer",
                              "minimum": 1,
                              "title": "Days",
                              "description": "How many days of history.",
                              "examples": [
                                90
                              ]
                            }
                          }
                        },
                        "name": {
                          "type": "string",
                          "title": "Name",
                          "description": "The snapshot name.",
                          "examples": [
                            "Blinkit listings, all India"
                          ]
                        },
                        "summary": {
                          "type": "string",
                          "title": "Summary",
                          "description": "What you get.",
                          "examples": [
                            "Every Blinkit listing Rewalto holds, as of one date."
                          ]
                        },
                        "format": {
                          "type": "string",
                          "const": "jsonl",
                          "title": "Format",
                          "description": "JSON Lines (D-1307)."
                        },
                        "minRecords": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Coverage floor",
                          "description": "An edition with fewer records is not for sale.",
                          "examples": [
                            1000
                          ]
                        },
                        "downloadMonths": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Download months",
                          "description": "How long a purchase can be downloaded (D-1555).",
                          "examples": [
                            12
                          ]
                        },
                        "licence": {
                          "type": "object",
                          "title": "Licence",
                          "description": "The licence a purchase is sold under (D-1556).",
                          "additionalProperties": false,
                          "required": [
                            "version",
                            "title",
                            "summary"
                          ],
                          "properties": {
                            "version": {
                              "type": "integer",
                              "minimum": 1,
                              "title": "Version",
                              "description": "The licence version, stored with each purchase.",
                              "examples": [
                                1
                              ]
                            },
                            "title": {
                              "type": "string",
                              "title": "Title",
                              "description": "The licence title.",
                              "examples": [
                                "Rewalto dataset licence, version 1"
                              ]
                            },
                            "summary": {
                              "type": "string",
                              "title": "Summary",
                              "description": "One line.",
                              "examples": [
                                "Use it inside your own organisation, including in your own products and analysis. Do not resell or redistribute the raw records. Cite Rewalto for figures you publish."
                              ]
                            }
                          }
                        },
                        "edition": {
                          "type": [
                            "null",
                            "object"
                          ],
                          "title": "Edition",
                          "description": "The snapshot as of one date.",
                          "additionalProperties": false,
                          "required": [
                            "asOf",
                            "recordCount",
                            "fields",
                            "coverage",
                            "computedAt"
                          ],
                          "properties": {
                            "asOf": {
                              "type": "string",
                              "title": "As of",
                              "description": "The date the edition describes (IST).",
                              "examples": [
                                "2026-10-16"
                              ],
                              "format": "date"
                            },
                            "recordCount": {
                              "type": "integer",
                              "minimum": 0,
                              "title": "Records",
                              "description": "How many records the edition holds.",
                              "examples": [
                                648142
                              ]
                            },
                            "fields": {
                              "type": "array",
                              "title": "Fields",
                              "description": "The fields of each record.",
                              "items": {
                                "type": "object",
                                "title": "Field",
                                "description": "One field every record carries.",
                                "additionalProperties": false,
                                "required": [
                                  "name",
                                  "type",
                                  "description"
                                ],
                                "properties": {
                                  "name": {
                                    "type": "string",
                                    "title": "Name",
                                    "description": "The field name in each JSON Lines record.",
                                    "examples": [
                                      "priceMinor"
                                    ]
                                  },
                                  "type": {
                                    "type": "string",
                                    "title": "Type",
                                    "description": "Its JSON type.",
                                    "examples": [
                                      "integer"
                                    ]
                                  },
                                  "description": {
                                    "type": "string",
                                    "title": "Description",
                                    "description": "What it holds.",
                                    "examples": [
                                      "Selling price in paise."
                                    ]
                                  }
                                }
                              }
                            },
                            "coverage": {
                              "type": "object",
                              "title": "Coverage",
                              "description": "What the edition covers and how that was measured.",
                              "additionalProperties": false,
                              "required": [
                                "label",
                                "basis"
                              ],
                              "properties": {
                                "label": {
                                  "type": "string",
                                  "title": "Coverage",
                                  "description": "One line.",
                                  "examples": [
                                    "All listings seen on Blinkit, all India"
                                  ]
                                },
                                "basis": {
                                  "type": "string",
                                  "title": "Basis",
                                  "description": "How the figure was measured.",
                                  "examples": [
                                    "Distinct listings seen in the last 30 days"
                                  ]
                                }
                              }
                            },
                            "computedAt": {
                              "type": "string",
                              "title": "Computed at",
                              "description": "When the edition was counted.",
                              "examples": [
                                "2026-10-16T02:00:00Z"
                              ],
                              "format": "date-time"
                            }
                          }
                        },
                        "pricing": {
                          "type": "object",
                          "title": "Pricing",
                          "description": "The price in credits, from the newest rate card that carries the unit (D-1553). Credits are bought as packs; there is no rupee price per dataset.",
                          "additionalProperties": false,
                          "required": [
                            "unit",
                            "credits",
                            "perUnits",
                            "rateVersion",
                            "totalCredits"
                          ],
                          "properties": {
                            "unit": {
                              "type": "string",
                              "title": "Unit",
                              "description": "The rate-card unit.",
                              "examples": [
                                "listings"
                              ]
                            },
                            "credits": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 0,
                              "title": "Credits",
                              "description": "Credits per `perUnits` units; null when no rate card carries the unit.",
                              "examples": [
                                1
                              ]
                            },
                            "perUnits": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 0,
                              "title": "Per units",
                              "description": "How many units the credits buy; null when not priced.",
                              "examples": [
                                10
                              ]
                            },
                            "rateVersion": {
                              "type": [
                                "null",
                                "string"
                              ],
                              "title": "Rate version",
                              "description": "The rate card the price comes from, for example c3; null when not priced.",
                              "examples": [
                                "c3"
                              ]
                            },
                            "totalCredits": {
                              "type": [
                                "null",
                                "integer"
                              ],
                              "minimum": 0,
                              "title": "Total credits",
                              "description": "The newest edition in full: ceil(records x credits / perUnits). Null when not computed or not priced.",
                              "examples": [
                                64815
                              ]
                            }
                          }
                        },
                        "saleState": {
                          "type": "string",
                          "enum": [
                            "on_sale",
                            "below_coverage_floor",
                            "not_computed",
                            "not_priced"
                          ],
                          "title": "Sale state",
                          "description": "on_sale: can be bought. below_coverage_floor: the newest edition holds fewer than minRecords records. not_computed: no edition counted yet. not_priced: no rate card carries the unit.",
                          "examples": [
                            "on_sale"
                          ]
                        },
                        "licenceBody": {
                          "type": "string",
                          "title": "Licence text",
                          "description": "The licence in full, shown before buying.",
                          "examples": [
                            "This licence covers a dataset snapshot bought from Rewalto."
                          ]
                        },
                        "sample": {
                          "type": "array",
                          "title": "Sample",
                          "description": "Up to 100 records of the newest edition, free. Empty when no edition is counted.",
                          "maxItems": 100,
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `catalogue_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Define a snapshot",
                "description": "A new snapshot: a fixed scope of kept data for sale. Its unit follows its kind (listings for listings, dark_store for the dark-store map, history_points for category history, backer_records for investors, company_records for startups and companies) and it is sold under the newest licence. A snapshot never changes: a different scope is a new id.",
                "additionalProperties": false,
                "required": [
                  "id",
                  "family",
                  "categoryId",
                  "kind",
                  "scope",
                  "name",
                  "summary",
                  "minRecords"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "title": "Id",
                    "description": "The new snapshot id.",
                    "examples": [
                      "listings_blinkit_in"
                    ],
                    "pattern": "^[a-z][a-z0-9_]{1,63}$"
                  },
                  "family": {
                    "type": "string",
                    "enum": [
                      "commerce",
                      "investors",
                      "startups",
                      "companies",
                      "public_records"
                    ],
                    "title": "Family",
                    "description": "The Data library family.",
                    "examples": [
                      "commerce"
                    ]
                  },
                  "categoryId": {
                    "type": "string",
                    "title": "Category",
                    "description": "An existing catalogue category.",
                    "examples": [
                      "quick_commerce"
                    ],
                    "pattern": "^[a-z][a-z0-9_]{1,63}$"
                  },
                  "kind": {
                    "type": "string",
                    "enum": [
                      "listings_app",
                      "listings_app_city",
                      "dark_store_map",
                      "category_history",
                      "investors",
                      "startups",
                      "companies"
                    ],
                    "title": "Kind",
                    "description": "What it holds (D-1558).",
                    "examples": [
                      "listings_app"
                    ]
                  },
                  "scope": {
                    "type": "object",
                    "title": "Scope",
                    "description": "What the snapshot holds. listings_app: one retailer, all India. listings_app_city: one retailer in one city. dark_store_map: one platform. category_history: one category over the last `days` days. investors, startups, companies: the whole list, no scope.",
                    "additionalProperties": false,
                    "required": [],
                    "properties": {
                      "retailer": {
                        "type": "string",
                        "title": "Retailer",
                        "description": "The retailer slug.",
                        "examples": [
                          "blinkit"
                        ]
                      },
                      "city": {
                        "type": "string",
                        "title": "City",
                        "description": "The city, as the dark-store map names it.",
                        "examples": [
                          "Bengaluru"
                        ]
                      },
                      "platform": {
                        "type": "string",
                        "title": "Platform",
                        "description": "The quick-commerce platform.",
                        "examples": [
                          "zepto"
                        ]
                      },
                      "category": {
                        "type": "string",
                        "title": "Category",
                        "description": "The category.",
                        "examples": [
                          "dairy"
                        ]
                      },
                      "days": {
                        "type": "integer",
                        "minimum": 1,
                        "title": "Days",
                        "description": "How many days of history.",
                        "examples": [
                          90
                        ]
                      }
                    }
                  },
                  "name": {
                    "type": "string",
                    "title": "Name",
                    "description": "The name buyers see.",
                    "examples": [
                      "Blinkit listings, all India"
                    ],
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "summary": {
                    "type": "string",
                    "title": "Summary",
                    "description": "What buyers get.",
                    "examples": [
                      "Every Blinkit listing Rewalto holds."
                    ],
                    "minLength": 1,
                    "maxLength": 2000
                  },
                  "minRecords": {
                    "type": "integer",
                    "minimum": 1,
                    "title": "Coverage floor",
                    "description": "An edition with fewer records is not for sale.",
                    "examples": [
                      1000
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/staff/snapshots/{id}/editions": {
      "post": {
        "operationId": "countSnapshotEdition",
        "summary": "Queue the count of a snapshot edition",
        "description": "Queues the count of the snapshot as of an IST date (default yesterday, the newest complete day). The worker counts it from the kept Library, without the request time limit, in one consistent read, and records the edition: record count, fields, a free sample of 100 records, coverage, and the exact records counted, so a purchase delivers the same records. Each date is counted once; the snapshot shows the edition when it is recorded. Rewalto staff only: a signed-in session whose user holds the catalogue editing role (`recipe_publisher`); an API key is always refused (`forbidden`). Every call is audited.",
        "tags": [
          "Staff: snapshots"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "202": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "title": "Count queued",
                  "description": "The count is queued: the worker counts the edition (no request time limit) and records it; then GET /v1/snapshots/{id} shows it.",
                  "additionalProperties": false,
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "object",
                      "title": "Queued count",
                      "description": "The count job.",
                      "additionalProperties": false,
                      "required": [
                        "jobId",
                        "snapshotId",
                        "asOf",
                        "state"
                      ],
                      "properties": {
                        "jobId": {
                          "type": "string",
                          "title": "Job",
                          "description": "The queue job that counts it.",
                          "examples": [
                            "1042"
                          ]
                        },
                        "snapshotId": {
                          "type": "string",
                          "title": "Snapshot",
                          "description": "The snapshot.",
                          "examples": [
                            "listings_blinkit_in"
                          ],
                          "pattern": "^[a-z][a-z0-9_]{1,63}$"
                        },
                        "asOf": {
                          "type": "string",
                          "title": "As of",
                          "description": "The IST date counted.",
                          "examples": [
                            "2026-10-16"
                          ],
                          "format": "date"
                        },
                        "state": {
                          "type": "string",
                          "title": "State",
                          "description": "The job state.",
                          "examples": [
                            "queued"
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "409": {
            "description": "Error. The `error.code` is one of:\n- `catalogue_refused`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "title": "Id",
              "description": "The snapshot id.",
              "examples": [
                "listings_blinkit_in"
              ],
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "title": "Count an edition",
                "description": "Count the snapshot from the kept Library as of an IST date and record the edition (record count, fields, a free sample of 100, coverage). Each date is counted once.",
                "additionalProperties": false,
                "required": [],
                "properties": {
                  "asOf": {
                    "type": "string",
                    "title": "As of",
                    "description": "The IST date; default yesterday (IST), the newest complete day.",
                    "examples": [
                      "2026-10-16"
                    ],
                    "format": "date"
                  }
                }
              }
            }
          }
        }
      }
    },
    "/v1/staff/time-to-first-data": {
      "get": {
        "operationId": "getTimeToFirstData",
        "summary": "Time to first data for new sign-ups (staff)",
        "description": "Per IST sign-up week (and for the whole window, `signupWeek` null), for organisations and for the users in them: how many signed up, how many reached first search, first data shown and first purchase, and the median and 75th percentile seconds from sign-up. Sign-up is the first time Core saw the account; a purchase is a credit spend or a paid order (organisation level; a user is credited with a paid order they placed). Only accounts Core saw from their start count. Counts and times only; no account is named. Rewalto staff only: a signed-in session whose user holds the staff role `adoption_reader` (Varun, as super-admin, holds it); an API key is always refused (`forbidden`). Every call is audited. Free.",
        "tags": [
          "Staff: adoption"
        ],
        "security": [
          {
            "sessionJwt": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeToFirstData"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "weeks",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^([1-9]|[1-9][0-9]|10[0-4])$",
              "examples": [
                "12"
              ]
            },
            "description": "Sign-up weeks to cover, counting this IST week (1-104, default 12)."
          }
        ]
      }
    },
    "/v1/version": {
      "get": {
        "operationId": "getVersion",
        "summary": "The API release that answered",
        "description": "No credentials needed. Use it to confirm which release a base URL runs.",
        "tags": [
          "Service"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Version"
                },
                "example": {
                  "service": "rewalto-api",
                  "version": "api-dev-v20261015.3",
                  "apiVersion": "v1"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/walt/ask": {
      "post": {
        "operationId": "askWalt",
        "summary": "Ask Walt a question about Rewalto",
        "description": "The website’s assistant. One question about Rewalto (at most 600 characters) is answered only from Rewalto’s own published pages, with the pages it drew from, or refused (off-topic, about a customer’s private data, or not published). No credentials and no credits; called from the browser on rewalto.com with a Cloudflare Turnstile token, checked here. Limits: one question every 10 seconds and 30 an hour per IP (`rate_limited`, with `Retry-After`), and a daily ceiling on Walt’s own model spend (`unavailable` once reached, until the next IST day). A failed Turnstile check is `forbidden`. A browser request is accepted only from Rewalto’s own site (CORS).",
        "tags": [
          "Walt"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "cache-control": {
                "description": "Always `no-store`: the answer must not be cached.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AskWaltResponse"
                },
                "example": {
                  "status": "answered",
                  "answer": "Every account gets 1,000 free credits a month.",
                  "citations": [
                    {
                      "url": "https://rewalto.com/pricing",
                      "title": "Pricing"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `forbidden`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AskWaltRequest"
              }
            }
          }
        }
      }
    },
    "/v1/walt/chat": {
      "post": {
        "operationId": "chatWithWalt",
        "summary": "Ask Walt about your organisation’s data",
        "description": "Dashboard Walt: the signed-in assistant. Send the conversation (and, optionally, the dashboard page); Walt answers from your organisation’s own data by calling the same tools the Rewalto MCP connector lists, each one an API call made with your own credential, so it sees, refuses and charges exactly what your own call would. Every tool call is listed in `toolCalls`. A tool that spends credits or creates a record never runs on Walt’s word: the answer is `needs_confirmation` with a `pendingAction` (what it does and what it can cost), and it runs only when you send its id back as `confirm` within 10 minutes. Walt’s own model use is free to you. Limits: 10 turns a minute and 120 an hour per user (`rate_limited`), at most 8 model steps a turn (`stopped`), and a daily ceiling on Walt’s model spend (`unavailable` once reached). While Walt is switched off the route answers 503 `unavailable` (see `GET /v1/walt/status`). `style` is `concise` (default: a few lines pointing at the data shown) or `full`. Each `ok` tool call carries its answer for display (`result`, cut to 200 rows and 256 KiB), a `view` hint and a `resultId` for the whole answer; `sources` number the data the answer cites as `[1]`, `followUps` suggests up to 3 next questions, and `usage` reports Walt’s own tokens and cost. With `Accept: text/event-stream` the turn is streamed as Server-Sent Events, one JSON `data:` line each: `{\"type\":\"thinking\",\"step\":n}` before each model call, `{\"type\":\"step\",\"index\",\"tool\",\"status\",\"creditsCharged\"}` as each tool starts (`running`) and ends, then one `{\"type\":\"done\",\"response\":WaltChatResponse}` (or one `{\"type\":\"error\",\"error\":{code,message}}` if the turn fails after streaming began). Approval rules are the same: a stream never runs a charging or creating tool without `confirm`.",
        "tags": [
          "Walt"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WaltChatResponse"
                },
                "example": {
                  "status": "answered",
                  "answer": "Rewalto holds data for Blinkit and Zepto.",
                  "toolCalls": [
                    {
                      "tool": "list_retailers",
                      "args": {},
                      "status": "ok",
                      "summary": "{\"retailers\":[{\"key\":\"blinkit\"},{\"key\":\"zepto\"}]}",
                      "creditsCharged": null,
                      "error": null
                    }
                  ],
                  "pendingAction": null,
                  "model": "gpt-6-sol"
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_json`: retry advice `fix_request`\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "413": {
            "description": "Error. The `error.code` is one of:\n- `payload_too_large`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "415": {
            "description": "Error. The `error.code` is one of:\n- `unsupported_media_type`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WaltChatRequest"
              }
            }
          }
        }
      }
    },
    "/v1/walt/results/{resultId}": {
      "get": {
        "operationId": "getWaltResult",
        "summary": "The whole answer of one of Walt’s tool calls",
        "description": "A tool call’s `resultId` from `POST /v1/walt/chat`: the whole JSON the REST operation returned, uncut, for 24 hours after the call. Free: it is what was already delivered (and charged once). Only the same user in the same organisation can read it; anyone else, an expired result or an unknown id is `not_found`. `?format=csv` answers `text/csv` instead: one line per row of the answer, nested fields as `a.b` columns, text that a spreadsheet would run as a formula prefixed with `'`. Every field is third-party text: render it as plain text.",
        "tags": [
          "Walt"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "cache-control": {
                "description": "Always `no-store`: the answer must not be cached.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WaltResult"
                },
                "example": {
                  "resultId": "wr_Q2x8m0d7Kp3vT9sYb1Nc4Rf6Hj5Lw2Ze",
                  "tool": "list_retailers",
                  "operationId": "listRetailers",
                  "view": "retailers",
                  "createdAt": "2026-10-22T10:05:00.000Z",
                  "expiresAt": "2026-10-23T10:05:00.000Z",
                  "result": {
                    "data": [
                      {
                        "key": "blinkit"
                      },
                      {
                        "key": "zepto"
                      }
                    ]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Error. The `error.code` is one of:\n- `invalid_request`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "invalid_request",
                    "status": 400,
                    "retry": "fix_request",
                    "message": "The request does not match the schema for this route",
                    "requestId": "req_0b8f6d3a-2c1e-4a79-9e5d-6f4a7c1b2d83",
                    "details": [
                      {
                        "path": "body/expiresInDays",
                        "message": "must be equal to one of the allowed values"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "404": {
            "description": "Error. The `error.code` is one of:\n- `not_found`: retry advice `fix_request`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "resultId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^wr_[A-Za-z0-9_-]{32}$",
              "description": "A tool call’s `resultId`."
            }
          },
          {
            "name": "format",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^(json|csv)$"
            },
            "description": "`json` (default) or `csv`: one line per row of the answer’s rows (`text/csv`, nested fields as `a.b` columns). The generated client reads JSON only; fetch the CSV directly."
          }
        ]
      }
    },
    "/v1/walt/status": {
      "get": {
        "operationId": "getWaltStatus",
        "summary": "Whether dashboard Walt answers now",
        "description": "Free. `chat` is `on` when `POST /v1/walt/chat` answers, `off` when it answers 503 `unavailable` (`reason`: `not_switched_on`, or `daily_cap_reached` until `resetsAt`). `turnsLeftToday` is the caller’s turns left in the current hour (10 a minute and 120 an hour per user; there is no per-day turn count), with `resetsAt` when that allowance renews. Asking does not use a turn.",
        "tags": [
          "Walt"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "cache-control": {
                "description": "Always `no-store`: the answer must not be cached.",
                "schema": {
                  "type": "string"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WaltStatus"
                },
                "example": {
                  "chat": "on",
                  "reason": null,
                  "turnsLeftToday": 118,
                  "resetsAt": "2026-10-22T11:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    },
    "/v1/whoami": {
      "get": {
        "operationId": "getWhoami",
        "summary": "Who is calling, their organisation, role and plan",
        "description": "Accepts a Clerk session token or an API key. For a signed-in user without an organisation it creates one personal organisation on the first call (idempotent). A session token that carries `org_name` keeps the stored organisation name in step with Clerk. Costs nothing; the credits balance is GET /v1/credits/balance.",
        "tags": [
          "Identity"
        ],
        "security": [
          {
            "sessionJwt": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Success",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Whoami"
                },
                "example": {
                  "user": {
                    "id": "user_2abcDEFghiJKLmno",
                    "email": "asha@example.com",
                    "name": "Asha Rao"
                  },
                  "organisation": {
                    "id": "3f2a8c1e-6b4d-4e8a-9c0f-1d7b5a2e9f10",
                    "name": "Acme Retail"
                  },
                  "role": "admin",
                  "platformRole": null,
                  "plan": null,
                  "credential": {
                    "kind": "session",
                    "keyId": null,
                    "scopes": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error. The `error.code` is one of:\n- `key_expired`: retry advice `refresh_credentials`\n- `key_revoked`: retry advice `refresh_credentials`\n- `session_expired`: retry advice `refresh_credentials`\n- `unauthenticated`: retry advice `refresh_credentials`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "example": {
                  "error": {
                    "code": "session_expired",
                    "status": 401,
                    "retry": "refresh_credentials",
                    "message": "The session token has expired; sign in again",
                    "requestId": "req_7c1e2a90-4b3d-4f6e-8a15-0d9c2b7e3f41"
                  }
                }
              }
            }
          },
          "403": {
            "description": "Error. The `error.code` is one of:\n- `org_missing`: retry advice `never`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "429": {
            "description": "Error. The `error.code` is one of:\n- `rate_limited`: retry advice `after_reset`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              },
              "RateLimit-Limit": {
                "$ref": "#/components/headers/RateLimitLimitHeader"
              },
              "RateLimit-Remaining": {
                "$ref": "#/components/headers/RateLimitRemainingHeader"
              },
              "RateLimit-Reset": {
                "$ref": "#/components/headers/RateLimitResetHeader"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfterHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "500": {
            "description": "Error. The `error.code` is one of:\n- `internal`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          },
          "503": {
            "description": "Error. The `error.code` is one of:\n- `unavailable`: retry advice `bounded`",
            "headers": {
              "x-request-id": {
                "$ref": "#/components/headers/RequestIdHeader"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "ErrorEnvelope": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "code",
              "status",
              "retry",
              "message",
              "requestId"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "invalid_request",
                  "invalid_json",
                  "unauthenticated",
                  "session_expired",
                  "key_expired",
                  "key_revoked",
                  "credits_exhausted",
                  "over_quote",
                  "plan_required",
                  "price_changed",
                  "forbidden",
                  "org_missing",
                  "scope_missing",
                  "not_entitled",
                  "private_data",
                  "access_control",
                  "not_found",
                  "quote_expired",
                  "quote_already_approved",
                  "refund_refused",
                  "catalogue_refused",
                  "not_for_sale",
                  "export_not_ready",
                  "download_expired",
                  "idempotency_conflict",
                  "stale_version",
                  "package_not_ready",
                  "upload_not_ready",
                  "cost_changed",
                  "billing_profile_missing",
                  "export_not_available",
                  "unknown_capability",
                  "schema_retired",
                  "payload_too_large",
                  "unsupported_media_type",
                  "rate_limited",
                  "internal",
                  "evidence_unavailable",
                  "payment_provider_unavailable",
                  "checkout_unavailable",
                  "invoicing_unavailable",
                  "unavailable"
                ]
              },
              "status": {
                "type": "integer"
              },
              "retry": {
                "type": "string",
                "enum": [
                  "fix_request",
                  "refresh_credentials",
                  "never",
                  "after_reset",
                  "bounded"
                ]
              },
              "message": {
                "type": "string"
              },
              "requestId": {
                "type": "string"
              },
              "quote": {
                "$ref": "#/components/schemas/Quote"
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "path",
                    "message"
                  ],
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "ApiKey": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "prefix",
          "scopes",
          "status",
          "createdAt",
          "expiresAt",
          "revokedAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "name": {
            "type": "string"
          },
          "prefix": {
            "type": "string"
          },
          "scopes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "data:read",
                "tools:run",
                "usage:read"
              ]
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "expired",
              "revoked"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "revokedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "lastUsedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "When the key was last used to call the API; null if never. Updated at most once a minute per key, so it can lag a busy key by up to a minute. Optional: absent from servers before it was added; treat a missing field as unknown, not as never used."
          }
        }
      },
      "CreateKeyRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "scopes",
          "expiresInDays"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "scopes": {
            "type": "array",
            "minItems": 1,
            "maxItems": 3,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "enum": [
                "data:read",
                "tools:run",
                "usage:read"
              ]
            }
          },
          "expiresInDays": {
            "type": "integer",
            "enum": [
              7,
              30,
              90
            ]
          }
        }
      },
      "CreateKeyResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "key",
          "secret"
        ],
        "properties": {
          "key": {
            "$ref": "#/components/schemas/ApiKey"
          },
          "secret": {
            "type": "string"
          }
        }
      },
      "ListKeysResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "keys"
        ],
        "properties": {
          "keys": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ApiKey"
            }
          }
        }
      },
      "ProvisionFirstKeyResponse": {
        "type": "object",
        "title": "First key",
        "description": "The organisation's first API key. `secret` is the whole secret only in the answer of the one call that made the key (`created: true`); every other call returns the same key with `secret: null`.",
        "additionalProperties": false,
        "required": [
          "key",
          "secret",
          "created"
        ],
        "properties": {
          "key": {
            "$ref": "#/components/schemas/ApiKey"
          },
          "secret": {
            "type": [
              "null",
              "string"
            ],
            "description": "Shown once, when `created` is true; null otherwise. Only its SHA-256 is stored."
          },
          "created": {
            "type": "boolean",
            "description": "True only for the call that made the key now. False when the organisation already had a key."
          }
        }
      },
      "RevokeKeyResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "key"
        ],
        "properties": {
          "key": {
            "$ref": "#/components/schemas/ApiKey"
          }
        }
      },
      "Version": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "service",
          "version",
          "apiVersion"
        ],
        "properties": {
          "service": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "apiVersion": {
            "type": "string"
          }
        }
      },
      "Whoami": {
        "type": "object",
        "title": "Who am I",
        "additionalProperties": false,
        "required": [
          "user",
          "organisation",
          "role",
          "plan",
          "credential"
        ],
        "properties": {
          "user": {
            "type": "object",
            "title": "User",
            "description": "The signed-in user. Every field is null when the caller is an API key.",
            "additionalProperties": false,
            "required": [
              "id",
              "email",
              "name"
            ],
            "properties": {
              "id": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "The Clerk user id (`sub`)."
              },
              "email": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "The session token's `email` claim; null when the token does not carry it."
              },
              "name": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "The session token's `name` claim; null when the token does not carry it."
              }
            }
          },
          "organisation": {
            "type": "object",
            "title": "Organisation",
            "description": "The organisation this request acts as, as stored by Rewalto.",
            "additionalProperties": false,
            "required": [
              "id",
              "name"
            ],
            "properties": {
              "id": {
                "type": "string",
                "format": "uuid"
              },
              "name": {
                "type": "string",
                "description": "A Clerk organisation's name follows the session token's `org_name` claim; until a token carries it, the placeholder \"Organisation\". A personal organisation is \"Personal organisation\"."
              }
            }
          },
          "role": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "admin",
              "member",
              null
            ],
            "description": "The signed-in user's role in the organisation; null for an API key."
          },
          "platformRole": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "super_admin",
              null
            ],
            "description": "Rewalto's own platform role for the signed-in user, separate from the organisation `role`: `super_admin` for a Rewalto founder (every Rewalto staff power, the /v1/staff routes; bound to the Clerk user id), null for everyone else. Always null for an API key. An organisation admin is not a super-admin. Sent from contract 0.28.0; absent from older servers."
          },
          "staffRoles": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "The signed-in user's current Rewalto staff roles (for example `report_operator`, which the /v1/reports data, upload and schedule routes need), from the database roster (core.staff_roles_of), sorted; a super-admin holds every staff role. An empty list for everyone else, and always empty for an API key or an MCP (OAuth) sign-in, which can never call staff routes. A capability to show or hide staff features; the routes still check the role on every call. Sent from contract 0.37.0; absent from older servers."
          },
          "plan": {
            "type": [
              "null",
              "string"
            ],
            "description": "The plan name or tier; null while the organisation has only free credits. There are no plans yet, so it is always null. The credits balance is GET /v1/credits/balance."
          },
          "credential": {
            "type": "object",
            "title": "Credential",
            "description": "What authenticated this request.",
            "additionalProperties": false,
            "required": [
              "kind",
              "keyId",
              "scopes"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "api_key",
                  "session",
                  "oauth"
                ],
                "description": "`oauth` (contract 0.29.0): a user acting through an MCP client they signed in to with Rewalto (Clerk OAuth). It acts as that user's chosen organisation with the scopes they granted, like an API key; it cannot manage keys or call staff routes."
              },
              "keyId": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "The API key id; null for a session or OAuth."
              },
              "scopes": {
                "type": [
                  "null",
                  "array"
                ],
                "items": {
                  "type": "string",
                  "enum": [
                    "data:read",
                    "tools:run",
                    "usage:read"
                  ]
                },
                "description": "The API key's scopes, or the scopes the OAuth sign-in granted; null for a session."
              },
              "clientId": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "For `oauth`: the OAuth client the user authorised (for example an MCP client). Absent or null otherwise."
              }
            }
          }
        }
      },
      "CreditBalance": {
        "title": "CreditBalance",
        "description": "The caller's organisation's credits. They are spent in this order: this month's free credits, then promotional credits, then paid credits. The first call in an IST month grants that month's 1,000 free credits, so a new organisation sees them at once.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "orgId",
          "available",
          "held",
          "free",
          "paid",
          "nextResetAt"
        ],
        "properties": {
          "orgId": {
            "type": "string",
            "format": "uuid",
            "description": "The organisation these credits belong to."
          },
          "available": {
            "type": "integer",
            "minimum": -1,
            "description": "Credits that can be spent now: free plus promotional plus paid. **-1 means unlimited** (from contract 0.28.0, only when `unlimited` is true): the organisation is never refused for credits and charges never draw these credits down. -1 is a sentinel, never an amount: no balance is ever negative, and the free, promotional and paid parts below stay the real numbers."
          },
          "unlimited": {
            "type": "boolean",
            "description": "True when the organisation has unlimited credits (an entitlement Rewalto grants and can revoke). Every charged call is still quoted, recorded and receipted at its normal price and shows in usage; it is never refused for credits and never draws the balance down. False for every other organisation. Sent on every answer from contract 0.28.0; absent from older servers."
          },
          "held": {
            "type": "integer",
            "minimum": 0,
            "description": "Credits held for runs in progress: free plus promotional plus paid."
          },
          "free": {
            "$ref": "#/components/schemas/FreeCredits"
          },
          "promo": {
            "title": "PromoCredits",
            "description": "Promotional credits granted by Rewalto staff (for example the startups programme). Spent after this month’s free credits and before paid ones. Always sent from contract 0.4.0; zero and an empty list for an organisation with none.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "available",
              "held",
              "grants"
            ],
            "properties": {
              "available": {
                "type": "integer",
                "minimum": 0,
                "description": "Promotional credits that can be spent now, across all unexpired grants."
              },
              "held": {
                "type": "integer",
                "minimum": 0,
                "description": "Promotional credits held for runs in progress."
              },
              "grants": {
                "type": "array",
                "description": "Each promotional grant with credits left or held, soonest expiry first: the order promotional credits are spent. Each expires on its own date.",
                "items": {
                  "title": "PromoGrant",
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "campaign",
                    "credits",
                    "remaining",
                    "held",
                    "grantedAt",
                    "expiresAt"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "campaign": {
                      "type": "string",
                      "description": "The campaign that granted them, for example startups-2026."
                    },
                    "credits": {
                      "type": "integer",
                      "minimum": 1,
                      "description": "Credits granted."
                    },
                    "remaining": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Credits left to spend."
                    },
                    "held": {
                      "type": "integer",
                      "minimum": 0,
                      "description": "Credits held for runs in progress."
                    },
                    "grantedAt": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "expiresAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "When this grant’s unspent credits expire, as set by its campaign."
                    }
                  }
                }
              }
            }
          },
          "paid": {
            "$ref": "#/components/schemas/PaidCredits"
          },
          "nextResetAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the next monthly free grant lands: 00:00 IST on the 1st (UTC+05:30)."
          }
        },
        "examples": [
          {
            "orgId": "3f2b8c1e-7a4d-4e0b-9c55-1d2e3f4a5b6c",
            "available": 1440,
            "unlimited": false,
            "held": 0,
            "free": {
              "month": "2026-10",
              "granted": 1000,
              "used": 60,
              "remaining": 940,
              "held": 0,
              "expiresAt": "2026-10-31T18:30:00.000Z"
            },
            "promo": {
              "available": 0,
              "held": 0,
              "grants": []
            },
            "paid": {
              "available": 500,
              "held": 0,
              "lots": [
                {
                  "id": "0b6f1c9e-2a47-4d3b-8f10-5c9a7e1d2b34",
                  "credits": 500,
                  "remaining": 500,
                  "held": 0,
                  "purchasedAt": "2026-09-02T08:00:00.000Z",
                  "expiresAt": "2027-09-01T18:30:00.000Z"
                }
              ]
            },
            "nextResetAt": "2026-10-31T18:30:00.000Z"
          }
        ]
      },
      "FreeCredits": {
        "title": "FreeCredits",
        "description": "This IST month's free grant and how much of it is used.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "month",
          "granted",
          "used",
          "remaining",
          "held",
          "expiresAt"
        ],
        "properties": {
          "month": {
            "type": "string",
            "pattern": "^[0-9]{4}-(0[1-9]|1[0-2])$",
            "description": "The IST calendar month, for example 2026-10."
          },
          "granted": {
            "type": "integer",
            "minimum": 0,
            "description": "This month's free grant."
          },
          "used": {
            "type": "integer",
            "minimum": 0,
            "description": "Free credits spent or held for runs this month, net of any returned."
          },
          "remaining": {
            "type": "integer",
            "minimum": 0,
            "description": "Free credits that can be spent now: this month’s only. Unspent free credits expire at the end of the IST month and never roll over; next month starts again at 1,000."
          },
          "held": {
            "type": "integer",
            "minimum": 0,
            "description": "Free credits held for runs in progress."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "When this month’s free credits expire: 00:00 IST on the 1st of next month."
          }
        }
      },
      "PaidCredits": {
        "title": "PaidCredits",
        "description": "Credits that were bought. Zero for an organisation that has bought none.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "available",
          "held",
          "lots"
        ],
        "properties": {
          "available": {
            "type": "integer",
            "minimum": 0,
            "description": "Paid credits that can be spent now, across all unexpired lots."
          },
          "held": {
            "type": "integer",
            "minimum": 0,
            "description": "Paid credits held for runs in progress."
          },
          "lots": {
            "type": "array",
            "description": "Each purchase with credits left or held, soonest expiry first: the order paid credits are spent. Paid credits carry forward and expire 12 months after purchase.",
            "items": {
              "title": "PaidLot",
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id",
                "credits",
                "remaining",
                "held",
                "purchasedAt",
                "expiresAt"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "credits": {
                  "type": "integer",
                  "minimum": 1,
                  "description": "Credits when bought."
                },
                "remaining": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Credits left to spend."
                },
                "held": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Credits held for runs in progress."
                },
                "purchasedAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "expiresAt": {
                  "type": "string",
                  "format": "date-time",
                  "description": "12 months after purchase."
                }
              }
            }
          }
        }
      },
      "UsageEntry": {
        "title": "UsageEntry",
        "description": "One ledger event or one receipt of the caller’s organisation.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "type",
          "kind",
          "units",
          "credits",
          "rateVersion",
          "reservationId",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "evt_<number> for an event, rcp_<uuid> for a receipt."
          },
          "type": {
            "type": "string",
            "enum": [
              "event",
              "receipt"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "grant",
              "top_up",
              "promo",
              "reserve",
              "settle",
              "release",
              "refund",
              "expiry",
              "receipt",
              "read"
            ],
            "description": "grant: monthly free credits. top_up: bought credits. promo: promotional credits granted by Rewalto staff. reserve: credits held before a run. settle: the run closed and was charged. release: a hold went back unspent. refund: credits returned (for example a refunded read). expiry. receipt: what a run was charged and why; its id can be refunded with POST /v1/credits/refunds when the run failed (outcome failed) and was charged. read: what a Library read was charged; its id can be refunded with POST /v1/credits/refunds."
          },
          "units": {
            "type": [
              "null",
              "integer"
            ],
            "description": "Units delivered. Only a receipt has them; null for an event."
          },
          "credits": {
            "type": "integer",
            "minimum": 0,
            "description": "The credits this entry is about: granted, held, charged, returned or removed. Never negative."
          },
          "rateVersion": {
            "type": [
              "null",
              "string"
            ],
            "description": "The rate card version the price came from; null when no price was involved."
          },
          "priceBook": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": false,
            "required": [
              "channel",
              "version"
            ],
            "properties": {
              "channel": {
                "type": "string",
                "description": "The sales channel; `direct` today (one price everywhere)."
              },
              "version": {
                "type": "integer",
                "minimum": 1
              }
            },
            "description": "The price-book version this purchase was sold on (plan 04 T5). It never changes after a later price change. Null for an entry with no quote, and for purchases made before the price book existed."
          },
          "reservationId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "description": "The reservation the entry belongs to, when it belongs to one. Stable: one reservation per charge, and the same id is written on the charge’s receipt and on its reserve, settle and release events, so it links them (with view=all, a read appears as its receipt, kind read, and its settle event: the same credits, spent once, so never add the two). view=charges lists the receipt alone."
          },
          "runId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "description": "The fresh-read run this charge belongs to (0.66.0), when it belongs to one: GET /v1/runs/{runId} and GET /v1/runs/{runId}/rows read it and the rows it delivered, for the same organisation. Set on a run’s receipt (kind receipt) and on its reserve, settle and release events. Null for grants, top-ups, promotional grants, refunds, expiries, and receipts that are not a fresh-read run (such as a dataset export). Null for kind read too: a Library read keeps only a hash of what it delivered, not the rows, so they cannot be fetched again (repeat the same read; identical data within 7 days is free)."
          },
          "outcome": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "delivered",
              "failed",
              null
            ],
            "description": "How a run ended, on a run receipt (kind receipt): delivered, or failed. A charged failed run can be refunded on request; a delivered one cannot. Null for events and reads."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        },
        "examples": [
          {
            "id": "rcp_0b6f1c9e-2a47-4d3b-8f10-5c9a7e1d2b34",
            "type": "receipt",
            "kind": "receipt",
            "units": 120,
            "credits": 60,
            "rateVersion": "2026-10-01",
            "priceBook": {
              "channel": "direct",
              "version": 3
            },
            "reservationId": "7d1a4e52-9c38-4b6f-a0e3-12f4b5c6d7e8",
            "runId": "3c9e1f20-5b7a-4d8e-9f01-2a3b4c5d6e7f",
            "outcome": "delivered",
            "createdAt": "2026-10-15T09:30:00.000Z"
          }
        ]
      },
      "UsagePage": {
        "title": "UsagePage",
        "description": "A page of the caller's organisation's ledger events and receipts, newest first. Only the caller's own organisation is ever shown.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "entries",
          "nextCursor"
        ],
        "properties": {
          "entries": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UsageEntry"
            }
          },
          "nextCursor": {
            "type": [
              "null",
              "string"
            ],
            "description": "Pass as cursor to get the next, older page. Null on the last page."
          }
        },
        "examples": [
          {
            "entries": [],
            "nextCursor": null
          }
        ]
      },
      "RefundRequest": {
        "title": "RefundRequest",
        "description": "Ask for a charge’s credits back, by its receipt (the id of a `read` or `receipt` entry in GET /v1/credits/usage). A charged Library read is refunded, for example when its response never arrived, unless the same data was read again after the receipt. A charged run is refunded only when it failed (its usage entry has outcome failed); a run that returned nothing was never charged, and a run that delivered is not refunded on request. Refunded once: asking again returns the same refund. A refusal is a 409 refund_refused whose one detail (path body/receiptId) names the reason: charged_nothing, data_reread, run_delivered, or (contract 0.28.0) unlimited_credits: the charge was made under unlimited credits, so its price is on the receipt but nothing was drawn from the balance to give back.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "receiptId",
          "reason"
        ],
        "properties": {
          "receiptId": {
            "type": "string",
            "pattern": "^rcp_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "The receipt of the charged read or run, as GET /v1/credits/usage shows it.",
            "examples": [
              "rcp_5c2e8a91-4b7d-4f36-9e10-8a2b3c4d5e6f"
            ]
          },
          "reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "description": "Why, in a sentence. Kept with the refund.",
            "examples": [
              "The connection dropped before the data arrived."
            ]
          }
        },
        "examples": [
          {
            "receiptId": "rcp_5c2e8a91-4b7d-4f36-9e10-8a2b3c4d5e6f",
            "reason": "The connection dropped before the data arrived."
          }
        ]
      },
      "Refund": {
        "title": "Refund",
        "description": "A refund of a charged read or a failed run. The credits went back to the lots they were taken from, with those lots’ own expiry: credits from a lot that has since expired come back expired.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "receiptId",
          "receiptKind",
          "refunded",
          "credits",
          "expiredOnReturn",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "The refund."
          },
          "receiptId": {
            "type": "string",
            "description": "The receipt refunded."
          },
          "receiptKind": {
            "type": "string",
            "enum": [
              "read",
              "run"
            ],
            "description": "read: a Library read’s receipt. run: a run’s receipt."
          },
          "refunded": {
            "type": "boolean",
            "description": "True when this request refunded the receipt; false when it had already been refunded (nothing new happened, the first refund is returned)."
          },
          "credits": {
            "type": "integer",
            "minimum": 1,
            "description": "Credits returned."
          },
          "expiredOnReturn": {
            "type": "integer",
            "minimum": 0,
            "description": "Of those, credits returned to lots that had already expired: returned, but not spendable."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When it was refunded."
          }
        },
        "examples": [
          {
            "id": "9e1d2c3b-4a5f-4e6d-8c7b-0a1b2c3d4e5f",
            "receiptId": "rcp_5c2e8a91-4b7d-4f36-9e10-8a2b3c4d5e6f",
            "receiptKind": "read",
            "refunded": true,
            "credits": 3,
            "expiredOnReturn": 0,
            "createdAt": "2026-10-15T11:05:00.000Z"
          }
        ]
      },
      "QuoteRequest": {
        "title": "QuoteRequest",
        "description": "What to price: a catalogue recipe, how many units of its data are wanted, and the extras to use. Add a cadence for a recurring report or watch to see the cost of each delivery and of a month. The organisation is taken from the credential, never from the body.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "recipe",
          "units"
        ],
        "properties": {
          "recipe": {
            "type": "string",
            "pattern": "^[a-z][a-z0-9_]{1,63}$",
            "description": "The catalogue recipe id, for example commerce_product_page."
          },
          "units": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10000000,
            "description": "Units of the recipe’s data wanted (pages, records, rows...)."
          },
          "extras": {
            "type": "array",
            "maxItems": 10,
            "description": "Extras to use. Only extras the recipe offers are accepted.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "key"
              ],
              "properties": {
                "key": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{1,63}$"
                },
                "multiplier": {
                  "type": "integer",
                  "minimum": 1,
                  "maximum": 1000,
                  "default": 1
                }
              }
            }
          },
          "cadence": {
            "type": "string",
            "enum": [
              "daily",
              "weekly",
              "monthly"
            ],
            "description": "Set for a recurring report or watch: how often it delivers."
          },
          "run": {
            "title": "QuoteRun",
            "description": "Set to quote a fresh read: the recipe’s collector reads the query now at each pin code, one job per pin, once the quote is approved. units is then the most listings wanted across all pins. The run’s id is the quote’s id: follow it at GET /v1/runs/{id}.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "query",
              "pincodes"
            ],
            "properties": {
              "query": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200,
                "description": "A search term, or a product reference for a recipe that reads one product."
              },
              "pincodes": {
                "type": "array",
                "minItems": 1,
                "maxItems": 20,
                "uniqueItems": true,
                "items": {
                  "type": "string",
                  "pattern": "^([1-9][0-9]{5}|national)$"
                },
                "description": "Pin codes to read at; `national` for a recipe that is not location scoped. One job each."
              }
            }
          }
        },
        "examples": [
          {
            "recipe": "commerce_product_page",
            "units": 120,
            "extras": [
              {
                "key": "browser"
              }
            ],
            "cadence": "weekly"
          },
          {
            "recipe": "jiomart",
            "units": 100,
            "run": {
              "query": "atta",
              "pincodes": [
                "400001",
                "560001"
              ]
            }
          }
        ]
      },
      "Quote": {
        "title": "Quote",
        "description": "What a run would cost at most. mode published: the recipe has a published rate and runs at once. mode approval: no rate is set yet, so the run starts only after the quote is approved. The ceiling is never exceeded; a run is charged for what it delivers, rounded up.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "mode",
          "status",
          "recipe",
          "unit",
          "units",
          "rateVersion",
          "extras",
          "lines",
          "ceiling",
          "expiresAt",
          "createdAt",
          "approvedAt",
          "recurring"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "mode": {
            "type": "string",
            "enum": [
              "published",
              "approval"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "approved",
              "expired"
            ],
            "description": "open: can be approved. approved: credits are held. expired: ask for a new quote."
          },
          "recipe": {
            "type": "string"
          },
          "unit": {
            "type": "string"
          },
          "units": {
            "type": "integer",
            "minimum": 1,
            "description": "The units estimate this quote prices."
          },
          "rateVersion": {
            "type": "string",
            "description": "The one rate version every line was priced at, for example c1.r2."
          },
          "extras": {
            "type": "array",
            "items": {
              "title": "QuoteExtra",
              "description": "An extra (a tool such as a browser or OCR) applied to the quoted data.",
              "type": "object",
              "additionalProperties": false,
              "required": [
                "key",
                "credits",
                "perUnits",
                "multiplier"
              ],
              "properties": {
                "key": {
                  "type": "string",
                  "description": "The extra’s name, from the rate card."
                },
                "credits": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Credits per perUnits units."
                },
                "perUnits": {
                  "type": "integer",
                  "minimum": 1
                },
                "multiplier": {
                  "type": "integer",
                  "minimum": 1,
                  "description": "How many times the extra applies per unit, for example the number of pin codes."
                }
              },
              "examples": [
                {
                  "key": "browser",
                  "credits": 1,
                  "perUnits": 1,
                  "multiplier": 1
                }
              ]
            }
          },
          "lines": {
            "type": "array",
            "items": {
              "title": "QuoteLine",
              "description": "One kind of data in a quote: the units expected and the credits for them.",
              "type": "object",
              "additionalProperties": false,
              "required": [
                "recipe",
                "unit",
                "units",
                "base",
                "extras",
                "credits"
              ],
              "properties": {
                "recipe": {
                  "type": "string"
                },
                "unit": {
                  "type": "string",
                  "description": "What one unit is, for example page or record."
                },
                "units": {
                  "type": "integer",
                  "minimum": 0
                },
                "base": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "credits",
                    "perUnits"
                  ],
                  "properties": {
                    "credits": {
                      "type": "integer",
                      "minimum": 0
                    },
                    "perUnits": {
                      "type": "integer",
                      "minimum": 1
                    }
                  }
                },
                "extras": {
                  "type": "array",
                  "items": {
                    "title": "QuoteExtra",
                    "description": "An extra (a tool such as a browser or OCR) applied to the quoted data.",
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "key",
                      "credits",
                      "perUnits",
                      "multiplier"
                    ],
                    "properties": {
                      "key": {
                        "type": "string",
                        "description": "The extra’s name, from the rate card."
                      },
                      "credits": {
                        "type": "integer",
                        "minimum": 0,
                        "description": "Credits per perUnits units."
                      },
                      "perUnits": {
                        "type": "integer",
                        "minimum": 1
                      },
                      "multiplier": {
                        "type": "integer",
                        "minimum": 1,
                        "description": "How many times the extra applies per unit, for example the number of pin codes."
                      }
                    },
                    "examples": [
                      {
                        "key": "browser",
                        "credits": 1,
                        "perUnits": 1,
                        "multiplier": 1
                      }
                    ]
                  }
                },
                "credits": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Credits for this line, rounded up."
                }
              }
            }
          },
          "ceiling": {
            "type": "integer",
            "minimum": 0,
            "description": "The most the run can be charged, in credits. This is what approval holds."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "approvedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "run": {
            "title": "QuoteRun",
            "description": "Only for a fresh-read run: what it reads. Its id is this quote’s id (GET /v1/runs/{id} once approved).",
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": false,
            "required": [
              "query",
              "pincodes"
            ],
            "properties": {
              "query": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200,
                "description": "A search term, or a product reference for a recipe that reads one product."
              },
              "pincodes": {
                "type": "array",
                "minItems": 1,
                "maxItems": 20,
                "uniqueItems": true,
                "items": {
                  "type": "string",
                  "pattern": "^([1-9][0-9]{5}|national)$"
                },
                "description": "Pin codes to read at; `national` for a recipe that is not location scoped. One job each."
              }
            }
          },
          "recurring": {
            "title": "QuoteRecurring",
            "description": "Only for a recurring report or watch, shown once before the first delivery: the cost of each delivery and of a month, and whether the month fits the credits left.",
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": false,
            "required": [
              "cadence",
              "deliveriesPerMonth",
              "perDelivery",
              "perMonth",
              "creditsAvailable",
              "fitsPlan",
              "notice"
            ],
            "properties": {
              "cadence": {
                "type": "string",
                "enum": [
                  "daily",
                  "weekly",
                  "monthly"
                ]
              },
              "deliveriesPerMonth": {
                "type": "integer",
                "minimum": 1,
                "description": "Deliveries counted in a month: the most the cadence can make."
              },
              "perDelivery": {
                "type": "integer",
                "minimum": 0,
                "description": "Credits for one delivery (at most)."
              },
              "perMonth": {
                "type": "integer",
                "minimum": 0,
                "description": "Credits for a month of deliveries (at most)."
              },
              "creditsAvailable": {
                "type": "integer",
                "minimum": -1,
                "description": "Credits the organisation has now; -1 when it has unlimited credits (as `available` on GET /v1/credits/balance, contract 0.28.0)."
              },
              "fitsPlan": {
                "type": "boolean",
                "description": "False when the month costs more than the credits left. Always true with unlimited credits."
              },
              "notice": {
                "type": [
                  "null",
                  "string"
                ],
                "description": "When fitsPlan is false: that it will not fit and a bigger plan is needed."
              }
            }
          }
        },
        "examples": [
          {
            "id": "9b1d6e0a-4c3f-4f7e-8a21-5d0c7b9e1f42",
            "mode": "published",
            "status": "open",
            "recipe": "commerce_product_page",
            "unit": "page",
            "units": 120,
            "rateVersion": "c1.r1",
            "extras": [
              {
                "key": "browser",
                "credits": 1,
                "perUnits": 1,
                "multiplier": 1
              }
            ],
            "lines": [
              {
                "recipe": "commerce_product_page",
                "unit": "page",
                "units": 120,
                "base": {
                  "credits": 1,
                  "perUnits": 1
                },
                "extras": [
                  {
                    "key": "browser",
                    "credits": 1,
                    "perUnits": 1,
                    "multiplier": 1
                  }
                ],
                "credits": 240
              }
            ],
            "ceiling": 240,
            "expiresAt": "2026-10-15T10:30:00.000Z",
            "createdAt": "2026-10-15T10:00:00.000Z",
            "approvedAt": null,
            "recurring": {
              "cadence": "weekly",
              "deliveriesPerMonth": 5,
              "perDelivery": 240,
              "perMonth": 1200,
              "creditsAvailable": 1000,
              "fitsPlan": false,
              "notice": "A month of deliveries can cost up to 1200 credits and 1000 are left: it will not fit. A bigger plan is needed."
            }
          }
        ]
      },
      "ApprovedQuote": {
        "title": "ApprovedQuote",
        "description": "The quote after approval, and the credits held for the run: free credits first, then paid. Approving an expired or already approved quote, or one that is not yours, is refused.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "quote",
          "reservation"
        ],
        "properties": {
          "quote": {
            "$ref": "#/components/schemas/Quote"
          },
          "reservation": {
            "title": "Reservation",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "ceiling",
              "freeCredits",
              "paidCredits"
            ],
            "properties": {
              "id": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "uuid",
                "description": "The hold on the credits; null when the ceiling is zero and nothing is held."
              },
              "ceiling": {
                "type": "integer",
                "minimum": 0
              },
              "freeCredits": {
                "type": "integer",
                "minimum": 0,
                "description": "Held from free credits."
              },
              "paidCredits": {
                "type": "integer",
                "minimum": 0,
                "description": "Held from paid credits."
              }
            }
          }
        }
      },
      "CatalogueCategory": {
        "type": "object",
        "title": "Catalogue category",
        "description": "One tab and one section of the catalogue page.",
        "additionalProperties": false,
        "required": [
          "id",
          "name",
          "description",
          "family",
          "order",
          "productCount",
          "entryCount",
          "statusCounts"
        ],
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable category id.",
            "examples": [
              "quick_commerce"
            ],
            "pattern": "^[a-z][a-z0-9_]{1,63}$"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The tab and section title.",
            "examples": [
              "Quick commerce"
            ]
          },
          "description": {
            "type": "string",
            "title": "Description",
            "description": "One line under the section title.",
            "examples": [
              "Prices, stock and assortment by pin code and dark store on India’s quick-commerce apps."
            ]
          },
          "family": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "commerce",
              "investors",
              "startups",
              "companies",
              "public-records",
              null
            ],
            "title": "Family",
            "description": "The Data library family it is grouped under (D-1548): commerce, investors, startups, companies or public-records; null when it is in none (social listening, reports and watches, free tools). Added in contract 0.28.0.",
            "examples": [
              "commerce"
            ]
          },
          "order": {
            "type": "integer",
            "minimum": 0,
            "title": "Order",
            "description": "Position on the page, from 1.",
            "examples": [
              1
            ]
          },
          "productCount": {
            "type": "integer",
            "minimum": 0,
            "title": "Products",
            "description": "Cards in this category (for \"see N more\").",
            "examples": [
              5
            ]
          },
          "entryCount": {
            "type": "integer",
            "minimum": 0,
            "title": "Entries",
            "description": "Entries across those cards: the tab count.",
            "examples": [
              12
            ]
          },
          "statusCounts": {
            "type": "object",
            "title": "Status counts",
            "description": "How many entries have each status.",
            "additionalProperties": false,
            "required": [
              "live",
              "preview",
              "planned",
              "degraded"
            ],
            "properties": {
              "live": {
                "type": "integer",
                "minimum": 0,
                "title": "Live",
                "description": "Entries that are live.",
                "examples": [
                  3
                ]
              },
              "preview": {
                "type": "integer",
                "minimum": 0,
                "title": "Preview",
                "description": "Entries in preview.",
                "examples": [
                  0
                ]
              },
              "planned": {
                "type": "integer",
                "minimum": 0,
                "title": "Planned",
                "description": "Entries that are planned.",
                "examples": [
                  5
                ]
              },
              "degraded": {
                "type": "integer",
                "minimum": 0,
                "title": "Degraded",
                "description": "Entries that are degraded.",
                "examples": [
                  1
                ]
              }
            }
          }
        }
      },
      "CatalogueProduct": {
        "type": "object",
        "title": "Catalogue product",
        "description": "One card: a data product and what it offers. Derived fields (counts, kinds, modes, status, pricing) come from its entries.",
        "additionalProperties": false,
        "required": [
          "id",
          "categoryId",
          "name",
          "summary",
          "order",
          "entryIds",
          "entryCount",
          "entryKinds",
          "modes",
          "status",
          "statusNote",
          "entryStatusCounts",
          "sources",
          "coverage",
          "freshness",
          "pricing"
        ],
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable data-product id.",
            "examples": [
              "qc_prices_by_pin"
            ],
            "pattern": "^[a-z][a-z0-9_]{1,63}$"
          },
          "categoryId": {
            "type": "string",
            "title": "Category",
            "description": "The category it is listed in.",
            "examples": [
              "quick_commerce"
            ],
            "pattern": "^[a-z][a-z0-9_]{1,63}$"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The card title.",
            "examples": [
              "Prices and stock by pin"
            ]
          },
          "summary": {
            "type": "string",
            "title": "What you get",
            "description": "One line: what you get.",
            "examples": [
              "Selling price, MRP, discount and in-stock state per product, by pin code."
            ]
          },
          "order": {
            "type": "integer",
            "minimum": 0,
            "title": "Order",
            "description": "Position within its category, from 1.",
            "examples": [
              1
            ]
          },
          "entryIds": {
            "type": "array",
            "title": "Entries",
            "description": "The ids of its entries.",
            "items": {
              "type": "string",
              "title": "Entry id",
              "description": "An entry id.",
              "examples": [
                "qc_price_history"
              ],
              "pattern": "^[a-z][a-z0-9_]{1,63}$"
            }
          },
          "entryCount": {
            "type": "integer",
            "minimum": 0,
            "title": "Entry count",
            "description": "How many entries it has.",
            "examples": [
              8
            ]
          },
          "entryKinds": {
            "type": "array",
            "title": "Kinds",
            "description": "The kinds of entry it has, in the order dataset, recipe, workflow, tool.",
            "items": {
              "type": "string",
              "enum": [
                "dataset",
                "recipe",
                "workflow",
                "tool"
              ],
              "title": "Kind",
              "description": "An entry kind.",
              "examples": [
                "dataset"
              ]
            }
          },
          "modes": {
            "type": "array",
            "title": "Modes",
            "description": "keep: results are kept as history. live: fetched on demand and not stored. Shown as badges.",
            "items": {
              "type": "string",
              "enum": [
                "keep",
                "live"
              ],
              "title": "Mode",
              "description": "keep or live.",
              "examples": [
                "keep"
              ]
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "live",
              "preview",
              "planned",
              "degraded"
            ],
            "title": "Status",
            "description": "live: collected and served today. preview: built and checked, shown for a look; it cannot be run or charged yet. planned: not built; listed honestly as planned. degraded: live, but failing now (statusNote says how); data already kept stays readable.",
            "examples": [
              "live"
            ]
          },
          "statusNote": {
            "type": [
              "null",
              "string"
            ],
            "title": "Status note",
            "description": "Why it is degraded, preview or planned, in plain words; null when there is nothing to add.",
            "examples": [
              "Instamart has delivered no new prices since 15 Oct 2026; the other apps are current."
            ]
          },
          "entryStatusCounts": {
            "type": "object",
            "title": "Status counts",
            "description": "How many entries have each status.",
            "additionalProperties": false,
            "required": [
              "live",
              "preview",
              "planned",
              "degraded"
            ],
            "properties": {
              "live": {
                "type": "integer",
                "minimum": 0,
                "title": "Live",
                "description": "Entries that are live.",
                "examples": [
                  3
                ]
              },
              "preview": {
                "type": "integer",
                "minimum": 0,
                "title": "Preview",
                "description": "Entries in preview.",
                "examples": [
                  0
                ]
              },
              "planned": {
                "type": "integer",
                "minimum": 0,
                "title": "Planned",
                "description": "Entries that are planned.",
                "examples": [
                  5
                ]
              },
              "degraded": {
                "type": "integer",
                "minimum": 0,
                "title": "Degraded",
                "description": "Entries that are degraded.",
                "examples": [
                  1
                ]
              }
            }
          },
          "sources": {
            "type": "array",
            "title": "Sources",
            "description": "The retailers, sites or registers it covers.",
            "items": {
              "type": "object",
              "title": "Source",
              "description": "A retailer, site or register the data is about, with its own status. Never another data vendor.",
              "additionalProperties": false,
              "required": [
                "name",
                "status"
              ],
              "properties": {
                "name": {
                  "type": "string",
                  "title": "Name",
                  "description": "The retailer, site or register, as people know it.",
                  "examples": [
                    "Blinkit"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "live",
                    "preview",
                    "planned",
                    "degraded"
                  ],
                  "title": "Status",
                  "description": "live: collected and served today. preview: built and checked, shown for a look; it cannot be run or charged yet. planned: not built; listed honestly as planned. degraded: live, but failing now (statusNote says how); data already kept stays readable.",
                  "examples": [
                    "live"
                  ]
                }
              }
            }
          },
          "coverage": {
            "type": "object",
            "title": "Coverage",
            "description": "What the data covers, in one line, and where the figures come from.",
            "additionalProperties": false,
            "required": [
              "label",
              "basis",
              "asOf"
            ],
            "properties": {
              "label": {
                "type": "string",
                "title": "Coverage",
                "description": "One line for the card, computed from data (or marked an estimate). Holes are shown, not hidden.",
                "examples": [
                  "Blinkit 30 pins · Instamart 26 of 28 pins"
                ]
              },
              "basis": {
                "type": "string",
                "enum": [
                  "measured",
                  "estimate",
                  "not_measured"
                ],
                "title": "Basis",
                "description": "measured: counted from data at asOf. estimate: an estimate, and shown as one. not_measured: no figure yet.",
                "examples": [
                  "measured"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "Measured at",
                "description": "When the figures were measured; null when not measured.",
                "examples": [
                  "2026-10-15T09:54:00Z"
                ]
              }
            }
          },
          "freshness": {
            "type": "object",
            "title": "Freshness",
            "description": "How often it is collected, and the newest data time.",
            "additionalProperties": false,
            "required": [
              "label",
              "cadence",
              "lastUpdatedAt",
              "basis"
            ],
            "properties": {
              "label": {
                "type": "string",
                "title": "Freshness",
                "description": "One line for the card. The page adds \"updated N ago\" from lastUpdatedAt.",
                "examples": [
                  "daily"
                ]
              },
              "cadence": {
                "type": "string",
                "enum": [
                  "hourly",
                  "daily",
                  "weekly",
                  "on_demand",
                  "historical",
                  "not_scheduled"
                ],
                "title": "Cadence",
                "description": "How often new data arrives: hourly, daily, weekly, on_demand (fetched when asked), historical (kept data whose collection has stopped or was a one-off: sold as history, with its newest date in lastUpdatedAt), or not_scheduled (nothing collected yet).",
                "examples": [
                  "hourly"
                ]
              },
              "lastUpdatedAt": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "Last updated",
                "description": "The newest data time; null when nothing is collected yet.",
                "examples": [
                  "2026-10-15T09:27:00Z"
                ]
              },
              "basis": {
                "type": "string",
                "enum": [
                  "measured",
                  "estimate",
                  "not_measured"
                ],
                "title": "Basis",
                "description": "measured: counted from data at asOf. estimate: an estimate, and shown as one. not_measured: no figure yet.",
                "examples": [
                  "measured"
                ]
              }
            }
          },
          "pricing": {
            "$ref": "#/components/schemas/CataloguePricing"
          }
        }
      },
      "CatalogueEntry": {
        "type": "object",
        "title": "Catalogue entry",
        "description": "One entry in full: a dataset, recipe, workflow or tool, with its inputs, outputs, sample, data dictionary, coverage table, freshness, rates, rights, versions and, for a workflow, what it uses.",
        "additionalProperties": false,
        "required": [
          "id",
          "kind",
          "categoryId",
          "productId",
          "name",
          "summary",
          "status",
          "statusNote",
          "modes",
          "dataTypes",
          "sources",
          "coverage",
          "freshness",
          "pricing",
          "rates",
          "recipe",
          "freshRead",
          "inputs",
          "outputs",
          "dataDictionary",
          "sample",
          "rights",
          "versions",
          "uses"
        ],
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable entry id.",
            "examples": [
              "qc_price_history"
            ],
            "pattern": "^[a-z][a-z0-9_]{1,63}$"
          },
          "kind": {
            "type": "string",
            "enum": [
              "dataset",
              "recipe",
              "workflow",
              "tool"
            ],
            "title": "Kind",
            "description": "dataset: kept data Rewalto holds. recipe: a tested way to fetch one kind of data from one source. workflow: a product built on recipes and datasets. tool: one of the eight free tools; never priced.",
            "examples": [
              "dataset"
            ]
          },
          "categoryId": {
            "type": "string",
            "title": "Category",
            "description": "Its category.",
            "examples": [
              "quick_commerce"
            ],
            "pattern": "^[a-z][a-z0-9_]{1,63}$"
          },
          "productId": {
            "type": "string",
            "title": "Product",
            "description": "Its card.",
            "examples": [
              "qc_prices_by_pin"
            ],
            "pattern": "^[a-z][a-z0-9_]{1,63}$"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The entry title.",
            "examples": [
              "Price history by pin"
            ]
          },
          "summary": {
            "type": "string",
            "title": "Summary",
            "description": "One line: what it is.",
            "examples": [
              "Every price we have read, per product, pin and time."
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "live",
              "preview",
              "planned",
              "degraded"
            ],
            "title": "Status",
            "description": "live: collected and served today. preview: built and checked, shown for a look; it cannot be run or charged yet. planned: not built; listed honestly as planned. degraded: live, but failing now (statusNote says how); data already kept stays readable.",
            "examples": [
              "live"
            ]
          },
          "statusNote": {
            "type": [
              "null",
              "string"
            ],
            "title": "Status note",
            "description": "Why it is degraded, preview or planned.",
            "examples": [
              "Not built yet."
            ]
          },
          "modes": {
            "type": "array",
            "title": "Modes",
            "description": "keep and/or live. Empty for a tool.",
            "items": {
              "type": "string",
              "enum": [
                "keep",
                "live"
              ],
              "title": "Mode",
              "description": "keep or live.",
              "examples": [
                "keep"
              ]
            }
          },
          "dataTypes": {
            "type": "array",
            "title": "Data types",
            "description": "The kinds of data it carries, in words (searched).",
            "items": {
              "type": "string",
              "title": "Data type",
              "description": "A data type.",
              "examples": [
                "price by pin"
              ]
            }
          },
          "sources": {
            "type": "array",
            "title": "Sources",
            "description": "The retailers, sites or registers it covers.",
            "items": {
              "type": "object",
              "title": "Source",
              "description": "A retailer, site or register the data is about, with its own status. Never another data vendor.",
              "additionalProperties": false,
              "required": [
                "name",
                "status"
              ],
              "properties": {
                "name": {
                  "type": "string",
                  "title": "Name",
                  "description": "The retailer, site or register, as people know it.",
                  "examples": [
                    "Blinkit"
                  ]
                },
                "status": {
                  "type": "string",
                  "enum": [
                    "live",
                    "preview",
                    "planned",
                    "degraded"
                  ],
                  "title": "Status",
                  "description": "live: collected and served today. preview: built and checked, shown for a look; it cannot be run or charged yet. planned: not built; listed honestly as planned. degraded: live, but failing now (statusNote says how); data already kept stays readable.",
                  "examples": [
                    "live"
                  ]
                }
              }
            }
          },
          "coverage": {
            "type": "object",
            "title": "Coverage",
            "description": "One line plus the full table, holes included.",
            "additionalProperties": false,
            "required": [
              "label",
              "basis",
              "asOf",
              "table"
            ],
            "properties": {
              "label": {
                "type": "string",
                "title": "Coverage",
                "description": "One line for the card, computed from data (or marked an estimate). Holes are shown, not hidden.",
                "examples": [
                  "Blinkit 30 pins · Instamart 26 of 28 pins"
                ]
              },
              "basis": {
                "type": "string",
                "enum": [
                  "measured",
                  "estimate",
                  "not_measured"
                ],
                "title": "Basis",
                "description": "measured: counted from data at asOf. estimate: an estimate, and shown as one. not_measured: no figure yet.",
                "examples": [
                  "measured"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "Measured at",
                "description": "When the figures were measured; null when not measured.",
                "examples": [
                  "2026-10-15T09:54:00Z"
                ]
              },
              "table": {
                "type": "array",
                "title": "Coverage table",
                "description": "Per source or dimension; holes included.",
                "items": {
                  "type": "object",
                  "title": "Coverage row",
                  "description": "One row of the coverage table; holes have covered false.",
                  "additionalProperties": false,
                  "required": [
                    "label",
                    "value",
                    "covered",
                    "basis",
                    "asOf",
                    "note"
                  ],
                  "properties": {
                    "label": {
                      "type": "string",
                      "title": "Label",
                      "description": "What the row is about: a source, a city, a field.",
                      "examples": [
                        "Instamart"
                      ]
                    },
                    "value": {
                      "type": "string",
                      "title": "Value",
                      "description": "The figure, in words.",
                      "examples": [
                        "26 of 28 pins"
                      ]
                    },
                    "covered": {
                      "type": "boolean",
                      "title": "Covered",
                      "description": "False for a hole.",
                      "examples": [
                        true
                      ]
                    },
                    "basis": {
                      "type": "string",
                      "enum": [
                        "measured",
                        "estimate",
                        "not_measured"
                      ],
                      "title": "Basis",
                      "description": "measured: counted from data at asOf. estimate: an estimate, and shown as one. not_measured: no figure yet.",
                      "examples": [
                        "measured"
                      ]
                    },
                    "asOf": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "format": "date-time",
                      "title": "Measured at",
                      "description": "When it was measured; null when not measured.",
                      "examples": [
                        "2026-10-15T21:06:00Z"
                      ]
                    },
                    "note": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Note",
                      "description": "Anything the reader should know.",
                      "examples": [
                        "Two pins taken out of the daily panel."
                      ]
                    },
                    "pincodes": {
                      "type": "array",
                      "title": "Pin codes",
                      "description": "A measured source only: every pin code Rewalto's own collection read this source at, all time, sorted. Pins only customers' fresh reads reached are never listed. Absent on a row that is not a measured source; empty when it reads nationally only.",
                      "items": {
                        "type": "string",
                        "title": "Pin code",
                        "description": "A six-digit Indian pin code.",
                        "examples": [
                          "560001"
                        ],
                        "pattern": "^[1-9][0-9]{5}$"
                      },
                      "examples": [
                        [
                          "560001",
                          "560034"
                        ]
                      ]
                    }
                  }
                }
              }
            }
          },
          "freshness": {
            "type": "object",
            "title": "Freshness",
            "description": "How often it is collected, and the newest data time.",
            "additionalProperties": false,
            "required": [
              "label",
              "cadence",
              "lastUpdatedAt",
              "basis"
            ],
            "properties": {
              "label": {
                "type": "string",
                "title": "Freshness",
                "description": "One line for the card. The page adds \"updated N ago\" from lastUpdatedAt.",
                "examples": [
                  "daily"
                ]
              },
              "cadence": {
                "type": "string",
                "enum": [
                  "hourly",
                  "daily",
                  "weekly",
                  "on_demand",
                  "historical",
                  "not_scheduled"
                ],
                "title": "Cadence",
                "description": "How often new data arrives: hourly, daily, weekly, on_demand (fetched when asked), historical (kept data whose collection has stopped or was a one-off: sold as history, with its newest date in lastUpdatedAt), or not_scheduled (nothing collected yet).",
                "examples": [
                  "hourly"
                ]
              },
              "lastUpdatedAt": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "Last updated",
                "description": "The newest data time; null when nothing is collected yet.",
                "examples": [
                  "2026-10-15T09:27:00Z"
                ]
              },
              "basis": {
                "type": "string",
                "enum": [
                  "measured",
                  "estimate",
                  "not_measured"
                ],
                "title": "Basis",
                "description": "measured: counted from data at asOf. estimate: an estimate, and shown as one. not_measured: no figure yet.",
                "examples": [
                  "measured"
                ]
              }
            }
          },
          "pricing": {
            "$ref": "#/components/schemas/CataloguePricing"
          },
          "rates": {
            "type": "array",
            "title": "Rates",
            "description": "Its rate rows; empty when it has none (planned entries, tools).",
            "items": {
              "type": "object",
              "title": "Rate",
              "description": "One rate row of an entry (C-012), read from the rate card.",
              "additionalProperties": false,
              "required": [
                "unit",
                "unitLabel",
                "credits",
                "perUnits",
                "extras",
                "rateStatus",
                "cardVersion"
              ],
              "properties": {
                "unit": {
                  "type": "string",
                  "title": "Unit",
                  "description": "The rate-card unit key.",
                  "examples": [
                    "history_points"
                  ]
                },
                "unitLabel": {
                  "type": "string",
                  "title": "Unit in words",
                  "description": "The unit, plural.",
                  "examples": [
                    "data points"
                  ]
                },
                "credits": {
                  "type": [
                    "null",
                    "integer"
                  ],
                  "minimum": 0,
                  "title": "Credits",
                  "description": "Credits per perUnits units; null while the rate is not set.",
                  "examples": [
                    1
                  ]
                },
                "perUnits": {
                  "type": [
                    "null",
                    "integer"
                  ],
                  "minimum": 0,
                  "title": "Per units",
                  "description": "How many units the credits buy; null while not set.",
                  "examples": [
                    10
                  ]
                },
                "extras": {
                  "type": "array",
                  "title": "Extras",
                  "description": "Extras that apply on top (browser, pin_code, ai_structuring, pdf, ocr), from the same rate card.",
                  "items": {
                    "type": "string",
                    "title": "Extra",
                    "description": "An extra on the rate card.",
                    "examples": [
                      "pin_code"
                    ]
                  }
                },
                "rateStatus": {
                  "type": "string",
                  "enum": [
                    "published",
                    "not_set"
                  ],
                  "title": "Rate status",
                  "description": "published: charged at once at this rate. not_set: quoted first and run only after approval.",
                  "examples": [
                    "published"
                  ]
                },
                "cardVersion": {
                  "type": "integer",
                  "minimum": 0,
                  "title": "Rate card",
                  "description": "The rate card this row is on.",
                  "examples": [
                    2
                  ]
                }
              }
            }
          },
          "recipe": {
            "type": [
              "null",
              "string"
            ],
            "pattern": "^[a-z][a-z0-9_]{1,63}$",
            "title": "Recipe",
            "description": "The catalogue recipe this entry runs: send exactly this as `recipe` in POST /v1/quotes. Null for a dataset, workflow or tool, and for a recipe entry not linked to a recipe. Never derive it from the entry id.",
            "examples": [
              "ajio"
            ]
          },
          "freshRead": {
            "type": "object",
            "title": "Fresh read",
            "description": "Whether this entry can be quoted as a fresh-read run now (POST /v1/quotes with `recipe` and `run`), and at which pin codes. As of meta.asOf (cached up to a minute): the quote checks again and can still refuse with `unknown_capability` if a collector stopped since. Offer a run only when `available` is true.",
            "additionalProperties": false,
            "required": [
              "available",
              "reason",
              "pinScope",
              "pincodes",
              "maxPincodes"
            ],
            "properties": {
              "available": {
                "type": "boolean",
                "title": "Available",
                "description": "True when a run can be quoted now. False whenever it cannot, or it could not be checked.",
                "examples": [
                  true
                ]
              },
              "reason": {
                "type": [
                  "null",
                  "string"
                ],
                "enum": [
                  "not_a_recipe",
                  "no_recipe",
                  "planned",
                  "not_published",
                  "not_priced",
                  "no_running_lane",
                  "not_checked",
                  null
                ],
                "title": "Reason",
                "description": "Why no run is offered; null exactly when available. not_a_recipe: only recipe entries run. no_recipe: not linked to a recipe. planned: the entry is Planned. not_published: no published version to run. not_priced: its recipe has no current rate. no_running_lane: no collector runs it on demand now. not_checked: could not be checked, so not offered.",
                "examples": [
                  null
                ]
              },
              "pinScope": {
                "type": [
                  "null",
                  "string"
                ],
                "enum": [
                  "any",
                  "listed",
                  null
                ],
                "title": "Pin scope",
                "description": "any: any six-digit pin code (or `national`). listed: only the pin codes in `pincodes`. Null when not available.",
                "examples": [
                  "listed"
                ]
              },
              "pincodes": {
                "type": "array",
                "title": "Pin codes",
                "description": "When pinScope is listed: the pin codes a run may ask for, ascending. Empty otherwise.",
                "items": {
                  "type": "string",
                  "title": "Pin code",
                  "description": "A six-digit pin code.",
                  "examples": [
                    "400001"
                  ],
                  "pattern": "^[1-9][0-9]{5}$"
                }
              },
              "maxPincodes": {
                "type": "integer",
                "minimum": 0,
                "title": "Most pin codes",
                "description": "The most pin codes one run may ask for.",
                "examples": [
                  20
                ]
              }
            }
          },
          "inputs": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": true,
            "title": "Inputs",
            "description": "What it takes, as JSON Schema; null when it is not designed yet or takes nothing."
          },
          "outputs": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": true,
            "title": "Outputs",
            "description": "One record it returns, as JSON Schema; null when not designed yet."
          },
          "dataDictionary": {
            "type": "array",
            "title": "Data dictionary",
            "description": "Each output field in words.",
            "items": {
              "type": "object",
              "title": "Field",
              "description": "One output field.",
              "additionalProperties": false,
              "required": [
                "field",
                "type",
                "description"
              ],
              "properties": {
                "field": {
                  "type": "string",
                  "title": "Field",
                  "description": "The field name.",
                  "examples": [
                    "priceMinor"
                  ]
                },
                "type": {
                  "type": "string",
                  "title": "Type",
                  "description": "Its JSON type, with null when it can be empty.",
                  "examples": [
                    "integer | null"
                  ]
                },
                "description": {
                  "type": "string",
                  "title": "Description",
                  "description": "What it means.",
                  "examples": [
                    "Selling price in paise."
                  ]
                }
              }
            }
          },
          "sample": {
            "type": "object",
            "title": "Sample",
            "description": "A few rows to show the shape.",
            "additionalProperties": false,
            "required": [
              "rows",
              "illustrative"
            ],
            "properties": {
              "rows": {
                "type": "array",
                "title": "Rows",
                "description": "Sample rows.",
                "items": {
                  "type": "object",
                  "additionalProperties": true,
                  "title": "Row",
                  "description": "One sample row, shaped like outputs."
                }
              },
              "illustrative": {
                "type": "boolean",
                "title": "Illustrative",
                "description": "True when the rows are made up to show the shape, not real readings.",
                "examples": [
                  true
                ]
              }
            }
          },
          "rights": {
            "type": "object",
            "title": "Rights",
            "description": "How it may be used (the collection policy, D-1380).",
            "additionalProperties": false,
            "required": [
              "note",
              "redistribution"
            ],
            "properties": {
              "note": {
                "type": "string",
                "title": "Note",
                "description": "Usage rights in one or two lines.",
                "examples": [
                  "Public data Rewalto collects itself."
                ]
              },
              "redistribution": {
                "type": "string",
                "enum": [
                  "allowed",
                  "not_allowed",
                  "undecided"
                ],
                "title": "Redistribution",
                "description": "Whether a customer may pass the data on: allowed, not_allowed or undecided.",
                "examples": [
                  "allowed"
                ]
              }
            }
          },
          "versions": {
            "type": "array",
            "title": "Versions",
            "description": "Its versions, newest first; empty when nothing is built.",
            "items": {
              "type": "object",
              "title": "Version",
              "description": "One version.",
              "additionalProperties": false,
              "required": [
                "version",
                "status",
                "publishedAt"
              ],
              "properties": {
                "version": {
                  "type": "string",
                  "title": "Version",
                  "description": "The version as published.",
                  "examples": [
                    "5"
                  ]
                },
                "status": {
                  "type": "string",
                  "title": "Status",
                  "description": "The version status (draft, tested, published, degraded, retired).",
                  "examples": [
                    "tested"
                  ]
                },
                "publishedAt": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "format": "date-time",
                  "title": "Published at",
                  "description": "When it was published in the catalogue; null when not yet.",
                  "examples": [
                    "2026-10-20T00:00:00Z"
                  ]
                }
              }
            }
          },
          "uses": {
            "type": "array",
            "title": "Uses",
            "description": "For a workflow: the recipes and datasets it uses, with the version used. Empty for other kinds.",
            "items": {
              "type": "object",
              "title": "Use",
              "description": "One entry a workflow uses.",
              "additionalProperties": false,
              "required": [
                "entryId",
                "kind",
                "version"
              ],
              "properties": {
                "entryId": {
                  "type": "string",
                  "title": "Entry",
                  "description": "The entry used.",
                  "examples": [
                    "qc_price_history"
                  ],
                  "pattern": "^[a-z][a-z0-9_]{1,63}$"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "dataset",
                    "recipe",
                    "workflow",
                    "tool"
                  ],
                  "title": "Kind",
                  "description": "Its kind.",
                  "examples": [
                    "dataset"
                  ]
                },
                "version": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "title": "Version",
                  "description": "The version used; null when that entry is not versioned yet.",
                  "examples": [
                    "5"
                  ]
                }
              }
            }
          }
        }
      },
      "CataloguePricing": {
        "type": "object",
        "title": "Catalogue pricing",
        "description": "The price a card or entry shows, from the rate-card rows (C-012). state rate: \"from N credits / unit\", the lowest published rate; the number fields are set only then. quote_first: only rates that are not set yet; the user approves a quote before anything runs. tool_free: a tool, which never carries a price (tools are not charged on their own). not_offered: nothing to run or buy here yet (planned or preview, or read through another entry).",
        "additionalProperties": false,
        "required": [
          "state",
          "credits",
          "perUnits",
          "unit",
          "unitLabel",
          "cardVersion",
          "label"
        ],
        "properties": {
          "state": {
            "type": "string",
            "enum": [
              "rate",
              "quote_first",
              "tool_free",
              "not_offered"
            ],
            "title": "State",
            "description": "Which of the four ways the price is shown.",
            "examples": [
              "rate"
            ]
          },
          "credits": {
            "type": [
              "null",
              "integer"
            ],
            "minimum": 0,
            "title": "Credits",
            "description": "Credits per perUnits units; only with state rate.",
            "examples": [
              1
            ]
          },
          "perUnits": {
            "type": [
              "null",
              "integer"
            ],
            "minimum": 0,
            "title": "Per units",
            "description": "How many units the credits buy; only with state rate.",
            "examples": [
              10
            ]
          },
          "unit": {
            "type": [
              "null",
              "string"
            ],
            "title": "Unit",
            "description": "The rate-card unit key, e.g. history_points or listings; only with state rate.",
            "examples": [
              "history_points"
            ]
          },
          "unitLabel": {
            "type": [
              "null",
              "string"
            ],
            "title": "Unit in words",
            "description": "The unit, plural; only with state rate.",
            "examples": [
              "data points"
            ]
          },
          "cardVersion": {
            "type": [
              "null",
              "integer"
            ],
            "minimum": 0,
            "title": "Rate card",
            "description": "The rate card the rate is from; only with state rate. A published card never changes.",
            "examples": [
              2
            ]
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "What the card shows: \"from 1 credit / 10 data points\", \"quote first\", \"free tool\" or \"not available yet\".",
            "examples": [
              "from 1 credit / 10 data points"
            ]
          }
        }
      },
      "CatalogueCategories": {
        "type": "object",
        "title": "Catalogue categories",
        "description": "Every category, in page order, with its counts.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Categories",
            "description": "In page order.",
            "items": {
              "$ref": "#/components/schemas/CatalogueCategory"
            }
          },
          "meta": {
            "type": "object",
            "title": "Catalogue meta",
            "description": "Where this answer comes from.",
            "additionalProperties": false,
            "required": [
              "servedFrom",
              "asOf"
            ],
            "properties": {
              "servedFrom": {
                "type": "string",
                "enum": [
                  "fixture",
                  "catalogue"
                ],
                "title": "Served from",
                "description": "fixture: the reviewed fixture, until the catalogue tables are read (plan 04 T16-T18). catalogue: the catalogue tables.",
                "examples": [
                  "fixture"
                ]
              },
              "asOf": {
                "type": "string",
                "format": "date-time",
                "title": "As of",
                "description": "When the statuses and figures were last checked.",
                "examples": [
                  "2026-10-15T21:06:00Z"
                ]
              }
            }
          }
        }
      },
      "CatalogueProducts": {
        "type": "object",
        "title": "Catalogue products",
        "description": "Cards matching the filters, by category order then card order.",
        "additionalProperties": false,
        "required": [
          "data",
          "total",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Products",
            "description": "The cards.",
            "items": {
              "$ref": "#/components/schemas/CatalogueProduct"
            }
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "title": "Total",
            "description": "How many cards matched.",
            "examples": [
              5
            ]
          },
          "meta": {
            "type": "object",
            "title": "Catalogue meta",
            "description": "Where this answer comes from.",
            "additionalProperties": false,
            "required": [
              "servedFrom",
              "asOf"
            ],
            "properties": {
              "servedFrom": {
                "type": "string",
                "enum": [
                  "fixture",
                  "catalogue"
                ],
                "title": "Served from",
                "description": "fixture: the reviewed fixture, until the catalogue tables are read (plan 04 T16-T18). catalogue: the catalogue tables.",
                "examples": [
                  "fixture"
                ]
              },
              "asOf": {
                "type": "string",
                "format": "date-time",
                "title": "As of",
                "description": "When the statuses and figures were last checked.",
                "examples": [
                  "2026-10-15T21:06:00Z"
                ]
              }
            }
          }
        }
      },
      "CatalogueEntryAnswer": {
        "type": "object",
        "title": "Catalogue entry answer",
        "description": "One entry in full.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/CatalogueEntry"
          },
          "meta": {
            "type": "object",
            "title": "Catalogue meta",
            "description": "Where this answer comes from.",
            "additionalProperties": false,
            "required": [
              "servedFrom",
              "asOf"
            ],
            "properties": {
              "servedFrom": {
                "type": "string",
                "enum": [
                  "fixture",
                  "catalogue"
                ],
                "title": "Served from",
                "description": "fixture: the reviewed fixture, until the catalogue tables are read (plan 04 T16-T18). catalogue: the catalogue tables.",
                "examples": [
                  "fixture"
                ]
              },
              "asOf": {
                "type": "string",
                "format": "date-time",
                "title": "As of",
                "description": "When the statuses and figures were last checked.",
                "examples": [
                  "2026-10-15T21:06:00Z"
                ]
              }
            }
          }
        }
      },
      "CatalogueSearch": {
        "type": "object",
        "title": "Catalogue search",
        "description": "Matches over names, data types, sources and field names. A pasted URL or SKU also gets an intake answer.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Search answer",
            "description": "What matched, and the intake answer for a URL or SKU.",
            "additionalProperties": false,
            "required": [
              "query",
              "results",
              "intake"
            ],
            "properties": {
              "query": {
                "type": "string",
                "title": "Query",
                "description": "The query as received.",
                "examples": [
                  "zepto price"
                ]
              },
              "results": {
                "type": "array",
                "title": "Results",
                "description": "Categories, cards and entries that match, cards and entries first.",
                "items": {
                  "type": "object",
                  "title": "Result",
                  "description": "One match.",
                  "additionalProperties": false,
                  "required": [
                    "type",
                    "id",
                    "name",
                    "categoryId",
                    "productId",
                    "matchedOn",
                    "matchedText"
                  ],
                  "properties": {
                    "type": {
                      "type": "string",
                      "enum": [
                        "category",
                        "product",
                        "entry"
                      ],
                      "title": "Type",
                      "description": "What matched.",
                      "examples": [
                        "category"
                      ]
                    },
                    "id": {
                      "type": "string",
                      "title": "Id",
                      "description": "Its id.",
                      "examples": [
                        "qc_price_history"
                      ],
                      "pattern": "^[a-z][a-z0-9_]{1,63}$"
                    },
                    "name": {
                      "type": "string",
                      "title": "Name",
                      "description": "Its name.",
                      "examples": [
                        "Price history by pin"
                      ]
                    },
                    "categoryId": {
                      "type": "string",
                      "title": "Category",
                      "description": "Its category.",
                      "examples": [
                        "quick_commerce"
                      ],
                      "pattern": "^[a-z][a-z0-9_]{1,63}$"
                    },
                    "productId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "pattern": "^[a-z][a-z0-9_]{1,63}$",
                      "title": "Product",
                      "description": "Its card (null for a category).",
                      "examples": [
                        "qc_prices_by_pin"
                      ]
                    },
                    "matchedOn": {
                      "type": "string",
                      "enum": [
                        "name",
                        "data_type",
                        "source",
                        "field"
                      ],
                      "title": "Matched on",
                      "description": "What the query matched.",
                      "examples": [
                        "name"
                      ]
                    },
                    "matchedText": {
                      "type": "string",
                      "title": "Matched text",
                      "description": "The text that matched.",
                      "examples": [
                        "Zepto"
                      ]
                    }
                  }
                }
              },
              "intake": {
                "title": "Intake",
                "description": "For a pasted product URL or SKU: whether Rewalto already holds it (plan 04 T7), the same answer as POST /v1/catalogue/intake. null for an ordinary query.",
                "type": [
                  "null",
                  "object"
                ],
                "additionalProperties": false,
                "required": [
                  "input",
                  "held",
                  "message",
                  "retailer",
                  "declaredSku",
                  "linkMethod",
                  "listings"
                ],
                "properties": {
                  "input": {
                    "type": "string",
                    "enum": [
                      "url",
                      "sku"
                    ],
                    "description": "What was pasted."
                  },
                  "held": {
                    "type": "string",
                    "enum": [
                      "yes",
                      "no",
                      "not_checked"
                    ],
                    "description": "yes: Rewalto holds a listing for it; no: it does not; not_checked: this server cannot check (no Library database configured)."
                  },
                  "message": {
                    "type": "string",
                    "description": "What to show."
                  },
                  "retailer": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "description": "The retailer whose site the link is on; null for a bare SKU or a site Rewalto does not collect."
                  },
                  "declaredSku": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "description": "The retailer product id the input declares (read from the link, or the pasted SKU). Kept apart from the canonical product: see listings[].productId."
                  },
                  "linkMethod": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "enum": [
                      "sku_in_url",
                      "listing_url",
                      "sku",
                      null
                    ],
                    "description": "How the input was linked to a held listing: sku_in_url (the link carries the retailer’s product id), listing_url (the link matched the stored product link; for sites whose links carry no id), sku (a pasted product id matched a listing). null when nothing is held."
                  },
                  "listings": {
                    "type": "array",
                    "maxItems": 5,
                    "items": {
                      "$ref": "#/components/schemas/IntakeListing"
                    },
                    "description": "The held listings, at most five (a bare SKU can name one at several retailers)."
                  }
                }
              },
              "askFinder": {
                "$ref": "#/components/schemas/AskFinder"
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Catalogue meta",
            "description": "Where this answer comes from.",
            "additionalProperties": false,
            "required": [
              "servedFrom",
              "asOf"
            ],
            "properties": {
              "servedFrom": {
                "type": "string",
                "enum": [
                  "fixture",
                  "catalogue"
                ],
                "title": "Served from",
                "description": "fixture: the reviewed fixture, until the catalogue tables are read (plan 04 T16-T18). catalogue: the catalogue tables.",
                "examples": [
                  "fixture"
                ]
              },
              "asOf": {
                "type": "string",
                "format": "date-time",
                "title": "As of",
                "description": "When the statuses and figures were last checked.",
                "examples": [
                  "2026-10-15T21:06:00Z"
                ]
              }
            }
          }
        }
      },
      "CatalogueCoverageGrid": {
        "type": "object",
        "title": "Catalogue coverage grid",
        "description": "An entry's coverage per pin code and IST day, holes included.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Coverage grid",
            "description": "The grid of every source the entry draws on.",
            "additionalProperties": false,
            "required": [
              "entryId",
              "groupedBy",
              "days",
              "sources"
            ],
            "properties": {
              "entryId": {
                "type": "string",
                "title": "Entry",
                "description": "The entry.",
                "examples": [
                  "rcp_blinkit"
                ],
                "pattern": "^[a-z][a-z0-9_]{1,63}$"
              },
              "groupedBy": {
                "type": "string",
                "enum": [
                  "pincode"
                ],
                "title": "Grouped by",
                "description": "How rows are grouped. pincode only, until a pin-to-city map exists.",
                "examples": [
                  "pincode"
                ]
              },
              "days": {
                "type": "array",
                "title": "Days",
                "description": "The IST days of the grid, oldest first, ending today.",
                "items": {
                  "type": "string",
                  "title": "Day",
                  "description": "An IST day.",
                  "examples": [
                    "2026-10-15"
                  ]
                }
              },
              "sources": {
                "type": "array",
                "title": "Sources",
                "description": "Every source the entry draws on. Empty for a planned entry, a tool, or one with no measured source.",
                "items": {
                  "type": "object",
                  "title": "Grid source",
                  "description": "One retailer the entry draws on, with its pin-by-day grid.",
                  "additionalProperties": false,
                  "required": [
                    "key",
                    "name",
                    "basis",
                    "coveredShare",
                    "pins"
                  ],
                  "properties": {
                    "key": {
                      "type": "string",
                      "title": "Key",
                      "description": "The retailer key, as in the data API.",
                      "examples": [
                        "blinkit"
                      ],
                      "pattern": "^[a-z][a-z0-9_]{1,63}$"
                    },
                    "name": {
                      "type": "string",
                      "title": "Name",
                      "description": "The retailer name.",
                      "examples": [
                        "Blinkit"
                      ]
                    },
                    "basis": {
                      "type": "string",
                      "enum": [
                        "measured",
                        "estimate",
                        "not_measured"
                      ],
                      "title": "Basis",
                      "description": "measured: counted from data at asOf. estimate: an estimate, and shown as one. not_measured: no figure yet.",
                      "examples": [
                        "measured"
                      ]
                    },
                    "coveredShare": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "minimum": 0,
                      "maximum": 1,
                      "title": "Covered share",
                      "description": "Covered cells over computed cells, 0 to 1. null when no pin is expected.",
                      "examples": [
                        0.93
                      ]
                    },
                    "pins": {
                      "type": "array",
                      "title": "Pins",
                      "description": "Expected pin codes, ascending.",
                      "items": {
                        "type": "object",
                        "title": "Grid pin",
                        "description": "One row of the grid: a pin code.",
                        "additionalProperties": false,
                        "required": [
                          "pincode",
                          "city",
                          "holes",
                          "cells"
                        ],
                        "properties": {
                          "pincode": {
                            "type": "string",
                            "title": "Pin code",
                            "description": "Six-digit Indian pin code.",
                            "examples": [
                              "110092"
                            ],
                            "pattern": "^[1-9][0-9]{5}$"
                          },
                          "city": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "City",
                            "description": "The city of the pin code. Always null for now: rewalto-core holds no pin-to-city map yet.",
                            "examples": [
                              "Delhi"
                            ]
                          },
                          "holes": {
                            "type": "integer",
                            "minimum": 0,
                            "title": "Holes",
                            "description": "Computed days with no readings for this pin.",
                            "examples": [
                              1
                            ]
                          },
                          "cells": {
                            "type": "array",
                            "title": "Cells",
                            "description": "One per day of the grid, oldest first.",
                            "items": {
                              "type": "object",
                              "title": "Grid cell",
                              "description": "One pin code on one IST day.",
                              "additionalProperties": false,
                              "required": [
                                "day",
                                "readings",
                                "computed",
                                "covered"
                              ],
                              "properties": {
                                "day": {
                                  "type": "string",
                                  "title": "Day",
                                  "description": "The IST day, YYYY-MM-DD.",
                                  "examples": [
                                    "2026-10-15"
                                  ],
                                  "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                                },
                                "readings": {
                                  "type": "integer",
                                  "minimum": 0,
                                  "title": "Readings",
                                  "description": "Readings kept for this pin that day.",
                                  "examples": [
                                    412
                                  ]
                                },
                                "computed": {
                                  "type": "boolean",
                                  "title": "Computed",
                                  "description": "Whether coverage was computed for this day. false means unknown, never shown as a hole.",
                                  "examples": [
                                    true
                                  ]
                                },
                                "covered": {
                                  "type": "boolean",
                                  "title": "Covered",
                                  "description": "false for a hole: the pin is expected (read on some day in the grid) but had no readings this day.",
                                  "examples": [
                                    true
                                  ]
                                }
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Catalogue meta",
            "description": "Where this answer comes from.",
            "additionalProperties": false,
            "required": [
              "servedFrom",
              "asOf"
            ],
            "properties": {
              "servedFrom": {
                "type": "string",
                "enum": [
                  "fixture",
                  "catalogue"
                ],
                "title": "Served from",
                "description": "fixture: the reviewed fixture, until the catalogue tables are read (plan 04 T16-T18). catalogue: the catalogue tables.",
                "examples": [
                  "fixture"
                ]
              },
              "asOf": {
                "type": "string",
                "format": "date-time",
                "title": "As of",
                "description": "When the statuses and figures were last checked.",
                "examples": [
                  "2026-10-15T21:06:00Z"
                ]
              }
            }
          }
        }
      },
      "IntakeRequest": {
        "title": "IntakeRequest",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "items"
        ],
        "properties": {
          "items": {
            "type": "array",
            "minItems": 1,
            "maxItems": 25,
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 2000
            },
            "description": "Product links or retailer product ids (SKUs), up to 25. Free text that is neither is refused."
          }
        }
      },
      "IntakeResponse": {
        "title": "IntakeResponse",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "results"
            ],
            "properties": {
              "results": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/IntakeAnswer"
                },
                "description": "One answer per item, in order."
              }
            }
          }
        }
      },
      "IntakeAnswer": {
        "title": "IntakeAnswer",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "query",
          "input",
          "held",
          "message",
          "retailer",
          "declaredSku",
          "linkMethod",
          "listings"
        ],
        "properties": {
          "query": {
            "type": "string",
            "description": "The item as sent."
          },
          "input": {
            "type": "string",
            "enum": [
              "url",
              "sku"
            ],
            "description": "What was pasted."
          },
          "held": {
            "type": "string",
            "enum": [
              "yes",
              "no",
              "not_checked"
            ],
            "description": "yes: Rewalto holds a listing for it; no: it does not; not_checked: this server cannot check (no Library database configured)."
          },
          "message": {
            "type": "string",
            "description": "What to show."
          },
          "retailer": {
            "type": [
              "null",
              "string"
            ],
            "description": "The retailer whose site the link is on; null for a bare SKU or a site Rewalto does not collect."
          },
          "declaredSku": {
            "type": [
              "null",
              "string"
            ],
            "description": "The retailer product id the input declares (read from the link, or the pasted SKU). Kept apart from the canonical product: see listings[].productId."
          },
          "linkMethod": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "sku_in_url",
              "listing_url",
              "sku",
              null
            ],
            "description": "How the input was linked to a held listing: sku_in_url (the link carries the retailer’s product id), listing_url (the link matched the stored product link; for sites whose links carry no id), sku (a pasted product id matched a listing). null when nothing is held."
          },
          "listings": {
            "type": "array",
            "maxItems": 5,
            "items": {
              "$ref": "#/components/schemas/IntakeListing"
            },
            "description": "The held listings, at most five (a bare SKU can name one at several retailers)."
          }
        }
      },
      "IntakeListing": {
        "title": "IntakeListing",
        "description": "A listing Rewalto holds that the input was linked to. Coverage facts only, never its data.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "retailer",
          "retailerSku",
          "firstSeen",
          "lastSeen",
          "observations",
          "productId"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "The listing; read it with GET /v1/data/listings."
          },
          "retailer": {
            "type": "string"
          },
          "retailerSku": {
            "type": "string",
            "description": "The retailer’s own product id for this listing."
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time"
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time"
          },
          "observations": {
            "type": "integer",
            "minimum": 0,
            "description": "Readings kept for it."
          },
          "productId": {
            "type": [
              "null",
              "string"
            ],
            "description": "The canonical product (Rewalto’s cross-retailer product) the listing is linked to, or null when not linked yet. Never the declared SKU: that names this one listing."
          }
        }
      },
      "DataRequestCreate": {
        "title": "DataRequestCreate",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "text",
          "surface"
        ],
        "properties": {
          "text": {
            "type": "string",
            "minLength": 3,
            "maxLength": 1000,
            "description": "What data is missing, in the asker’s words. No contact details: text with an email address or a phone number is refused."
          },
          "query": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000,
            "description": "What found nothing: the catalogue search, or the pasted product link or product id that is not held. Requests are grouped by it."
          },
          "surface": {
            "type": "string",
            "enum": [
              "catalogue_page",
              "search",
              "intake",
              "api",
              "cli",
              "mcp"
            ],
            "description": "Where the request was made."
          }
        }
      },
      "DataRequest": {
        "title": "DataRequest",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "kind",
          "subject",
          "surface",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "missing_data",
              "not_held"
            ],
            "description": "not_held: a pasted product Rewalto does not collect. missing_data: anything else."
          },
          "subject": {
            "type": "string",
            "description": "What it is counted under: retailer:<key>, site:<host>, product:<id> or text:<words>."
          },
          "surface": {
            "type": "string",
            "enum": [
              "catalogue_page",
              "search",
              "intake",
              "api",
              "cli",
              "mcp"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "DataRequestAnswer": {
        "title": "DataRequestAnswer",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "request",
          "message"
        ],
        "properties": {
          "request": {
            "$ref": "#/components/schemas/DataRequest"
          },
          "message": {
            "type": "string",
            "description": "What to show."
          }
        }
      },
      "AskFinder": {
        "title": "AskFinder",
        "type": [
          "null",
          "object"
        ],
        "additionalProperties": false,
        "required": [
          "label",
          "path",
          "prefill"
        ],
        "description": "Shown when the search matched nothing, or a pasted product is not held: the \"Ask the Finder\" link, and the request body to send (POST) when the user confirms. null otherwise.",
        "properties": {
          "label": {
            "type": "string"
          },
          "path": {
            "type": "string",
            "description": "POST here with `prefill` (the user may edit `text`)."
          },
          "prefill": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "text",
              "query",
              "surface"
            ],
            "properties": {
              "text": {
                "type": "string"
              },
              "query": {
                "type": "string"
              },
              "surface": {
                "type": "string",
                "enum": [
                  "catalogue_page",
                  "search",
                  "intake",
                  "api",
                  "cli",
                  "mcp"
                ]
              }
            }
          }
        }
      },
      "AskWaltRequest": {
        "title": "AskWaltRequest",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "question",
          "turnstileToken"
        ],
        "properties": {
          "question": {
            "type": "string",
            "minLength": 1,
            "maxLength": 600,
            "pattern": "\\S",
            "description": "One question about Rewalto, in the visitor’s own words."
          },
          "page": {
            "type": "string",
            "maxLength": 300,
            "description": "The path the question was asked from, e.g. `/pricing`. Optional; it only helps find the right pages."
          },
          "turnstileToken": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "description": "The Cloudflare Turnstile token from the page’s widget. One token answers one question."
          }
        }
      },
      "AskWaltResponse": {
        "title": "AskWaltResponse",
        "oneOf": [
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "status",
              "answer",
              "citations"
            ],
            "properties": {
              "status": {
                "type": "string",
                "const": "answered"
              },
              "answer": {
                "type": "string",
                "description": "Plain text. Every sentence comes from one of the cited pages; lines are separated by `\\n`."
              },
              "citations": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "url",
                    "title"
                  ],
                  "properties": {
                    "url": {
                      "type": "string",
                      "description": "The page on rewalto.com the answer drew from."
                    },
                    "title": {
                      "type": "string"
                    }
                  }
                },
                "minItems": 1
              }
            }
          },
          {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "status",
              "reason"
            ],
            "properties": {
              "status": {
                "type": "string",
                "const": "refused"
              },
              "reason": {
                "type": "string",
                "description": "Why Walt did not answer, in one sentence the page can show as is: off-topic, about a customer’s private data, or nothing published answers it."
              }
            }
          }
        ],
        "examples": [
          {
            "status": "answered",
            "answer": "Every account gets 1,000 free credits a month.",
            "citations": [
              {
                "url": "https://rewalto.com/pricing",
                "title": "Pricing"
              }
            ]
          }
        ]
      },
      "WaltChatRequest": {
        "title": "WaltChatRequest",
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "messages": {
            "type": "array",
            "minItems": 1,
            "maxItems": 40,
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "role",
                "content"
              ],
              "properties": {
                "role": {
                  "type": "string",
                  "enum": [
                    "user",
                    "assistant"
                  ]
                },
                "content": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 4000
                }
              }
            },
            "description": "The conversation so far, oldest first, ending with the user’s new message. Walt keeps no conversation of its own: send the whole thread each time (assistant turns as Walt answered them). Required unless `confirm` is sent."
          },
          "page": {
            "type": "string",
            "pattern": "^[A-Za-z_-]{1,32}(:[A-Za-z0-9_.-]{1,96})?$",
            "description": "The dashboard page the user is on, as `<kind>` or `<kind>:<id>`, e.g. `home`, `brand:colgate`, `listing:blinkit_12345`, `quote:qt_1`: a kind of 1 to 32 letters, `_` or `-`, and an id of 1 to 96 letters, digits, `_`, `.` or `-`. Anything else is refused (`invalid_request`). Context only: it is passed inside the user’s own turn and never widens what Walt may read."
          },
          "confirm": {
            "type": "string",
            "pattern": "^wpa_[A-Za-z0-9_-]{16,64}$",
            "description": "The `pendingAction.id` the user has just approved. Runs that one action with this request’s own credential, then Walt continues the same turn. `messages` is ignored when this is sent."
          },
          "style": {
            "type": "string",
            "enum": [
              "concise",
              "full"
            ],
            "description": "`concise` (default): one to three sentences or up to five `- ` lines with the key numbers only, pointing at the data shown under the answer (`toolCalls[].result`). `full`: a longer answer."
          }
        },
        "examples": [
          {
            "messages": [
              {
                "role": "user",
                "content": "Which retailers do you hold data for?"
              }
            ],
            "page": "home"
          },
          {
            "confirm": "wpa_3Jd9xQ2mT7vK1nB8cR5sYw"
          }
        ]
      },
      "WaltChatResponse": {
        "title": "WaltChatResponse",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status",
          "answer",
          "toolCalls",
          "pendingAction",
          "model"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "answered",
              "needs_confirmation",
              "stopped"
            ],
            "description": "`answered`: Walt’s answer; `needs_confirmation`: an action waits for the user (`pendingAction`); `stopped`: Walt reached its step limit for one turn and says so in `answer`."
          },
          "answer": {
            "type": "string",
            "description": "Plain text for the user; render it as text (never Markdown or HTML). Any web address in it is https on rewalto.com, www.rewalto.com or app.rewalto.com; anything else was replaced with \"[link removed]\". Linkify only those hosts."
          },
          "toolCalls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WaltToolCall"
            },
            "description": "Every tool Walt called in this turn, in order."
          },
          "pendingAction": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/WaltPendingAction"
              }
            ]
          },
          "model": {
            "type": "string",
            "description": "The model that answered, e.g. `gpt-6-sol`."
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WaltSource"
            },
            "description": "The data behind the answer: one per tool call that returned data, numbered from 1 in this order. The answer cites them as `[1]`, `[2]`."
          },
          "followUps": {
            "type": "array",
            "maxItems": 3,
            "items": {
              "type": "string",
              "maxLength": 80
            },
            "description": "Up to 3 short follow-up questions (plain text, at most 80 characters each). Show them as chips; a click sends one as the next user message, never as `confirm`."
          },
          "usage": {
            "$ref": "#/components/schemas/WaltUsage"
          },
          "reported": {
            "type": "boolean",
            "description": "Present (always true) when Walt reported a problem it hit in this turn to the Rewalto team (an internal issue with no customer data in it); the page can show \"Reported to the team\". Absent otherwise."
          }
        },
        "examples": [
          {
            "status": "answered",
            "answer": "Rewalto holds data for Blinkit and Zepto.",
            "toolCalls": [
              {
                "tool": "list_retailers",
                "args": {},
                "status": "ok",
                "summary": "{\"retailers\":[{\"key\":\"blinkit\"},{\"key\":\"zepto\"}]}",
                "creditsCharged": null,
                "error": null
              }
            ],
            "pendingAction": null,
            "model": "gpt-6-sol"
          },
          {
            "status": "needs_confirmation",
            "answer": "Approve a quote: this holds up to 120 credits. Confirm to go ahead.",
            "toolCalls": [
              {
                "tool": "approve_quote",
                "args": {
                  "id": "qt_123",
                  "confirmedCeiling": 120
                },
                "status": "pending",
                "summary": "",
                "creditsCharged": null,
                "error": null
              }
            ],
            "pendingAction": {
              "id": "wpa_3Jd9xQ2mT7vK1nB8cR5sYw",
              "tool": "approve_quote",
              "title": "Approve a quote",
              "effect": "charges",
              "args": {
                "id": "qt_123",
                "confirmedCeiling": 120
              },
              "cost": {
                "kind": "quote_ceiling",
                "credits": 120,
                "text": "Approving holds up to 120 credits; the run is charged for what it delivers, never more."
              },
              "expiresAt": "2026-10-22T10:15:00.000Z"
            },
            "model": "gpt-6-sol"
          }
        ]
      },
      "WaltToolCall": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "tool",
          "args",
          "status",
          "summary",
          "creditsCharged",
          "error"
        ],
        "properties": {
          "tool": {
            "type": "string",
            "description": "The tool name, as the Rewalto MCP connector lists it."
          },
          "args": {
            "type": "object",
            "additionalProperties": true,
            "description": "The arguments, as the tool’s input schema names them."
          },
          "status": {
            "type": "string",
            "enum": [
              "ok",
              "error",
              "pending",
              "not_run"
            ],
            "description": "`ok` ran; `error` the API refused (see `error`); `pending` waits for the user (`pendingAction`); `not_run` was not run (a second action needing approval in the same step: ask again after)."
          },
          "summary": {
            "type": "string",
            "description": "The start of the API’s answer (at most 400 characters of its JSON), for display."
          },
          "creditsCharged": {
            "type": [
              "null",
              "integer"
            ],
            "description": "Credits the API reported charging for this call (`meta.credits.charged`); null when it says none."
          },
          "error": {
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": false,
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          },
          "result": {
            "oneOf": [
              {
                "type": "null"
              },
              {
                "$ref": "#/components/schemas/WaltToolResult"
              }
            ],
            "description": "The call’s answer for display (`status: \"ok\"` only; null otherwise)."
          },
          "resultId": {
            "type": [
              "null",
              "string"
            ],
            "pattern": "^wr_[A-Za-z0-9_-]{32}$",
            "description": "The whole answer, uncut, at `GET /v1/walt/results/{resultId}` (JSON, or `?format=csv`) for 24 hours, to the same user in the same organisation only; no new charge. Null when the call did not run or the answer could not be kept."
          },
          "view": {
            "type": "string",
            "enum": [
              "listings",
              "products",
              "observations",
              "series",
              "catalogue_entries",
              "catalogue_products",
              "brand",
              "retailers",
              "credits",
              "usage",
              "quote",
              "run",
              "run_rows",
              "report",
              "table",
              "none"
            ],
            "description": "How to show `result`: `listings`, `observations`, `catalogue_entries` and so on match the Data page’s views; `table` is a plain table of the rows; `none` needs no data view (e.g. `whoami`)."
          }
        }
      },
      "WaltPendingAction": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "tool",
          "title",
          "effect",
          "args",
          "cost",
          "expiresAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "Send this back as `confirm` to run it."
          },
          "tool": {
            "type": "string"
          },
          "title": {
            "type": "string",
            "description": "What the action does, e.g. \"Approve a quote\"."
          },
          "effect": {
            "type": "string",
            "enum": [
              "charges",
              "creates"
            ],
            "description": "`charges` may spend credits; `creates` writes a record and spends nothing."
          },
          "args": {
            "type": "object",
            "additionalProperties": true,
            "description": "The arguments, as the tool’s input schema names them."
          },
          "cost": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "kind",
              "credits",
              "text"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "quote_ceiling",
                  "published_rate",
                  "settles_run",
                  "no_charge"
                ],
                "description": "`quote_ceiling`: approving holds up to `credits`; `published_rate`: a data read charged at its published rate for what it returns; `settles_run`: may settle a run the user already approved; `no_charge`: creates a record and spends nothing."
              },
              "credits": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "The most it can cost, in credits, when known before running: a quote’s ceiling, or for a `published_rate` read `ceil(most rows / rate.perUnits) * rate.credits` for the arguments as held."
              },
              "text": {
                "type": "string",
                "description": "One sentence the page can show as is."
              },
              "rate": {
                "oneOf": [
                  {
                    "type": "null"
                  },
                  {
                    "$ref": "#/components/schemas/WaltRate"
                  }
                ],
                "description": "`published_rate` only: the rate the read is charged at; null otherwise."
              }
            }
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "After this, confirming answers `not_found`."
          }
        }
      },
      "WaltToolResult": {
        "type": "object",
        "additionalProperties": true,
        "required": [
          "operationId",
          "truncated"
        ],
        "description": "The JSON the REST operation returned, as it returned it (third-party text included: render every field as plain text), plus `operationId` and `truncated`. Display only: it is never sent back to the model. Cut to the first 200 rows and 256 KiB; when cut, `truncated` is true and `rowsKey`, `shownRows` and `totalRows` say which array was cut and by how much (the whole answer is at `GET /v1/walt/results/{resultId}`).",
        "properties": {
          "operationId": {
            "type": "string",
            "description": "The REST operation, e.g. `searchListings`."
          },
          "truncated": {
            "type": "boolean"
          },
          "rowsKey": {
            "type": "string",
            "description": "When cut: the array that was cut, e.g. `data`."
          },
          "shownRows": {
            "type": "integer",
            "minimum": 0,
            "description": "When cut: rows kept here."
          },
          "totalRows": {
            "type": "integer",
            "minimum": 0,
            "description": "When cut: rows the API returned."
          }
        }
      },
      "WaltRate": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "credits",
          "perUnits",
          "unit"
        ],
        "description": "The published rate the read is charged at (the newest rate card holding the unit).",
        "properties": {
          "credits": {
            "type": "integer",
            "minimum": 0,
            "description": "Credits for every `perUnits` units."
          },
          "perUnits": {
            "type": "integer",
            "minimum": 1
          },
          "unit": {
            "type": "string",
            "description": "The rate-card unit, e.g. `listings`."
          }
        }
      },
      "WaltSource": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "toolCall",
          "asOf",
          "label"
        ],
        "properties": {
          "toolCall": {
            "type": "integer",
            "minimum": 0,
            "description": "The index in `toolCalls` of the call the data came from."
          },
          "asOf": {
            "type": "string",
            "format": "date-time",
            "description": "The date of the data: the API’s own `meta.asOf` (or `meta.refreshedAt`) when it gives one, else when Walt read it."
          },
          "label": {
            "type": "string",
            "description": "A short plain-text name for the source."
          }
        }
      },
      "WaltUsage": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "inputTokens",
          "outputTokens",
          "costUsd"
        ],
        "description": "Walt’s own model use in this request (free to you; it counts against Walt’s daily ceiling): input tokens (cached included), output tokens (reasoning included) and their cost in US dollars.",
        "properties": {
          "inputTokens": {
            "type": "integer",
            "minimum": 0
          },
          "outputTokens": {
            "type": "integer",
            "minimum": 0
          },
          "costUsd": {
            "type": "number",
            "minimum": 0
          }
        }
      },
      "WaltStatus": {
        "title": "WaltStatus",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "chat",
          "reason",
          "turnsLeftToday",
          "resetsAt"
        ],
        "properties": {
          "chat": {
            "type": "string",
            "enum": [
              "on",
              "off"
            ],
            "description": "`on`: `POST /v1/walt/chat` answers; `off`: it answers 503 `unavailable`."
          },
          "reason": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "not_switched_on",
              "daily_cap_reached",
              null
            ],
            "description": "Why it is off: `not_switched_on` (not enabled on this API) or `daily_cap_reached` (Walt’s model spend for the day is used up; back at `resetsAt`). Null when on."
          },
          "turnsLeftToday": {
            "type": [
              "null",
              "integer"
            ],
            "minimum": 0,
            "description": "Turns this user has left in the current hour (Walt allows 10 a minute and 120 an hour per user, and has no per-day turn count); 0 when off."
          },
          "resetsAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "When `daily_cap_reached` ends (the next midnight IST); else when the hourly allowance resets. Null when not switched on."
          }
        },
        "examples": [
          {
            "chat": "on",
            "reason": null,
            "turnsLeftToday": 118,
            "resetsAt": "2026-10-22T11:00:00.000Z"
          },
          {
            "chat": "off",
            "reason": "not_switched_on",
            "turnsLeftToday": 0,
            "resetsAt": null
          }
        ]
      },
      "WaltResult": {
        "title": "WaltResult",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "resultId",
          "tool",
          "operationId",
          "view",
          "createdAt",
          "expiresAt",
          "result"
        ],
        "properties": {
          "resultId": {
            "type": "string"
          },
          "tool": {
            "type": "string",
            "description": "The tool Walt called, e.g. `search_listings`."
          },
          "operationId": {
            "type": "string"
          },
          "view": {
            "type": "string",
            "enum": [
              "listings",
              "products",
              "observations",
              "series",
              "catalogue_entries",
              "catalogue_products",
              "brand",
              "retailers",
              "credits",
              "usage",
              "quote",
              "run",
              "run_rows",
              "report",
              "table",
              "none"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "description": "When the call ran."
          },
          "expiresAt": {
            "type": "string",
            "format": "date-time",
            "description": "After this: `not_found`."
          },
          "result": {
            "type": "object",
            "additionalProperties": true,
            "description": "The whole JSON the REST operation returned, uncut. Render it as plain text."
          }
        },
        "examples": [
          {
            "resultId": "wr_Q2x8m0d7Kp3vT9sYb1Nc4Rf6Hj5Lw2Ze",
            "tool": "list_retailers",
            "operationId": "listRetailers",
            "view": "retailers",
            "createdAt": "2026-10-22T10:05:00.000Z",
            "expiresAt": "2026-10-23T10:05:00.000Z",
            "result": {
              "data": [
                {
                  "key": "blinkit"
                },
                {
                  "key": "zepto"
                }
              ]
            }
          }
        ]
      },
      "QueryInterpretRequest": {
        "title": "QueryInterpretRequest",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "text"
        ],
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "pattern": "\\S",
            "description": "What the person typed in the search box. Email addresses and phone numbers in it are removed before it is read and are never stored."
          },
          "turnstileToken": {
            "type": "string",
            "minLength": 1,
            "maxLength": 2048,
            "description": "Anonymous callers only (no Authorization header): the Cloudflare Turnstile token from the page’s widget, as for askWalt. A signed-in session or an API key does not send it."
          }
        }
      },
      "QueryInterpretResponse": {
        "title": "QueryInterpretResponse",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "route",
          "target",
          "fields",
          "unresolved",
          "alternatives"
        ],
        "properties": {
          "route": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "data",
              "fresh",
              "watch",
              "finder",
              "request",
              null
            ],
            "description": "Which feature answers the question; null when there is no reading (see `fallback`): run the text as a plain search."
          },
          "target": {
            "type": [
              "null",
              "string"
            ],
            "description": "The operationId to call with `fields` once the person confirms them; null with `route` null.",
            "examples": [
              "discoverListings"
            ]
          },
          "fields": {
            "title": "QueryInterpretFields",
            "type": "object",
            "additionalProperties": false,
            "description": "The fields for the target endpoint, under its own parameter names. Only fields the text gives (or that are a clear guess) are present.",
            "properties": {
              "q": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value",
                  "source"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "description": "The product words, without the retailer, the place or the time.",
                    "examples": [
                      "Amul butter"
                    ]
                  },
                  "label": {
                    "type": "string",
                    "description": "How to show the value, when it is an id (a location’s place name)."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "stated",
                      "inferred"
                    ],
                    "description": "`stated`: the person typed it. `inferred`: a guess; show it for the person to check."
                  }
                }
              },
              "brand": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value",
                  "source"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "description": "The brand, as typed.",
                    "examples": [
                      "Amul"
                    ]
                  },
                  "label": {
                    "type": "string",
                    "description": "How to show the value, when it is an id (a location’s place name)."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "stated",
                      "inferred"
                    ],
                    "description": "`stated`: the person typed it. `inferred`: a guess; show it for the person to check."
                  }
                }
              },
              "retailer": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value",
                  "source"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "description": "A retailer slug from listRetailers; never any other value.",
                    "examples": [
                      "blinkit"
                    ]
                  },
                  "label": {
                    "type": "string",
                    "description": "How to show the value, when it is an id (a location’s place name)."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "stated",
                      "inferred"
                    ],
                    "description": "`stated`: the person typed it. `inferred`: a guess; show it for the person to check."
                  }
                }
              },
              "pincode": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value",
                  "source"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "description": "A six-digit pin code.",
                    "examples": [
                      "560001"
                    ]
                  },
                  "label": {
                    "type": "string",
                    "description": "How to show the value, when it is an id (a location’s place name)."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "stated",
                      "inferred"
                    ],
                    "description": "`stated`: the person typed it. `inferred`: a guess; show it for the person to check."
                  }
                }
              },
              "location": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value",
                  "source"
                ],
                "properties": {
                  "value": {
                    "type": "string",
                    "description": "A Core location id (a city or an area), as getLocationFilter takes it; `label` names the place.",
                    "examples": [
                      "IN:city:maharashtra:pune"
                    ]
                  },
                  "label": {
                    "type": "string",
                    "description": "How to show the value, when it is an id (a location’s place name)."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "stated",
                      "inferred"
                    ],
                    "description": "`stated`: the person typed it. `inferred`: a guess; show it for the person to check."
                  }
                }
              },
              "items": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value",
                  "source"
                ],
                "properties": {
                  "value": {
                    "type": "array",
                    "minItems": 1,
                    "maxItems": 25,
                    "items": {
                      "type": "string"
                    },
                    "description": "Product links or retailer product ids, for checkIntake."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "stated",
                      "inferred"
                    ],
                    "description": "`stated`: the person typed it. `inferred`: a guess; show it for the person to check."
                  }
                }
              },
              "frequency": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "value",
                  "source"
                ],
                "properties": {
                  "value": {
                    "type": "object",
                    "title": "Frequency",
                    "description": "How often a watch refreshes, in Asia/Kolkata: daily at a time, weekly on a weekday at a time, or monthly on a day (1 to 28) at a time. A search has none.",
                    "additionalProperties": false,
                    "required": [
                      "kind",
                      "time"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "enum": [
                          "daily",
                          "weekly",
                          "monthly"
                        ],
                        "title": "Kind",
                        "description": "daily, weekly or monthly.",
                        "examples": [
                          "daily"
                        ]
                      },
                      "time": {
                        "type": "string",
                        "title": "Time",
                        "description": "HH:MM, 24-hour, Asia/Kolkata.",
                        "examples": [
                          "07:30"
                        ],
                        "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                      },
                      "weekday": {
                        "type": "string",
                        "enum": [
                          "monday",
                          "tuesday",
                          "wednesday",
                          "thursday",
                          "friday",
                          "saturday",
                          "sunday"
                        ],
                        "title": "Weekday",
                        "description": "For weekly.",
                        "examples": [
                          "monday"
                        ]
                      },
                      "dayOfMonth": {
                        "type": "integer",
                        "title": "Day of month",
                        "description": "For monthly, 1 to 28.",
                        "examples": [
                          1
                        ],
                        "minimum": 1,
                        "maximum": 28
                      }
                    }
                  },
                  "label": {
                    "type": "string",
                    "description": "How to show it, e.g. \"Weekly, Monday, 09:00 (time assumed)\"."
                  },
                  "source": {
                    "type": "string",
                    "enum": [
                      "stated",
                      "inferred"
                    ],
                    "description": "`stated`: the person typed it. `inferred`: a guess; show it for the person to check."
                  }
                }
              }
            }
          },
          "unresolved": {
            "type": "array",
            "description": "What could not be mapped (an unknown retailer, an ambiguous place, a second retailer when the request takes one: `one_retailer_only`). Ask the person about these; never guess.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "field",
                "text",
                "reason"
              ],
              "properties": {
                "field": {
                  "type": "string",
                  "enum": [
                    "retailer",
                    "location"
                  ]
                },
                "text": {
                  "type": "string",
                  "description": "What was typed."
                },
                "reason": {
                  "type": "string",
                  "enum": [
                    "unknown_retailer",
                    "ambiguous_place",
                    "unknown_place",
                    "one_retailer_only"
                  ]
                },
                "options": {
                  "type": "array",
                  "maxItems": 5,
                  "description": "For an ambiguous place: the places it could be.",
                  "items": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "value",
                      "label"
                    ],
                    "properties": {
                      "value": {
                        "type": "string"
                      },
                      "label": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "alternatives": {
            "type": "array",
            "maxItems": 2,
            "description": "At most two other readings, only when the route is unclear.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "route",
                "why"
              ],
              "properties": {
                "route": {
                  "type": "string",
                  "enum": [
                    "data",
                    "fresh",
                    "watch",
                    "finder",
                    "request"
                  ]
                },
                "why": {
                  "type": "string"
                }
              }
            }
          },
          "fallback": {
            "type": "string",
            "enum": [
              "unavailable",
              "cap_reached",
              "model_failed",
              "unsure"
            ],
            "description": "Only with `route` null: unavailable (switched off), cap_reached (the day’s model budget is spent), model_failed (no usable answer in time) or unsure."
          },
          "interpretationId": {
            "type": "string",
            "format": "uuid",
            "description": "This reading’s id (since 0.70.0; sent with every answer, `route` null or not). Opaque: keep it to refer to this reading later. Absent from older servers, so treat it as optional.",
            "examples": [
              "5b0d6a52-3c1e-4a8e-9f61-2f0a7c9d4e10"
            ]
          }
        },
        "examples": [
          {
            "route": "data",
            "target": "discoverListings",
            "fields": {
              "q": {
                "value": "Amul butter",
                "source": "stated"
              },
              "retailer": {
                "value": "blinkit",
                "source": "stated"
              },
              "location": {
                "value": "IN:city:maharashtra:pune",
                "label": "Pune",
                "source": "stated"
              }
            },
            "unresolved": [],
            "alternatives": [
              {
                "route": "fresh",
                "why": "Latest prices straight from the app, at the published rate"
              }
            ]
          }
        ]
      },
      "FinderDemand": {
        "title": "FinderDemand",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "days",
          "total",
          "top",
          "recent"
        ],
        "properties": {
          "days": {
            "type": "integer",
            "minimum": 1
          },
          "total": {
            "type": "integer",
            "minimum": 0,
            "description": "Requests in the window."
          },
          "top": {
            "type": "array",
            "description": "The most-asked subjects in the window, most requests first: demand for plan 21.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "subject",
                "requests",
                "organisations",
                "anonymous",
                "firstAt",
                "lastAt",
                "examples"
              ],
              "properties": {
                "subject": {
                  "type": "string"
                },
                "requests": {
                  "type": "integer",
                  "minimum": 1
                },
                "organisations": {
                  "type": "integer",
                  "minimum": 0,
                  "description": "Distinct signed-in organisations that asked."
                },
                "anonymous": {
                  "type": "integer",
                  "minimum": 0
                },
                "firstAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "lastAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "examples": {
                  "type": "array",
                  "maxItems": 3,
                  "items": {
                    "type": "string"
                  },
                  "description": "Up to three of the latest texts."
                }
              }
            }
          },
          "recent": {
            "type": "array",
            "description": "The latest requests, newest first.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "id",
                "kind",
                "text",
                "query",
                "subject",
                "surface",
                "requester",
                "orgId",
                "createdAt"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid"
                },
                "kind": {
                  "type": "string",
                  "enum": [
                    "missing_data",
                    "not_held"
                  ]
                },
                "text": {
                  "type": "string"
                },
                "query": {
                  "type": [
                    "null",
                    "string"
                  ]
                },
                "subject": {
                  "type": "string"
                },
                "surface": {
                  "type": "string",
                  "enum": [
                    "catalogue_page",
                    "search",
                    "intake",
                    "api",
                    "cli",
                    "mcp"
                  ]
                },
                "requester": {
                  "type": "string",
                  "enum": [
                    "anonymous",
                    "session",
                    "api_key"
                  ]
                },
                "orgId": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "format": "uuid"
                },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                }
              }
            }
          }
        }
      },
      "Retailer": {
        "type": "object",
        "title": "Retailer",
        "description": "A retailer Rewalto tracks.",
        "additionalProperties": false,
        "required": [
          "slug",
          "name",
          "kind",
          "market"
        ],
        "properties": {
          "slug": {
            "type": "string",
            "title": "Retailer key",
            "description": "The key used in the retailer filter and on every record.",
            "examples": [
              "blinkit"
            ]
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "Display name.",
            "examples": [
              "Blinkit"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "marketplace",
              "quick_commerce",
              "direct",
              "aggregator"
            ],
            "title": "Kind",
            "description": "What sort of retailer.",
            "examples": [
              "quick_commerce"
            ]
          },
          "market": {
            "type": "string",
            "title": "Market",
            "description": "ISO 3166-1 country code of the market.",
            "examples": [
              "IN"
            ]
          }
        }
      },
      "Brand": {
        "type": "object",
        "title": "Brand",
        "description": "A brand profile with its marks: logo and favicon addresses from its own site or store page, never the files (C-010, D-1362).",
        "additionalProperties": false,
        "required": [
          "name",
          "category",
          "website",
          "logoUrl",
          "faviconUrl"
        ],
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "The brand name.",
            "examples": [
              "Amul"
            ]
          },
          "category": {
            "type": [
              "null",
              "string"
            ],
            "title": "Category",
            "description": "What the brand mainly sells.",
            "examples": [
              "Dairy"
            ]
          },
          "website": {
            "type": [
              "null",
              "string"
            ],
            "title": "Website",
            "description": "The brand own site.",
            "examples": [
              "https://amul.com"
            ]
          },
          "logoUrl": {
            "type": [
              "null",
              "string"
            ],
            "title": "Logo URL",
            "description": "The logo address.",
            "examples": [
              "https://amul.com/images/logo.png"
            ]
          },
          "faviconUrl": {
            "type": [
              "null",
              "string"
            ],
            "title": "Favicon URL",
            "description": "The site icon address.",
            "examples": [
              "https://amul.com/favicon.ico"
            ]
          }
        }
      },
      "Listing": {
        "type": "object",
        "title": "Listing",
        "description": "One product as one retailer lists it, with when it was first and last seen.",
        "additionalProperties": false,
        "required": [
          "id",
          "retailer",
          "retailerSku",
          "images",
          "firstSeen",
          "lastSeen",
          "observations"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Listing id",
            "description": "Stable identifier of the listing.",
            "examples": [
              "7c1e5f0a-2f55-4d2b-8c36-0f3f1d9c2b77"
            ]
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer key.",
            "examples": [
              "nykaa"
            ]
          },
          "retailerSku": {
            "type": "string",
            "title": "Retailer product id",
            "description": "The retailer own product identifier.",
            "examples": [
              "1234567"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ],
            "title": "Title",
            "description": "The product title as the retailer showed it.",
            "examples": [
              "Maybelline Superstay Matte Ink"
            ]
          },
          "brand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Brand",
            "description": "The brand as the retailer attributed it.",
            "examples": [
              "Maybelline"
            ]
          },
          "packSizeRaw": {
            "type": [
              "null",
              "string"
            ],
            "title": "Pack size",
            "description": "The pack size exactly as printed.",
            "examples": [
              "5 ml"
            ]
          },
          "imageUrl": {
            "type": [
              "null",
              "string"
            ],
            "title": "Image URL",
            "description": "The primary product image address (not the image itself): the first of images.",
            "examples": [
              "https://images.example/lipstick-1.jpg"
            ]
          },
          "images": {
            "type": "array",
            "title": "Images",
            "description": "Every image address the source showed, in its order, primary first. Empty when it showed none.",
            "items": {
              "$ref": "#/components/schemas/ListingImage"
            }
          },
          "url": {
            "type": [
              "null",
              "string"
            ],
            "title": "Product page",
            "description": "The retailer product page.",
            "examples": [
              "https://www.nykaa.com/p/1234567"
            ]
          },
          "productId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "title": "Product id",
            "description": "The matched Rewalto product, when matched.",
            "examples": [
              "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
            ]
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "title": "First seen",
            "description": "When the listing was first observed.",
            "examples": [
              "2026-08-27T08:00:00Z"
            ]
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "Last seen",
            "description": "When the listing was last observed.",
            "examples": [
              "2026-10-14T09:00:00Z"
            ]
          },
          "observations": {
            "type": "integer",
            "title": "Observation count",
            "description": "How many times the listing has been observed.",
            "examples": [
              37
            ]
          },
          "brandTag": {
            "type": [
              "null",
              "object"
            ],
            "title": "Model brand tag",
            "description": "Rewalto's model reading of the brand from the title (plan 13 T8), given only when the retailer attributed no brand. It never replaces brand. Null when the title is not tagged yet.",
            "additionalProperties": false,
            "required": [
              "brand",
              "confidence",
              "method",
              "promptVersion",
              "taggedAt",
              "accuracy"
            ],
            "properties": {
              "brand": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Brand",
                "description": "The brand span chosen from the title; null when the title names none or the model was below the minimum confidence (never a guess).",
                "examples": [
                  "Bazana"
                ]
              },
              "confidence": {
                "type": [
                  "null",
                  "number"
                ],
                "minimum": 0,
                "maximum": 1,
                "title": "Confidence",
                "description": "The model's own confidence, 0 to 1; a brand is kept only at 0.75 or above.",
                "examples": [
                  0.87
                ]
              },
              "method": {
                "type": "string",
                "enum": [
                  "model"
                ],
                "title": "Method",
                "description": "Always model: read by a language model, not the retailer.",
                "examples": [
                  "model"
                ]
              },
              "promptVersion": {
                "type": "string",
                "title": "Prompt version",
                "description": "The tagging prompt that produced it.",
                "examples": [
                  "core-brand-v1"
                ]
              },
              "taggedAt": {
                "type": "string",
                "format": "date-time",
                "title": "Tagged at",
                "description": "When the title was tagged.",
                "examples": [
                  "2026-10-16T11:40:20Z"
                ]
              },
              "accuracy": {
                "type": "string",
                "enum": [
                  "not_measured",
                  "measured"
                ],
                "title": "Accuracy",
                "description": "Whether this tag kind has been measured against hand-checked titles. not_measured: no accuracy figure yet; treat the tag as unverified.",
                "examples": [
                  "not_measured"
                ]
              }
            }
          },
          "categoryTag": {
            "type": [
              "null",
              "object"
            ],
            "title": "Model category tag",
            "description": "Rewalto's model reading of the GS1 GPC segment and family from the title (D-1498). Null when the title is not tagged yet.",
            "additionalProperties": false,
            "required": [
              "status",
              "standard",
              "gpcVersion",
              "segment",
              "family",
              "method",
              "promptVersion",
              "taggedAt",
              "accuracy"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "classified",
                  "segment_only",
                  "unclassified"
                ],
                "title": "Status",
                "description": "classified: segment and family chosen; segment_only: a segment without a family; unclassified: no GPC entry chosen (never a guess).",
                "examples": [
                  "classified"
                ]
              },
              "standard": {
                "type": "string",
                "enum": [
                  "GS1 GPC"
                ],
                "title": "Standard",
                "description": "The classification: GS1 Global Product Classification.",
                "examples": [
                  "GS1 GPC"
                ]
              },
              "gpcVersion": {
                "type": "string",
                "title": "GPC version",
                "description": "The GS1 GPC publication used.",
                "examples": [
                  "20260520"
                ]
              },
              "segment": {
                "type": [
                  "null",
                  "object"
                ],
                "title": "GS1 GPC entry",
                "description": "A GS1 Global Product Classification code and its English title; null when not chosen.",
                "additionalProperties": false,
                "required": [
                  "code",
                  "title"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "title": "Code",
                    "description": "The eight-digit GS1 GPC code.",
                    "examples": [
                      "50000000"
                    ]
                  },
                  "title": {
                    "type": "string",
                    "title": "Title",
                    "description": "The GS1 GPC English title.",
                    "examples": [
                      "Food/Beverage"
                    ]
                  }
                }
              },
              "family": {
                "type": [
                  "null",
                  "object"
                ],
                "title": "GS1 GPC entry",
                "description": "A GS1 Global Product Classification code and its English title; null when not chosen.",
                "additionalProperties": false,
                "required": [
                  "code",
                  "title"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "title": "Code",
                    "description": "The eight-digit GS1 GPC code.",
                    "examples": [
                      "50000000"
                    ]
                  },
                  "title": {
                    "type": "string",
                    "title": "Title",
                    "description": "The GS1 GPC English title.",
                    "examples": [
                      "Food/Beverage"
                    ]
                  }
                }
              },
              "method": {
                "type": "string",
                "enum": [
                  "model"
                ],
                "title": "Method",
                "description": "Always model: read by a language model, not the retailer.",
                "examples": [
                  "model"
                ]
              },
              "promptVersion": {
                "type": "string",
                "title": "Prompt version",
                "description": "The tagging prompt that produced it.",
                "examples": [
                  "core-category-gpc-v1"
                ]
              },
              "taggedAt": {
                "type": "string",
                "format": "date-time",
                "title": "Tagged at",
                "description": "When the title was tagged.",
                "examples": [
                  "2026-10-17T00:10:00Z"
                ]
              },
              "accuracy": {
                "type": "string",
                "enum": [
                  "not_measured",
                  "measured"
                ],
                "title": "Accuracy",
                "description": "Whether this tag kind has been measured against hand-checked titles. not_measured: no accuracy figure yet; treat the tag as unverified.",
                "examples": [
                  "not_measured"
                ]
              }
            }
          },
          "similarity": {
            "type": "number",
            "minimum": -1,
            "maximum": 1,
            "title": "Similarity",
            "description": "Listing search with mode=semantic only: the cosine similarity of the listing and the query embeddings (OpenAI text-embedding-3-small, 512 dimensions), -1 to 1, higher is closer in meaning, to 6 decimal places. Absent everywhere else.",
            "examples": [
              0.71234
            ]
          },
          "match": {
            "type": "object",
            "title": "Search match",
            "description": "How this listing matched the search, only on search results. kind: exact_id (the query is the retailer product id), phrase (the name holds the words in order, next to each other), words (every word, spread out), brand (only the brand the query names), near (an approximate match, a likely misspelling). wholeWords of queryWords are whole words of the listing (\"butter\" in \"Amul Butter\", not in \"Buttermilk\"); allWords is true when every word is. When any listing holds every word as a whole word, the search returns only such listings.",
            "additionalProperties": false,
            "required": [
              "kind",
              "wholeWords",
              "queryWords",
              "allWords"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "exact_id",
                  "phrase",
                  "words",
                  "brand",
                  "near"
                ],
                "title": "Kind",
                "description": "How the listing matched.",
                "examples": [
                  "phrase"
                ]
              },
              "wholeWords": {
                "type": "integer",
                "title": "Whole words",
                "description": "How many words of the query are whole words of the listing.",
                "examples": [
                  2
                ]
              },
              "queryWords": {
                "type": "integer",
                "title": "Query words",
                "description": "How many words the query has (at most 8).",
                "examples": [
                  2
                ]
              },
              "allWords": {
                "type": "boolean",
                "title": "All words whole",
                "description": "Every word of the query is a whole word of the listing.",
                "examples": [
                  true
                ]
              }
            }
          },
          "latest": {
            "type": "object",
            "title": "Newest price reading",
            "description": "The listing's newest kept reading in the last 30 days, at the pin code asked for, else at any pin. Never a guess.",
            "additionalProperties": false,
            "required": [
              "state",
              "priceMinor",
              "mrpMinor",
              "currency",
              "inStock",
              "pincode",
              "observedAt"
            ],
            "properties": {
              "state": {
                "type": "string",
                "enum": [
                  "priced",
                  "no_price_shown",
                  "no_recent_reading",
                  "excluded_pin_day"
                ],
                "title": "State",
                "description": "priced: the reading shows a price. no_price_shown: the newest reading had none. no_recent_reading: no kept reading in the last 30 days (at the pin, when one was asked for). excluded_pin_day: the newest reading falls on a pin-day left out of the data (D-1458), so nothing is shown.",
                "examples": [
                  "priced"
                ]
              },
              "priceMinor": {
                "type": [
                  "null",
                  "integer"
                ],
                "title": "Price",
                "description": "Selling price in paise; null when not shown.",
                "examples": [
                  5600
                ]
              },
              "mrpMinor": {
                "type": [
                  "null",
                  "integer"
                ],
                "title": "MRP",
                "description": "MRP in paise; null when not shown.",
                "examples": [
                  6000
                ]
              },
              "currency": {
                "const": "INR",
                "title": "Currency",
                "description": "Always INR.",
                "examples": [
                  "INR"
                ]
              },
              "inStock": {
                "type": [
                  "null",
                  "boolean"
                ],
                "title": "In stock",
                "description": "In stock in that reading; null when the retailer does not say (always null for Flipkart).",
                "examples": [
                  true
                ]
              },
              "pincode": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Pin code",
                "description": "Where the reading was taken.",
                "examples": [
                  "110092"
                ]
              },
              "observedAt": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "Read at",
                "description": "When the reading was taken; null when there is none.",
                "examples": [
                  "2026-10-20T05:55:00Z"
                ]
              }
            }
          }
        }
      },
      "ListingImage": {
        "type": "object",
        "title": "Image",
        "description": "One image address as the source showed it, never the image itself (C-010). Position 0 is the primary image.",
        "additionalProperties": false,
        "required": [
          "url",
          "position",
          "source",
          "firstSeen",
          "lastSeen"
        ],
        "properties": {
          "url": {
            "type": "string",
            "title": "Image URL",
            "description": "The image address.",
            "examples": [
              "https://images.example/lipstick-1.jpg"
            ],
            "format": "uri"
          },
          "position": {
            "type": "integer",
            "title": "Position",
            "description": "0 is the primary image; then the order the source shows them in.",
            "examples": [
              0
            ],
            "minimum": 0
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "Where the address was read: a retailer key or a site domain.",
            "examples": [
              "nykaa"
            ]
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "title": "First seen",
            "description": "When the address was first seen at this position.",
            "examples": [
              "2026-08-27T08:00:00Z"
            ]
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "Last seen",
            "description": "When the address was last seen at this position.",
            "examples": [
              "2026-10-14T09:00:00Z"
            ]
          },
          "sha256": {
            "type": "string",
            "title": "Image SHA-256",
            "description": "SHA-256 of the image bytes, 64 lowercase hex; present only when Rewalto has read them.",
            "examples": [
              "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
            ],
            "pattern": "^[0-9a-f]{64}$"
          }
        }
      },
      "Observation": {
        "type": "object",
        "title": "Observation",
        "description": "One reading of one product on one retailer, for one pin code, at one time: price, MRP and availability as the retailer showed them. Never a ranking, and never a stock claim for Flipkart.",
        "additionalProperties": false,
        "required": [
          "id",
          "retailer",
          "retailerSku",
          "pincode",
          "observedAt",
          "ingestedAt",
          "currency",
          "source",
          "evidence"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "title": "Observation id",
            "description": "Stable identifier of this reading; cite it when disputing a value.",
            "examples": [
              48210377
            ]
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer key, as listed by /v1/data/retailers.",
            "examples": [
              "blinkit"
            ]
          },
          "retailerSku": {
            "type": "string",
            "title": "Retailer product id",
            "description": "The retailer's own product identifier. Unique within one retailer only.",
            "examples": [
              "prd-88213"
            ]
          },
          "pincode": {
            "type": "string",
            "title": "Pin code",
            "description": "The Indian pin code the page was read for, or national when the page is not pin-scoped.",
            "examples": [
              "110092"
            ]
          },
          "observedAt": {
            "type": "string",
            "format": "date-time",
            "title": "Observed at",
            "description": "When the retailer's page was read.",
            "examples": [
              "2026-10-14T09:27:00Z"
            ]
          },
          "ingestedAt": {
            "type": "string",
            "format": "date-time",
            "title": "Ingested at",
            "description": "When the reading entered Rewalto's store.",
            "examples": [
              "2026-10-14T10:40:00Z"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ],
            "title": "Title",
            "description": "The product title as the retailer showed it.",
            "examples": [
              "Aashirvaad Atta 5 kg"
            ]
          },
          "brand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Brand",
            "description": "The brand as the retailer attributed it; often absent or wrong.",
            "examples": [
              "Aashirvaad"
            ]
          },
          "packSizeRaw": {
            "type": [
              "null",
              "string"
            ],
            "title": "Pack size",
            "description": "The pack size exactly as printed, unparsed.",
            "examples": [
              "5 kg"
            ]
          },
          "priceMinor": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Selling price (paise)",
            "description": "Selling price in paise; null when it could not be read, never 0 for unknown.",
            "examples": [
              28500
            ]
          },
          "mrpMinor": {
            "type": [
              "null",
              "integer"
            ],
            "title": "MRP (paise)",
            "description": "Maximum retail price in paise; null when the retailer published none.",
            "examples": [
              31000
            ]
          },
          "currency": {
            "type": "string",
            "enum": [
              "INR"
            ],
            "title": "Currency",
            "description": "ISO 4217 code of the amounts.",
            "examples": [
              "INR"
            ]
          },
          "inStock": {
            "type": [
              "null",
              "boolean"
            ],
            "title": "In stock",
            "description": "Availability as the page showed it; null when the page carried no signal. Always null for Flipkart.",
            "examples": [
              true
            ]
          },
          "category": {
            "type": [
              "null",
              "string"
            ],
            "title": "Category",
            "description": "The retailer's own category, not normalised across retailers.",
            "examples": [
              "atta-rice-dal"
            ]
          },
          "productId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "title": "Product id",
            "description": "The matched Rewalto product, when the listing is matched to one.",
            "examples": [
              "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
            ]
          },
          "sourceUrl": {
            "type": [
              "null",
              "string"
            ],
            "title": "Source URL",
            "description": "The page this reading was taken from.",
            "examples": [
              "https://blinkit.com/prn/aashirvaad-atta/prid/88213"
            ]
          },
          "recipeVersion": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Recipe version",
            "description": "Version of the extraction recipe that produced the reading.",
            "examples": [
              5
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "harvest"
            ],
            "title": "Source",
            "description": "Always harvest: Rewalto's own collection.",
            "examples": [
              "harvest"
            ]
          },
          "evidence": {
            "$ref": "#/components/schemas/Evidence"
          }
        }
      },
      "Evidence": {
        "type": "object",
        "title": "Evidence",
        "description": "Proof of where the record came from: the SHA-256 of the fetched response. The response itself is not kept; the hash, the source URL and the time are.",
        "additionalProperties": false,
        "required": [
          "sha256",
          "missing"
        ],
        "properties": {
          "sha256": {
            "type": [
              "null",
              "string"
            ],
            "title": "Response SHA-256",
            "description": "64 lowercase hex characters; null when no fingerprint was kept.",
            "examples": [
              "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08"
            ]
          },
          "missing": {
            "type": "boolean",
            "title": "Fingerprint missing",
            "description": "True when the response was not kept; the record still names its source URL and time.",
            "examples": [
              false
            ]
          }
        }
      },
      "ReadCredits": {
        "type": "object",
        "title": "Credits",
        "description": "What this response cost, at the published rate. An empty page, a free re-read of identical data and a plain list cost nothing.",
        "additionalProperties": false,
        "required": [
          "charged",
          "units",
          "freeReread",
          "rate"
        ],
        "properties": {
          "charged": {
            "type": "integer",
            "title": "Credits charged",
            "description": "Credits taken from the balance for this response.",
            "examples": [
              10
            ],
            "minimum": 0
          },
          "units": {
            "type": "integer",
            "title": "Records delivered",
            "description": "How many records are in data.",
            "examples": [
              100
            ],
            "minimum": 0
          },
          "freeReread": {
            "type": "boolean",
            "title": "Free re-read",
            "description": "True when identical data was read within 7 days and is not charged again.",
            "examples": [
              false
            ]
          },
          "rate": {
            "type": [
              "null",
              "object"
            ],
            "title": "Published rate",
            "description": "Credits per number of records, and the rate version; null when nothing is charged for this list.",
            "additionalProperties": false,
            "required": [
              "credits",
              "perUnits",
              "version"
            ],
            "properties": {
              "credits": {
                "type": "integer",
                "title": "Credits",
                "description": "Credits charged for every perUnits records.",
                "examples": [
                  1
                ]
              },
              "perUnits": {
                "type": "integer",
                "title": "Per units",
                "description": "Number of records the credits cover.",
                "examples": [
                  10
                ]
              },
              "version": {
                "type": "string",
                "title": "Rate version",
                "description": "The rate card the price came from.",
                "examples": [
                  "card-1"
                ]
              }
            }
          },
          "receiptId": {
            "type": "string",
            "title": "Receipt",
            "pattern": "^rcp_[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
            "description": "The receipt of a charged read; POST /v1/credits/refunds can refund it. Absent when nothing was charged.",
            "examples": [
              "rcp_5c2e8a91-4b7d-4f36-9e10-8a2b3c4d5e6f"
            ]
          }
        }
      },
      "RetailersPage": {
        "type": "object",
        "title": "Retailers",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/Retailer"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and that this list is free.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "BrandsPage": {
        "type": "object",
        "title": "Brands",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/Brand"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and that this list is free.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "ListingsPage": {
        "type": "object",
        "title": "Listings page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/Listing"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "ObservationsPage": {
        "type": "object",
        "title": "Observations page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/Observation"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "BrandMentionDay": {
        "type": "object",
        "title": "BrandMentionDay",
        "description": "Public videos that mention a brand on one IST day of publishing, and their summed public counts when last read. Observed counts, never a model.",
        "additionalProperties": false,
        "required": [
          "platform",
          "brand",
          "day",
          "videos",
          "atLeast",
          "views",
          "likes",
          "comments",
          "readAt"
        ],
        "properties": {
          "platform": {
            "type": "string",
            "enum": [
              "youtube"
            ],
            "title": "Platform",
            "examples": [
              "youtube"
            ]
          },
          "brand": {
            "type": "string",
            "title": "Brand",
            "description": "The brand searched for.",
            "examples": [
              "Mamaearth"
            ]
          },
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The IST day the videos were published.",
            "examples": [
              "2026-10-16"
            ]
          },
          "videos": {
            "type": "integer",
            "title": "Videos",
            "description": "Public videos published in India that day for the brand.",
            "examples": [
              12
            ],
            "minimum": 0
          },
          "atLeast": {
            "type": "boolean",
            "title": "At least",
            "description": "True when the 50-video page was full, so the real number is higher.",
            "examples": [
              false
            ]
          },
          "views": {
            "type": "integer",
            "title": "Views",
            "description": "Public view counts, summed.",
            "examples": [
              48210
            ],
            "minimum": 0
          },
          "likes": {
            "type": "integer",
            "title": "Likes",
            "description": "Public like counts, summed.",
            "examples": [
              1530
            ],
            "minimum": 0
          },
          "comments": {
            "type": "integer",
            "title": "Comments",
            "description": "Public comment counts, summed.",
            "examples": [
              212
            ],
            "minimum": 0
          },
          "readAt": {
            "type": "string",
            "format": "date-time",
            "title": "Read at",
            "description": "When the counts were read.",
            "examples": [
              "2026-10-17T03:10:00Z"
            ]
          }
        }
      },
      "RatingChange": {
        "type": "object",
        "title": "RatingChange",
        "description": "A listing’s rating, rating count and review count on an IST day when one of them changed, at one pin code (or national), from that day’s newest reading.",
        "additionalProperties": false,
        "required": [
          "retailer",
          "retailerSku",
          "pincode",
          "day",
          "rating",
          "ratingCount",
          "reviewCount",
          "observationId",
          "observedAt"
        ],
        "properties": {
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer.",
            "examples": [
              "nykaa"
            ]
          },
          "retailerSku": {
            "type": "string",
            "title": "Retailer SKU",
            "description": "The retailer's own product id.",
            "examples": [
              "1234567"
            ]
          },
          "pincode": {
            "type": "string",
            "title": "Pin code",
            "description": "The pin code, or national.",
            "examples": [
              "national"
            ]
          },
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The IST day of the change.",
            "examples": [
              "2026-10-16"
            ]
          },
          "rating": {
            "type": [
              "null",
              "number"
            ],
            "title": "Rating",
            "description": "The rating out of 5, to two decimals; null when the page showed none.",
            "examples": [
              4.21
            ]
          },
          "ratingCount": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Rating count",
            "description": "How many ratings.",
            "examples": [
              1834
            ]
          },
          "reviewCount": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Review count",
            "description": "How many written reviews.",
            "examples": [
              402
            ]
          },
          "observationId": {
            "type": "string",
            "title": "Observation",
            "description": "The kept reading the values come from (its source, fetch time, SHA-256 and the exact text read).",
            "examples": [
              "48210377"
            ]
          },
          "observedAt": {
            "type": "string",
            "format": "date-time",
            "title": "Observed at",
            "description": "When it was read.",
            "examples": [
              "2026-10-16T09:12:00Z"
            ]
          }
        }
      },
      "BannerPlacement": {
        "type": "object",
        "title": "BannerPlacement",
        "description": "One banner ad creative shown on one search term at one pin code on one IST day, as observed in quick-commerce search replies. The creative is a fingerprint; the image or video is never kept.",
        "additionalProperties": false,
        "required": [
          "day",
          "retailer",
          "searchTerm",
          "pincode",
          "unitKind",
          "brand",
          "advertiserRef",
          "billing",
          "matchType",
          "keyword",
          "mediaKind",
          "replies",
          "stores",
          "bestSlot",
          "productRefs",
          "creativeSha256",
          "firstSeen",
          "lastSeen"
        ],
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The IST day it was seen.",
            "examples": [
              "2026-10-16"
            ]
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The app: zepto or instamart.",
            "examples": [
              "zepto"
            ]
          },
          "searchTerm": {
            "type": "string",
            "title": "Search term",
            "description": "The search it was shown on.",
            "examples": [
              "anti dandruff shampoo"
            ]
          },
          "pincode": {
            "type": [
              "null",
              "string"
            ],
            "title": "Pin code",
            "description": "The pin code; null when not tied to one.",
            "examples": [
              "560034"
            ]
          },
          "unitKind": {
            "type": "string",
            "enum": [
              "sponsored_brands",
              "inline_banner"
            ],
            "title": "Unit kind",
            "description": "sponsored_brands (Zepto’s brand banner) or inline_banner (Instamart’s).",
            "examples": [
              "sponsored_brands"
            ]
          },
          "brand": {
            "type": "string",
            "title": "Brand",
            "description": "The brand advertised, as the app names it; empty when not named.",
            "examples": [
              "Head & Shoulders"
            ]
          },
          "advertiserRef": {
            "type": [
              "null",
              "string"
            ],
            "title": "Advertiser reference",
            "description": "The app’s own advertiser or campaign reference, when present.",
            "examples": [
              "ad-1234"
            ]
          },
          "billing": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "CPM",
              "CPC",
              "CPA",
              "CPT",
              null
            ],
            "title": "Billing",
            "description": "The billing model the app states.",
            "examples": [
              "CPM"
            ]
          },
          "matchType": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "EXACT",
              "PHRASE",
              "BROAD",
              null
            ],
            "title": "Match type",
            "description": "How the bought keyword matches.",
            "examples": [
              "EXACT"
            ]
          },
          "keyword": {
            "type": [
              "null",
              "string"
            ],
            "title": "Keyword",
            "description": "The keyword the brand bought, when stated.",
            "examples": [
              "anti dandruff shampoo"
            ]
          },
          "mediaKind": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "image",
              "video",
              null
            ],
            "title": "Media",
            "description": "image or video.",
            "examples": [
              "video"
            ]
          },
          "replies": {
            "type": "integer",
            "title": "Replies",
            "description": "Search replies that carried it that day.",
            "examples": [
              6
            ],
            "minimum": 1
          },
          "stores": {
            "type": "integer",
            "title": "Stores",
            "description": "Dark stores it was seen in.",
            "examples": [
              2
            ],
            "minimum": 0
          },
          "bestSlot": {
            "type": "integer",
            "title": "Best slot",
            "description": "Its highest position on the page (0 is the top).",
            "examples": [
              0
            ],
            "minimum": 0
          },
          "productRefs": {
            "type": "array",
            "title": "Products",
            "description": "The retailer product ids the banner links to (up to 20).",
            "maxItems": 20,
            "items": {
              "type": "string"
            },
            "examples": [
              [
                "12345",
                "67890"
              ]
            ]
          },
          "creativeSha256": {
            "type": "string",
            "title": "Creative fingerprint",
            "description": "SHA-256 of the banner’s image or video.",
            "examples": [
              "a3f1000000000000000000000000000000000000000000000000000000000000"
            ],
            "pattern": "^[0-9a-f]{64}$"
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "title": "First seen",
            "description": "First seen that day.",
            "examples": [
              "2026-10-16T04:02:00Z"
            ]
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "Last seen",
            "description": "Last seen that day.",
            "examples": [
              "2026-10-16T15:47:00Z"
            ]
          }
        }
      },
      "StorefrontPromoDay": {
        "type": "object",
        "title": "StorefrontPromoDay",
        "description": "A watched D2C store on one IST day: how many product variants were on sale, how deep the discounts were, and what changed since the last read.",
        "additionalProperties": false,
        "required": [
          "domain",
          "brand",
          "day",
          "variantsSeen",
          "variantsOnSale",
          "medianDiscountBp",
          "maxDiscountBp",
          "wentOnSale",
          "saleEnded",
          "priceCuts",
          "discountDeeper",
          "firstSeen",
          "lastSeen"
        ],
        "properties": {
          "domain": {
            "type": "string",
            "title": "Store",
            "description": "The brand’s store.",
            "examples": [
              "mamaearth.in"
            ]
          },
          "brand": {
            "type": "string",
            "title": "Brand",
            "description": "The brand.",
            "examples": [
              "Mamaearth"
            ]
          },
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The IST day of the read.",
            "examples": [
              "2026-10-16"
            ]
          },
          "variantsSeen": {
            "type": "integer",
            "title": "Variants",
            "description": "Product variants on the store that day.",
            "examples": [
              214
            ],
            "minimum": 1
          },
          "variantsOnSale": {
            "type": "integer",
            "title": "On sale",
            "description": "Variants with a struck-through price.",
            "examples": [
              61
            ],
            "minimum": 0
          },
          "medianDiscountBp": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Median discount",
            "description": "Median discount of the variants on sale, in basis points (1500 = 15%).",
            "examples": [
              2000
            ]
          },
          "maxDiscountBp": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Deepest discount",
            "description": "In basis points.",
            "examples": [
              4500
            ]
          },
          "wentOnSale": {
            "type": "integer",
            "title": "Went on sale",
            "description": "Variants that went on sale since the last read.",
            "examples": [
              38
            ],
            "minimum": 0
          },
          "saleEnded": {
            "type": "integer",
            "title": "Sale ended",
            "description": "Variants whose sale ended.",
            "examples": [
              2
            ],
            "minimum": 0
          },
          "priceCuts": {
            "type": "integer",
            "title": "Price cuts",
            "description": "Variants whose price was cut.",
            "examples": [
              5
            ],
            "minimum": 0
          },
          "discountDeeper": {
            "type": "integer",
            "title": "Deeper discounts",
            "description": "Variants whose discount got deeper.",
            "examples": [
              11
            ],
            "minimum": 0
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "title": "First seen",
            "description": "The first reading that day.",
            "examples": [
              "2026-10-16T05:30:00Z"
            ]
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "Last seen",
            "description": "The last reading that day.",
            "examples": [
              "2026-10-16T05:31:00Z"
            ]
          }
        }
      },
      "PromoEmail": {
        "type": "object",
        "title": "PromoEmail",
        "description": "One promotion a brand emailed to subscribers, as recorded by Rewalto: the offer, its dates, the public discount code if any, and the brand’s page it links to. Never the email itself.",
        "additionalProperties": false,
        "required": [
          "sendDate",
          "brand",
          "brandAsWritten",
          "company",
          "offer",
          "discountCode",
          "saleStart",
          "saleEnd",
          "link"
        ],
        "properties": {
          "sendDate": {
            "type": "string",
            "format": "date",
            "title": "Sent",
            "description": "The day the email was sent.",
            "examples": [
              "2026-10-16"
            ]
          },
          "brand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Brand",
            "description": "The brand, matched to a canonical brand; null when not matched yet.",
            "examples": [
              "The Derma Co"
            ]
          },
          "brandAsWritten": {
            "type": "string",
            "title": "Brand as written",
            "description": "The brand as the email names it.",
            "examples": [
              "The Derma Co."
            ]
          },
          "company": {
            "type": [
              "null",
              "string"
            ],
            "title": "Company",
            "description": "The company that owns the brand, when known.",
            "examples": [
              "Honasa Consumer Ltd"
            ]
          },
          "offer": {
            "type": "string",
            "title": "Offer",
            "description": "The offer in a sentence.",
            "examples": [
              "Festive sale: up to 40% off sitewide"
            ]
          },
          "discountCode": {
            "type": [
              "null",
              "string"
            ],
            "title": "Discount code",
            "description": "The public discount code, if the email gives one.",
            "examples": [
              "FESTIVE40"
            ]
          },
          "saleStart": {
            "type": [
              "null",
              "string"
            ],
            "format": "date",
            "title": "Sale starts",
            "description": "When the sale starts, if stated.",
            "examples": [
              "2026-10-17"
            ]
          },
          "saleEnd": {
            "type": [
              "null",
              "string"
            ],
            "format": "date",
            "title": "Sale ends",
            "description": "When it ends, if stated.",
            "examples": [
              "2026-10-20"
            ]
          },
          "link": {
            "type": [
              "null",
              "string"
            ],
            "title": "Link",
            "description": "The brand’s public page the email links to.",
            "examples": [
              "https://example.com/festive-sale"
            ]
          }
        }
      },
      "BrandMentionsPage": {
        "type": "object",
        "title": "Brand mentions page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/BrandMentionDay"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "RatingChangesPage": {
        "type": "object",
        "title": "Rating changes page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/RatingChange"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "BannerPlacementsPage": {
        "type": "object",
        "title": "Banner placements page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/BannerPlacement"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "StorefrontPromosPage": {
        "type": "object",
        "title": "Storefront promos page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/StorefrontPromoDay"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "PromoEmailsPage": {
        "type": "object",
        "title": "Promo emails page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/PromoEmail"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "AdCreative": {
        "type": "object",
        "title": "AdCreative",
        "description": "One ad creative a watched advertiser ran in India, as Google’s Ads Transparency Center lists it, read weekly: the advertiser and creative ids, the format, the first and last day it was shown, and a SHA-256 fingerprint. Never the ad’s text, image, video or landing page; the link opens the creative on the centre itself.",
        "additionalProperties": false,
        "required": [
          "day",
          "brand",
          "advertiserRef",
          "advertiserName",
          "readVia",
          "website",
          "creativeRef",
          "format",
          "firstShown",
          "lastShown",
          "firstReadWeek",
          "lastReadWeek",
          "creativeSha256",
          "link",
          "firstSeen",
          "lastSeen"
        ],
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The day it was last shown in India; when the centre states no date, the Monday (IST) of the latest weekly read that listed it. The order and the from and to filters use this day.",
            "examples": [
              "2026-10-16"
            ]
          },
          "brand": {
            "type": "string",
            "title": "Brand",
            "description": "The watched brand the advertiser or website belongs to.",
            "examples": [
              "Mamaearth (Honasa Consumer)"
            ]
          },
          "advertiserRef": {
            "type": "string",
            "title": "Advertiser id",
            "description": "The centre’s advertiser id.",
            "examples": [
              "AR17979653942044262401"
            ],
            "pattern": "^AR[0-9]{20}$"
          },
          "advertiserName": {
            "type": [
              "null",
              "string"
            ],
            "title": "Advertiser",
            "description": "The name the centre registers for the advertiser account; null when the creative was found through the brand’s website (often an agency placing it).",
            "examples": [
              "HONASA CONSUMER LIMITED"
            ]
          },
          "readVia": {
            "type": "string",
            "enum": [
              "advertiser",
              "website"
            ],
            "title": "Read via",
            "description": "advertiser (the brand’s own confirmed account) or website (the centre’s filter by the brand’s website, which also finds ads agencies place for it).",
            "examples": [
              "advertiser"
            ]
          },
          "website": {
            "type": [
              "null",
              "string"
            ],
            "title": "Website",
            "description": "The brand website the creative was found through, for readVia website.",
            "examples": [
              "godrejcp.com"
            ]
          },
          "creativeRef": {
            "type": "string",
            "title": "Creative id",
            "description": "The centre’s creative id.",
            "examples": [
              "CR01234567890123456789"
            ],
            "pattern": "^CR[0-9]{20}$"
          },
          "format": {
            "type": "string",
            "enum": [
              "text",
              "image",
              "video",
              "unknown"
            ],
            "title": "Format",
            "description": "text, image or video, inferred from the centre’s format code; unknown when it gives none.",
            "examples": [
              "video"
            ]
          },
          "firstShown": {
            "type": [
              "null",
              "string"
            ],
            "format": "date",
            "title": "First shown",
            "description": "The first day the centre says it was shown.",
            "examples": [
              "2026-10-12"
            ]
          },
          "lastShown": {
            "type": [
              "null",
              "string"
            ],
            "format": "date",
            "title": "Last shown",
            "description": "The last day the centre says it was shown.",
            "examples": [
              "2026-10-16"
            ]
          },
          "firstReadWeek": {
            "type": "string",
            "format": "date",
            "title": "First read week",
            "description": "The Monday (IST) of the first weekly read that listed it.",
            "examples": [
              "2026-10-12"
            ]
          },
          "lastReadWeek": {
            "type": "string",
            "format": "date",
            "title": "Last read week",
            "description": "The Monday (IST) of the latest weekly read that listed it.",
            "examples": [
              "2026-10-12"
            ]
          },
          "creativeSha256": {
            "type": "string",
            "title": "Creative fingerprint",
            "description": "SHA-256 of the centre’s listing of the creative, to tell creatives apart; never the creative itself.",
            "examples": [
              "b7c2000000000000000000000000000000000000000000000000000000000000"
            ],
            "pattern": "^[0-9a-f]{64}$"
          },
          "link": {
            "type": "string",
            "title": "Link",
            "description": "The creative’s public page on the Ads Transparency Center (India).",
            "examples": [
              "https://adstransparency.google.com/advertiser/AR17979653942044262401/creative/CR01234567890123456789?region=IN"
            ]
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "title": "First seen",
            "description": "When Rewalto first read it.",
            "examples": [
              "2026-10-14T09:12:00Z"
            ]
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "Last seen",
            "description": "When Rewalto last read it.",
            "examples": [
              "2026-10-14T09:12:00Z"
            ]
          }
        }
      },
      "AdCreativesPage": {
        "type": "object",
        "title": "Ad creatives page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/AdCreative"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "Storefront": {
        "type": "object",
        "title": "Storefront",
        "description": "One online store in Rewalto’s storefront index: the platform that runs it and how sure Rewalto is, its market, when Rewalto first and last read it, and how many products and variants Rewalto holds from its catalogue.",
        "additionalProperties": false,
        "required": [
          "host",
          "platform",
          "platformConfidence",
          "market",
          "firstCrawledAt",
          "lastCrawledAt",
          "lastReadOkAt",
          "catalogueProducts",
          "catalogueVariants"
        ],
        "properties": {
          "host": {
            "type": "string",
            "title": "Store",
            "description": "The store’s host name.",
            "examples": [
              "www.mamaearth.in"
            ],
            "pattern": "^[a-z0-9][a-z0-9.-]{1,252}$"
          },
          "platform": {
            "type": "string",
            "title": "Platform",
            "description": "The commerce platform that runs the store (for example shopify, woocommerce, magento, fynd, unicommerce).",
            "examples": [
              "shopify"
            ]
          },
          "platformConfidence": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "title": "Platform confidence",
            "description": "How sure Rewalto is of the platform, 0 to 1, from the evidence the store served.",
            "examples": [
              0.98
            ]
          },
          "market": {
            "type": "string",
            "title": "Market",
            "description": "The store’s market, an ISO 3166 country code.",
            "examples": [
              "IN"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "firstCrawledAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "title": "First read",
            "description": "When Rewalto first read the store; null if not yet.",
            "examples": [
              "2026-09-02T10:15:00Z"
            ]
          },
          "lastCrawledAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "title": "Last read",
            "description": "When Rewalto last tried to read the store; null if not yet.",
            "examples": [
              "2026-10-21T14:55:47Z"
            ]
          },
          "lastReadOkAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "title": "Last good read",
            "description": "When a read of the store last succeeded; null if never.",
            "examples": [
              "2026-10-21T14:55:47Z"
            ]
          },
          "catalogueProducts": {
            "type": "integer",
            "title": "Products",
            "description": "Products Rewalto holds from the store’s catalogue.",
            "examples": [
              214
            ],
            "minimum": 0
          },
          "catalogueVariants": {
            "type": "integer",
            "title": "Variants",
            "description": "Product variants Rewalto holds from the store’s catalogue.",
            "examples": [
              388
            ],
            "minimum": 0
          }
        }
      },
      "StorefrontsPage": {
        "type": "object",
        "title": "Storefronts page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/Storefront"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "SponsoredShareCell": {
        "type": "object",
        "title": "SponsoredShareCell",
        "description": "The search slots one brand held for one search term at one pin code on one IST day, how many were marked sponsored, and its share of all the sponsored slots of that term, pin and day. A slot is one product card in one search reply Rewalto read; ad counts are only kept from replies whose reading can see the retailer’s ad marker (adAwareSlots), so a reply that cannot see ads never reads as \"no ads\".",
        "additionalProperties": false,
        "required": [
          "day",
          "retailer",
          "searchTerm",
          "pincode",
          "brand",
          "slots",
          "adAwareSlots",
          "sponsoredSlots",
          "organicSlots",
          "top10AdAwareSlots",
          "top10SponsoredSlots",
          "termAdAwareSlots",
          "termSponsoredSlots",
          "sponsoredRate",
          "shareOfSponsored",
          "pages",
          "firstSeen",
          "lastSeen"
        ],
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The IST day.",
            "examples": [
              "2026-10-21"
            ]
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer.",
            "examples": [
              "blinkit"
            ]
          },
          "searchTerm": {
            "type": "string",
            "title": "Search term",
            "description": "The search term.",
            "examples": [
              "shampoo"
            ]
          },
          "pincode": {
            "type": "string",
            "title": "Pin code",
            "description": "The six-digit pin code searched at.",
            "examples": [
              "560034"
            ]
          },
          "brand": {
            "type": "string",
            "title": "Brand",
            "description": "The brand on the card, as the retailer wrote it; empty when the card named none.",
            "examples": [
              "Dove"
            ]
          },
          "slots": {
            "type": "integer",
            "minimum": 0,
            "title": "Slots",
            "description": "Product cards of this brand in the replies read.",
            "examples": [
              24
            ]
          },
          "adAwareSlots": {
            "type": "integer",
            "minimum": 0,
            "title": "Ad-aware slots",
            "description": "Of those, cards from a reading that can see the ad marker.",
            "examples": [
              24
            ]
          },
          "sponsoredSlots": {
            "type": "integer",
            "minimum": 0,
            "title": "Sponsored slots",
            "description": "Of the ad-aware cards, those marked sponsored.",
            "examples": [
              6
            ]
          },
          "organicSlots": {
            "type": "integer",
            "minimum": 0,
            "title": "Organic slots",
            "description": "Of the ad-aware cards, those the retailer itself states are organic (Tata 1mg only); 0 elsewhere.",
            "examples": [
              0
            ]
          },
          "top10AdAwareSlots": {
            "type": "integer",
            "minimum": 0,
            "title": "Top-10 ad-aware slots",
            "description": "Ad-aware cards in places 1 to 10 of a reply page.",
            "examples": [
              8
            ]
          },
          "top10SponsoredSlots": {
            "type": "integer",
            "minimum": 0,
            "title": "Top-10 sponsored slots",
            "description": "Sponsored cards in places 1 to 10 of a reply page.",
            "examples": [
              3
            ]
          },
          "termAdAwareSlots": {
            "type": "integer",
            "minimum": 0,
            "title": "Term ad-aware slots",
            "description": "Ad-aware cards of every brand for this term, pin and day.",
            "examples": [
              410
            ]
          },
          "termSponsoredSlots": {
            "type": "integer",
            "minimum": 0,
            "title": "Term sponsored slots",
            "description": "Sponsored cards of every brand for this term, pin and day.",
            "examples": [
              52
            ]
          },
          "sponsoredRate": {
            "type": [
              "null",
              "number"
            ],
            "minimum": 0,
            "maximum": 1,
            "title": "Sponsored rate",
            "description": "sponsoredSlots / adAwareSlots: how much of this brand’s shelf was bought; null when no card was ad-aware.",
            "examples": [
              0.25
            ]
          },
          "shareOfSponsored": {
            "type": [
              "null",
              "number"
            ],
            "minimum": 0,
            "maximum": 1,
            "title": "Share of sponsored",
            "description": "sponsoredSlots / termSponsoredSlots: this brand’s share of the bought slots of the term, pin and day; null when the term had no sponsored card.",
            "examples": [
              0.1154
            ]
          },
          "pages": {
            "type": "integer",
            "minimum": 0,
            "title": "Pages",
            "description": "Reply pages that carried this brand.",
            "examples": [
              4
            ]
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "title": "First seen",
            "description": "The first reading that day.",
            "examples": [
              "2026-10-21T02:31:10.000000Z"
            ]
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "Last seen",
            "description": "The last reading that day.",
            "examples": [
              "2026-10-21T14:02:44.000000Z"
            ]
          }
        }
      },
      "SponsoredSharePage": {
        "type": "object",
        "title": "Sponsored share page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/SponsoredShareCell"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "SearchRank": {
        "type": "object",
        "title": "SearchRank",
        "description": "Where one listing ranked for one search term at one pin code (or national) on one IST day, from every search reply Rewalto read that day. bestPlace is its best position in the whole result list, ads included; it is known only where the reply states where its page starts (a first page, or Blinkit’s offset), else null, and bestPage and bestPageSlot still say where it was seen.",
        "additionalProperties": false,
        "required": [
          "day",
          "retailer",
          "searchTerm",
          "pincode",
          "retailerSku",
          "brand",
          "bestPlace",
          "bestPage",
          "bestPageSlot",
          "readings",
          "top10Readings",
          "adAwareReadings",
          "sponsoredReadings",
          "firstSeen",
          "lastSeen"
        ],
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The IST day.",
            "examples": [
              "2026-10-21"
            ]
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer.",
            "examples": [
              "flipkart"
            ]
          },
          "searchTerm": {
            "type": "string",
            "title": "Search term",
            "description": "The search term.",
            "examples": [
              "instant coffee"
            ]
          },
          "pincode": {
            "type": "string",
            "title": "Pin code",
            "description": "The pin code searched at, or national.",
            "examples": [
              "national"
            ]
          },
          "retailerSku": {
            "type": "string",
            "title": "Retailer product id",
            "description": "The retailer’s own product id.",
            "examples": [
              "COFG5Z7H2ZQ8YH5K"
            ]
          },
          "brand": {
            "type": "string",
            "title": "Brand",
            "description": "The brand on the card; empty when it named none.",
            "examples": [
              "Nescafe"
            ]
          },
          "bestPlace": {
            "type": [
              "null",
              "integer"
            ],
            "minimum": 1,
            "title": "Best place",
            "description": "Best position in the whole result list that day (1 is first).",
            "examples": [
              3
            ]
          },
          "bestPage": {
            "type": "integer",
            "minimum": 0,
            "title": "Best page",
            "description": "The first result page it was seen on (1 is the first page).",
            "examples": [
              1
            ]
          },
          "bestPageSlot": {
            "type": "integer",
            "minimum": 0,
            "title": "Slot on that page",
            "description": "Its best position on that page, ads included.",
            "examples": [
              3
            ]
          },
          "readings": {
            "type": "integer",
            "minimum": 0,
            "title": "Readings",
            "description": "Search replies that showed it that day.",
            "examples": [
              4
            ]
          },
          "top10Readings": {
            "type": "integer",
            "minimum": 0,
            "title": "Top-10 readings",
            "description": "Of those, replies that placed it in places 1 to 10.",
            "examples": [
              4
            ]
          },
          "adAwareReadings": {
            "type": "integer",
            "minimum": 0,
            "title": "Ad-aware readings",
            "description": "Replies from a reading that can see the ad marker.",
            "examples": [
              4
            ]
          },
          "sponsoredReadings": {
            "type": "integer",
            "minimum": 0,
            "title": "Sponsored readings",
            "description": "Of the ad-aware replies, those that marked it sponsored.",
            "examples": [
              0
            ]
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "title": "First seen",
            "description": "The first reading that day.",
            "examples": [
              "2026-10-21T02:31:10.000000Z"
            ]
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "Last seen",
            "description": "The last reading that day.",
            "examples": [
              "2026-10-21T14:02:44.000000Z"
            ]
          }
        }
      },
      "SearchRanksPage": {
        "type": "object",
        "title": "Search ranks page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/SearchRank"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "ShareOfSearch": {
        "type": "object",
        "title": "ShareOfSearch",
        "description": "One brand’s share of the first ten places of one search term at one pin code (or national) on one IST day: its readings in places 1 to 10 over every brand’s, organic and sponsored together, from every search reply Rewalto read that day whose page start is known.",
        "additionalProperties": false,
        "required": [
          "day",
          "retailer",
          "searchTerm",
          "pincode",
          "brand",
          "listings",
          "top10Listings",
          "top10Readings",
          "top10SponsoredReadings",
          "termTop10Readings",
          "shareOfSearch",
          "sponsoredShareOfTop10",
          "firstSeen",
          "lastSeen"
        ],
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The IST day.",
            "examples": [
              "2026-10-21"
            ]
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer.",
            "examples": [
              "blinkit"
            ]
          },
          "searchTerm": {
            "type": "string",
            "title": "Search term",
            "description": "The search term.",
            "examples": [
              "shampoo"
            ]
          },
          "pincode": {
            "type": "string",
            "title": "Pin code",
            "description": "The pin code searched at, or national.",
            "examples": [
              "560034"
            ]
          },
          "brand": {
            "type": "string",
            "title": "Brand",
            "description": "The brand on the card; empty when it named none.",
            "examples": [
              "Dove"
            ]
          },
          "listings": {
            "type": "integer",
            "minimum": 0,
            "title": "Listings",
            "description": "Listings of this brand seen for the term that day.",
            "examples": [
              6
            ]
          },
          "top10Listings": {
            "type": "integer",
            "minimum": 0,
            "title": "Top-10 listings",
            "description": "Of those, seen at least once in places 1 to 10.",
            "examples": [
              2
            ]
          },
          "top10Readings": {
            "type": "integer",
            "minimum": 0,
            "title": "Top-10 readings",
            "description": "This brand’s cards in places 1 to 10, over every reply read.",
            "examples": [
              8
            ]
          },
          "top10SponsoredReadings": {
            "type": "integer",
            "minimum": 0,
            "title": "Top-10 sponsored readings",
            "description": "Of those, marked sponsored (only where the reading can see the ad marker).",
            "examples": [
              2
            ]
          },
          "termTop10Readings": {
            "type": "integer",
            "minimum": 0,
            "title": "Term top-10 readings",
            "description": "Every brand’s cards in places 1 to 10 for the term, pin and day.",
            "examples": [
              40
            ]
          },
          "shareOfSearch": {
            "type": [
              "null",
              "number"
            ],
            "minimum": 0,
            "maximum": 1,
            "title": "Share of search",
            "description": "top10Readings / termTop10Readings; null when no reply of the term had a known page start.",
            "examples": [
              0.2
            ]
          },
          "sponsoredShareOfTop10": {
            "type": [
              "null",
              "number"
            ],
            "minimum": 0,
            "maximum": 1,
            "title": "Sponsored part",
            "description": "top10SponsoredReadings / top10Readings: how much of the brand’s top-10 presence was bought; null when it had none.",
            "examples": [
              0.25
            ]
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "title": "First seen",
            "description": "The first reading that day.",
            "examples": [
              "2026-10-21T02:31:10.000000Z"
            ]
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "Last seen",
            "description": "The last reading that day.",
            "examples": [
              "2026-10-21T14:02:44.000000Z"
            ]
          }
        }
      },
      "ShareOfSearchPage": {
        "type": "object",
        "title": "Share of search page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/ShareOfSearch"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "RegulatoryNotice": {
        "type": "object",
        "title": "RegulatoryNotice",
        "description": "One public notice an Indian regulator lists on its own site (CDSCO public notices, FSSAI notifications): its title, the release day the regulator states, and the links to its documents. The documents themselves are not kept; the links open them on the regulator’s site.",
        "additionalProperties": false,
        "required": [
          "authority",
          "noticeRef",
          "title",
          "publishedOn",
          "documentUrl",
          "documentSize",
          "category",
          "commentsUrl",
          "extraDocuments",
          "recordedAt"
        ],
        "properties": {
          "authority": {
            "type": "string",
            "enum": [
              "cdsco",
              "fssai"
            ],
            "title": "Regulator",
            "description": "cdsco (Central Drugs Standard Control Organisation) or fssai (Food Safety and Standards Authority of India).",
            "examples": [
              "cdsco"
            ]
          },
          "noticeRef": {
            "type": "string",
            "title": "Notice ref",
            "description": "The notice’s reference: CDSCO’s own document number; for FSSAI, which names no id, n- and a fingerprint of its date, document and title. Stable across reads.",
            "examples": [
              "14763"
            ]
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "The notice’s title as the regulator lists it.",
            "examples": [
              "Clarification regarding requirement of Export NOC for already approved r-DNA products."
            ]
          },
          "publishedOn": {
            "type": [
              "null",
              "string"
            ],
            "format": "date",
            "title": "Published on",
            "description": "The release day the regulator states; null when it states none. The order and the from and to filters use this day.",
            "examples": [
              "2026-10-14"
            ]
          },
          "documentUrl": {
            "type": [
              "null",
              "string"
            ],
            "format": "uri",
            "title": "Document",
            "description": "The notice’s document (usually a PDF) on the regulator’s site; null when it links none.",
            "examples": [
              "https://cdsco.gov.in/opencms/opencms/system/modules/CDSCO.WEB/elements/download_file_division.jsp?num_id=MTQ3NjM="
            ]
          },
          "documentSize": {
            "type": [
              "null",
              "string"
            ],
            "title": "Document size",
            "description": "The document size as the regulator writes it.",
            "examples": [
              "101 KB"
            ]
          },
          "category": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "sps",
              "tbt",
              "notice",
              "draft",
              "gazette",
              "ordinary",
              null
            ],
            "title": "Category",
            "description": "FSSAI’s own filter for the notification: sps or tbt (WTO notifications), notice, draft, gazette or ordinary; null for CDSCO.",
            "examples": [
              "draft"
            ]
          },
          "commentsUrl": {
            "type": [
              "null",
              "string"
            ],
            "format": "uri",
            "title": "Comments link",
            "description": "Where the regulator takes public comments on the notice, when it links one.",
            "examples": [
              "https://comments.fssai.gov.in/Bestviewwl.aspx?NOTIFICATION_ID=5998"
            ]
          },
          "extraDocuments": {
            "type": "array",
            "title": "Further documents",
            "description": "Further documents the notice links, for example the format for comments.",
            "examples": [
              [
                {
                  "label": "Format for sending the comments and suggestions",
                  "url": "https://www.fssai.gov.in/docs/food-law/notice-comment/Format.pdf"
                }
              ]
            ],
            "items": {
              "type": "object",
              "title": "Further document",
              "description": "One further document and its label.",
              "additionalProperties": false,
              "required": [
                "label",
                "url"
              ],
              "properties": {
                "label": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "title": "Label",
                  "description": "The regulator’s label for it.",
                  "examples": [
                    "Format for sending the comments and suggestions"
                  ]
                },
                "url": {
                  "type": "string",
                  "title": "Link",
                  "description": "The document on the regulator’s site.",
                  "examples": [
                    "https://www.fssai.gov.in/docs/food-law/notice-comment/Format.pdf"
                  ],
                  "format": "uri"
                }
              }
            }
          },
          "recordedAt": {
            "type": "string",
            "format": "date-time",
            "title": "Recorded at",
            "description": "When Rewalto recorded this version of the notice (a notice the regulator changes gets a new version).",
            "examples": [
              "2026-10-27T09:31:00Z"
            ]
          }
        }
      },
      "RegulatoryNoticesPage": {
        "type": "object",
        "title": "Regulatory notices page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/RegulatoryNotice"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "StorefrontProduct": {
        "type": "object",
        "title": "StorefrontProduct",
        "description": "One product variant on a D2C store’s own catalogue, as Rewalto last read it: names, brand, SKU and barcode, price and struck-through price in minor units (paise for INR), whether it was in stock, tags and image addresses, and when Rewalto first and last saw it.",
        "additionalProperties": false,
        "required": [
          "host",
          "productId",
          "variantId",
          "handle",
          "title",
          "variantTitle",
          "brand",
          "sku",
          "barcode",
          "priceMinor",
          "compareAtMinor",
          "currency",
          "available",
          "tags",
          "images",
          "publishedAt",
          "firstSeen",
          "lastSeen",
          "missedReads"
        ],
        "properties": {
          "host": {
            "type": "string",
            "title": "Store",
            "description": "The store’s host name.",
            "examples": [
              "www.mamaearth.in"
            ],
            "pattern": "^[a-z0-9][a-z0-9.-]{1,252}$"
          },
          "productId": {
            "type": "string",
            "title": "Product id",
            "description": "The store’s own product id.",
            "examples": [
              "7781230412345"
            ]
          },
          "variantId": {
            "type": "string",
            "title": "Variant id",
            "description": "The store’s own variant id.",
            "examples": [
              "43012345678901"
            ]
          },
          "handle": {
            "type": [
              "null",
              "string"
            ],
            "title": "Handle",
            "description": "The product’s URL handle on the store.",
            "examples": [
              "onion-hair-oil"
            ]
          },
          "title": {
            "type": "string",
            "title": "Name",
            "description": "The product name as the store shows it.",
            "examples": [
              "Onion Hair Oil"
            ]
          },
          "variantTitle": {
            "type": [
              "null",
              "string"
            ],
            "title": "Variant",
            "description": "The variant name (size, colour).",
            "examples": [
              "250 ml"
            ]
          },
          "brand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Brand",
            "description": "The brand (vendor) the store states.",
            "examples": [
              "Mamaearth"
            ]
          },
          "sku": {
            "type": [
              "null",
              "string"
            ],
            "title": "SKU",
            "description": "The store’s SKU.",
            "examples": [
              "MAE-OHO-250"
            ]
          },
          "barcode": {
            "type": [
              "null",
              "string"
            ],
            "title": "Barcode",
            "description": "The barcode (GTIN/EAN) when the store states one.",
            "examples": [
              "8906087771234"
            ]
          },
          "priceMinor": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Price",
            "description": "The selling price in minor units (paise for INR).",
            "examples": [
              34900
            ]
          },
          "compareAtMinor": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Struck-through price",
            "description": "The compare-at (MRP or was) price in minor units, when shown.",
            "examples": [
              39900
            ]
          },
          "currency": {
            "type": [
              "null",
              "string"
            ],
            "title": "Currency",
            "description": "ISO 4217 currency code.",
            "examples": [
              "INR"
            ]
          },
          "available": {
            "type": [
              "null",
              "boolean"
            ],
            "title": "In stock",
            "description": "Whether the store offered it for sale when last read.",
            "examples": [
              true
            ]
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "title": "Tags",
            "description": "The store’s tags on the product.",
            "examples": [
              [
                "hair oil",
                "onion"
              ]
            ]
          },
          "images": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "title": "Images",
            "description": "Image addresses on the store (addresses only; Rewalto keeps no image files).",
            "examples": [
              [
                "https://www.mamaearth.in/cdn/shop/files/oho.jpg"
              ]
            ]
          },
          "publishedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "title": "Published",
            "description": "When the store published the product, if it says.",
            "examples": [
              "2025-03-01T00:00:00Z"
            ]
          },
          "firstSeen": {
            "type": "string",
            "format": "date-time",
            "title": "First seen",
            "description": "When Rewalto first saw this variant.",
            "examples": [
              "2026-09-02T10:15:00Z"
            ]
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "Last seen",
            "description": "When Rewalto last saw this variant.",
            "examples": [
              "2026-10-20T18:54:58Z"
            ]
          },
          "missedReads": {
            "type": "integer",
            "title": "Missed reads",
            "description": "Store reads in a row that did not list it (0 = still listed at the last read).",
            "examples": [
              0
            ],
            "minimum": 0
          }
        }
      },
      "StorefrontProductsPage": {
        "type": "object",
        "title": "Storefront products page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/StorefrontProduct"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "D2cBrand": {
        "type": "object",
        "title": "D2C brand",
        "description": "One Indian D2C brand store from Rewalto’s brand directory: its platform, categories, place, size and estimated traffic and sales. Estimates are estimates, not reported figures. Brand level only; no personal contact data.",
        "additionalProperties": false,
        "required": [
          "host",
          "brandName",
          "siteTitle",
          "platform",
          "categories",
          "city",
          "state",
          "countryCode",
          "postalCode",
          "employees",
          "employeesBand",
          "monthlyVisits",
          "monthlyPageviews",
          "trafficBand",
          "estimatedMonthlySalesUsdMinor",
          "estimatedYearlySalesUsdMinor",
          "salesBand",
          "productsSold",
          "salesChannels",
          "technologies",
          "instagramUrl",
          "facebookUrl",
          "twitterUrl",
          "youtubeHandle",
          "storefrontHost",
          "storefrontPlatform"
        ],
        "properties": {
          "host": {
            "type": "string",
            "title": "Store",
            "description": "The store’s host name as the directory lists it.",
            "examples": [
              "www.kent.co.in"
            ]
          },
          "brandName": {
            "type": [
              "null",
              "string"
            ],
            "title": "Brand",
            "description": "The brand or merchant name.",
            "examples": [
              "Kent RO"
            ]
          },
          "siteTitle": {
            "type": [
              "null",
              "string"
            ],
            "title": "Site title",
            "description": "The title of the store’s home page.",
            "examples": [
              "Kent RO Water Purifiers"
            ]
          },
          "platform": {
            "type": [
              "null",
              "string"
            ],
            "title": "Platform",
            "description": "The platform the directory lists for the store.",
            "examples": [
              "Shopify"
            ]
          },
          "categories": {
            "type": "array",
            "title": "Categories",
            "description": "Category paths, most specific last.",
            "items": {
              "type": "string",
              "examples": [
                "/Home & Garden/Home Appliances"
              ]
            }
          },
          "city": {
            "type": [
              "null",
              "string"
            ],
            "title": "City",
            "description": "The brand’s city.",
            "examples": [
              "Noida"
            ]
          },
          "state": {
            "type": [
              "null",
              "string"
            ],
            "title": "State",
            "description": "The brand’s state.",
            "examples": [
              "Uttar Pradesh"
            ]
          },
          "countryCode": {
            "type": [
              "null",
              "string"
            ],
            "title": "Country",
            "description": "ISO 3166 country code.",
            "examples": [
              "IN"
            ]
          },
          "postalCode": {
            "type": [
              "null",
              "string"
            ],
            "title": "Postal code",
            "description": "The brand’s postal code.",
            "examples": [
              "201301"
            ]
          },
          "employees": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Employees",
            "description": "Estimated number of employees.",
            "examples": [
              120
            ]
          },
          "employeesBand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Size band",
            "description": "Employees band: 1-10, 11-50, 51-200, 201-1,000, over 1,000.",
            "examples": [
              "51-200"
            ]
          },
          "monthlyVisits": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Monthly visits",
            "description": "Estimated site visits a month.",
            "examples": [
              250000
            ]
          },
          "monthlyPageviews": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Monthly page views",
            "description": "Estimated page views a month.",
            "examples": [
              900000
            ]
          },
          "trafficBand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Traffic band",
            "description": "Visits band, from under 10k to over 10m a month.",
            "examples": [
              "100k-1m"
            ]
          },
          "estimatedMonthlySalesUsdMinor": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Estimated monthly sales",
            "description": "Estimated sales a month in US cents.",
            "examples": [
              190272087
            ]
          },
          "estimatedYearlySalesUsdMinor": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Estimated yearly sales",
            "description": "Estimated sales a year in US cents.",
            "examples": [
              2283265044
            ]
          },
          "salesBand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Sales band",
            "description": "Monthly sales band, from under $10k to over $10m.",
            "examples": [
              "$1m-$10m"
            ]
          },
          "productsSold": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Products sold",
            "description": "Estimated number of products the store sells.",
            "examples": [
              484
            ]
          },
          "salesChannels": {
            "type": "array",
            "title": "Sales channels",
            "description": "Marketplaces and channels the brand also sells on.",
            "items": {
              "type": "string",
              "examples": [
                "Amazon"
              ]
            }
          },
          "technologies": {
            "type": "array",
            "title": "Technologies",
            "description": "Technologies detected on the store.",
            "items": {
              "type": "string",
              "examples": [
                "Google Analytics"
              ]
            }
          },
          "instagramUrl": {
            "type": [
              "null",
              "string"
            ],
            "title": "Instagram",
            "description": "The brand’s Instagram page.",
            "examples": [
              "https://www.instagram.com/kent"
            ]
          },
          "facebookUrl": {
            "type": [
              "null",
              "string"
            ],
            "title": "Facebook",
            "description": "The brand’s Facebook page.",
            "examples": [
              "https://www.facebook.com/kent"
            ]
          },
          "twitterUrl": {
            "type": [
              "null",
              "string"
            ],
            "title": "Twitter",
            "description": "The brand’s Twitter page.",
            "examples": [
              "https://twitter.com/kent"
            ]
          },
          "youtubeHandle": {
            "type": [
              "null",
              "string"
            ],
            "title": "YouTube",
            "description": "The brand’s YouTube handle.",
            "examples": [
              "kentrosystemsltd"
            ]
          },
          "storefrontHost": {
            "type": [
              "null",
              "string"
            ],
            "title": "Storefront index host",
            "description": "The host of the same store in Rewalto’s storefront index (GET /v1/data/storefronts); null when it is not there.",
            "examples": [
              "kent.co.in"
            ]
          },
          "storefrontPlatform": {
            "type": [
              "null",
              "string"
            ],
            "title": "Platform Rewalto detected",
            "description": "The platform Rewalto itself detected for the store; null when the store is not in the storefront index.",
            "examples": [
              "woocommerce"
            ]
          }
        }
      },
      "D2cBrandsPage": {
        "type": "object",
        "title": "D2C brands page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/D2cBrand"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "BrandShelfDay": {
        "type": "object",
        "title": "BrandShelfDay",
        "description": "A brand’s share of the shelf at one pin code on one IST day: its distinct listings read there over all distinct listings read there, for one retailer.",
        "additionalProperties": false,
        "required": [
          "day",
          "retailer",
          "pincode",
          "brand",
          "listings",
          "pinListings",
          "shareBp",
          "readings"
        ],
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The IST day.",
            "examples": [
              "2026-10-21"
            ]
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer key.",
            "examples": [
              "blinkit"
            ]
          },
          "brand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Brand",
            "description": "The brand as the retailer wrote it; null when none.",
            "examples": [
              "Amul"
            ]
          },
          "pincode": {
            "type": "string",
            "title": "Pin code",
            "description": "The six-digit pin code, or national.",
            "examples": [
              "560034"
            ]
          },
          "listings": {
            "type": "integer",
            "title": "Listings",
            "description": "Distinct listings of the brand read at the pin that day.",
            "examples": [
              12
            ]
          },
          "pinListings": {
            "type": "integer",
            "title": "Pin listings",
            "description": "Distinct listings of every brand read at the pin that day.",
            "examples": [
              480
            ]
          },
          "shareBp": {
            "type": "integer",
            "title": "Share",
            "description": "The brand’s share in basis points; 10000 is the whole shelf.",
            "examples": [
              250
            ]
          },
          "readings": {
            "type": "integer",
            "title": "Readings",
            "description": "Readings of the brand’s listings that day.",
            "examples": [
              31
            ]
          }
        }
      },
      "OosRateDay": {
        "type": "object",
        "title": "OosRateDay",
        "description": "How often a brand was out of stock in a city on one IST day, for one retailer: out-of-stock readings over readings that stated stock. Retailers that state no stock (Flipkart) give null.",
        "additionalProperties": false,
        "required": [
          "day",
          "retailer",
          "city",
          "brand",
          "listings",
          "readings",
          "stockKnown",
          "outOfStock",
          "oosBp"
        ],
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The IST day.",
            "examples": [
              "2026-10-21"
            ]
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer key.",
            "examples": [
              "blinkit"
            ]
          },
          "brand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Brand",
            "description": "The brand as the retailer wrote it; null when none.",
            "examples": [
              "Amul"
            ]
          },
          "city": {
            "type": "string",
            "title": "City",
            "description": "The city of the pin code (India Post directory), or national.",
            "examples": [
              "Bengaluru"
            ]
          },
          "listings": {
            "type": "integer",
            "title": "Listings",
            "description": "Distinct listings of the brand read in the city that day.",
            "examples": [
              40
            ]
          },
          "readings": {
            "type": "integer",
            "title": "Readings",
            "description": "All readings of those listings that day.",
            "examples": [
              120
            ]
          },
          "stockKnown": {
            "type": "integer",
            "title": "Stock known",
            "description": "Readings that said in stock or out of stock.",
            "examples": [
              120
            ]
          },
          "outOfStock": {
            "type": "integer",
            "title": "Out of stock",
            "description": "Readings that said out of stock.",
            "examples": [
              9
            ]
          },
          "oosBp": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Out-of-stock rate",
            "description": "outOfStock over stockKnown in basis points; null when no reading stated stock.",
            "examples": [
              750
            ]
          }
        }
      },
      "DiscountDay": {
        "type": "object",
        "title": "DiscountDay",
        "description": "Discount depth for a brand and category at one retailer on one IST day: how many readings carried both a selling price and an MRP, how many were priced below MRP, and the average, median and deepest discount in basis points of MRP.",
        "additionalProperties": false,
        "required": [
          "day",
          "retailer",
          "brand",
          "category",
          "listings",
          "readings",
          "priced",
          "discounted",
          "avgDiscountBp",
          "medianDiscountBp",
          "maxDiscountBp"
        ],
        "properties": {
          "day": {
            "type": "string",
            "format": "date",
            "title": "Day",
            "description": "The IST day.",
            "examples": [
              "2026-10-21"
            ]
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer key.",
            "examples": [
              "blinkit"
            ]
          },
          "brand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Brand",
            "description": "The brand as the retailer wrote it; null when none.",
            "examples": [
              "Amul"
            ]
          },
          "category": {
            "type": [
              "null",
              "string"
            ],
            "title": "Category",
            "description": "The category as the retailer wrote it; null when none.",
            "examples": [
              "Dairy"
            ]
          },
          "listings": {
            "type": "integer",
            "title": "Listings",
            "description": "Distinct listings read that day.",
            "examples": [
              60
            ]
          },
          "readings": {
            "type": "integer",
            "title": "Readings",
            "description": "All readings that day.",
            "examples": [
              180
            ]
          },
          "priced": {
            "type": "integer",
            "title": "Priced",
            "description": "Readings with a selling price and an MRP at least as high.",
            "examples": [
              170
            ]
          },
          "discounted": {
            "type": "integer",
            "title": "Discounted",
            "description": "Of those, readings priced below MRP.",
            "examples": [
              90
            ]
          },
          "avgDiscountBp": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Average discount",
            "description": "Mean discount in basis points of MRP over priced readings.",
            "examples": [
              1450
            ]
          },
          "medianDiscountBp": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Median discount",
            "description": "Median discount in basis points of MRP.",
            "examples": [
              1200
            ]
          },
          "maxDiscountBp": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Deepest discount",
            "description": "Deepest discount in basis points of MRP.",
            "examples": [
              4500
            ]
          }
        }
      },
      "BrandShelfPage": {
        "type": "object",
        "title": "Brand shelf page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/BrandShelfDay"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "OosRatePage": {
        "type": "object",
        "title": "Out-of-stock rate page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/OosRateDay"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "DiscountsPage": {
        "type": "object",
        "title": "Discounts page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/DiscountDay"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "StorefrontChange": {
        "type": "object",
        "title": "StorefrontChange",
        "description": "One change Rewalto saw on a D2C store’s catalogue between two reads: a product launched or delisted, a variant’s price changed, its struck-through price changed while the price held (a promotion), or its stock changed. Fields that do not apply to the change are null.",
        "additionalProperties": false,
        "required": [
          "host",
          "change",
          "productId",
          "variantId",
          "title",
          "handle",
          "variants",
          "publishedAt",
          "absentReads",
          "priceMinor",
          "oldPriceMinor",
          "compareAtMinor",
          "oldCompareAtMinor",
          "currency",
          "inStock",
          "wasInStock",
          "stockSummary",
          "observedAt"
        ],
        "properties": {
          "host": {
            "type": "string",
            "title": "Store",
            "description": "The store’s host name.",
            "examples": [
              "www.mamaearth.in"
            ],
            "pattern": "^[a-z0-9][a-z0-9.-]{1,252}$"
          },
          "change": {
            "type": "string",
            "enum": [
              "launched",
              "delisted",
              "price_changed",
              "promotion_changed",
              "stock_changed"
            ],
            "title": "Change",
            "description": "launched (new product), delisted (gone for several reads), price_changed, promotion_changed (struck-through price moved, price held) or stock_changed.",
            "examples": [
              "price_changed"
            ]
          },
          "productId": {
            "type": "string",
            "title": "Product id",
            "description": "The store’s own product id.",
            "examples": [
              "7781230412345"
            ]
          },
          "variantId": {
            "type": [
              "null",
              "string"
            ],
            "title": "Variant id",
            "description": "The store’s own variant id; null for product changes.",
            "examples": [
              "43012345678901"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ],
            "title": "Name",
            "description": "The product name, for launched and delisted.",
            "examples": [
              "Onion Hair Oil"
            ]
          },
          "handle": {
            "type": [
              "null",
              "string"
            ],
            "title": "Handle",
            "description": "The product’s URL handle, for launched and delisted.",
            "examples": [
              "onion-hair-oil"
            ]
          },
          "variants": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Variants",
            "description": "How many variants the product has, for launched and delisted.",
            "examples": [
              3
            ]
          },
          "publishedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "title": "Published (store’s claim)",
            "description": "When the store says the product was published, for launched. The store’s own claim, which it can edit; the launch is when Rewalto first saw the product.",
            "examples": [
              "2026-10-20T09:00:00Z"
            ]
          },
          "absentReads": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Reads absent",
            "description": "How many reads in a row the product was missing before it counted as delisted, for delisted.",
            "examples": [
              3
            ]
          },
          "priceMinor": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Price",
            "description": "The price after the change. In minor units (paise for INR).",
            "examples": [
              28900
            ]
          },
          "oldPriceMinor": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Old price",
            "description": "The price before, for price_changed. In minor units (paise for INR).",
            "examples": [
              33500
            ]
          },
          "compareAtMinor": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Struck-through price",
            "description": "The compare-at price after the change. In minor units (paise for INR).",
            "examples": [
              39900
            ]
          },
          "oldCompareAtMinor": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Old struck-through price",
            "description": "The compare-at price before. In minor units (paise for INR).",
            "examples": [
              44000
            ]
          },
          "currency": {
            "type": [
              "null",
              "string"
            ],
            "title": "Currency",
            "description": "ISO 4217 code, for price changes.",
            "examples": [
              "INR"
            ]
          },
          "inStock": {
            "type": [
              "null",
              "boolean"
            ],
            "title": "In stock",
            "description": "Stock after the change, for stock_changed.",
            "examples": [
              false
            ]
          },
          "wasInStock": {
            "type": [
              "null",
              "boolean"
            ],
            "title": "Was in stock",
            "description": "Stock before the change, for stock_changed.",
            "examples": [
              true
            ]
          },
          "stockSummary": {
            "type": [
              "null",
              "object"
            ],
            "title": "Stock change summary",
            "description": "Set on a stock_changed record that summarises a read whose stock changes passed the per-read event budget: how many variants changed, how many were compared, the budget, how many were left out and a few of them. Null on every other record.",
            "additionalProperties": false,
            "required": [
              "changed",
              "compared",
              "budget",
              "suppressed",
              "examples",
              "truncated"
            ],
            "properties": {
              "changed": {
                "type": [
                  "null",
                  "integer"
                ],
                "title": "Changed",
                "description": "Variants whose stock changed in the read.",
                "examples": [
                  1200
                ]
              },
              "compared": {
                "type": [
                  "null",
                  "integer"
                ],
                "title": "Compared",
                "description": "Variants compared in the read.",
                "examples": [
                  8000
                ]
              },
              "budget": {
                "type": [
                  "null",
                  "integer"
                ],
                "title": "Budget",
                "description": "Stock events written one by one per read.",
                "examples": [
                  200
                ]
              },
              "suppressed": {
                "type": [
                  "null",
                  "integer"
                ],
                "title": "Left out",
                "description": "Stock changes not written one by one.",
                "examples": [
                  1000
                ]
              },
              "examples": {
                "type": "array",
                "title": "Examples",
                "description": "A few of the left-out changes, as product id/variant id.",
                "items": {
                  "type": "string",
                  "examples": [
                    "7781230412345/43012345678901"
                  ]
                }
              },
              "truncated": {
                "type": [
                  "null",
                  "boolean"
                ],
                "title": "Read stopped early",
                "description": "True when the read stopped before the whole catalogue, so compared is what was read, not the catalogue size; null when the record does not say.",
                "examples": [
                  false
                ]
              }
            }
          },
          "observedAt": {
            "type": "string",
            "format": "date-time",
            "title": "Seen",
            "description": "When Rewalto’s read saw the change.",
            "examples": [
              "2026-10-22T13:48:08Z"
            ]
          }
        }
      },
      "StorefrontChangesPage": {
        "type": "object",
        "title": "Storefront changes page",
        "description": "One page of records with paging, the as-of time and what the page cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page, newest first.",
            "items": {
              "$ref": "#/components/schemas/StorefrontChange"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  100
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNFQwOToyNzowMC4wMDBaIiwiaSI6NDgyMTAzNzcsImYiOiJhYmMxMjMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from and what the page cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "kept"
                ],
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest ingestion time among the records; null for an empty page.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "DiscoverRow": {
        "type": "object",
        "title": "Preview row",
        "description": "One matching listing, shown free: what it is, its primary image address, the Rewalto product it is matched to, and its newest kept price reading. The full listing (every image, the product page, tags, history) comes only with a paid Fetch.",
        "additionalProperties": false,
        "required": [
          "selectionId",
          "retailer",
          "retailerSku",
          "title",
          "brand",
          "packSizeRaw",
          "imageUrl",
          "productId",
          "match",
          "lastSeen",
          "latest"
        ],
        "properties": {
          "selectionId": {
            "type": "string",
            "title": "Selection id",
            "description": "Opaque id of this match. Send it back in selection on GET /v1/data/listings to fetch exactly this listing (paid). Do not parse it.",
            "examples": [
              "sel_7c1e5f0a2f554d2b8c360f3f1d9c2b77"
            ],
            "pattern": "^sel_[0-9a-f]{32}$"
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer key.",
            "examples": [
              "blinkit"
            ]
          },
          "retailerSku": {
            "type": "string",
            "title": "Retailer product id",
            "description": "The retailer's own product id. With retailer, it selects this listing's price history in listObservations (paid).",
            "examples": [
              "571168"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ],
            "title": "Title",
            "description": "The title as the retailer showed it.",
            "examples": [
              "Amul Butter 100 g"
            ]
          },
          "brand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Brand",
            "description": "The brand as the retailer wrote it.",
            "examples": [
              "Amul"
            ]
          },
          "packSizeRaw": {
            "type": [
              "null",
              "string"
            ],
            "title": "Pack size",
            "description": "The pack size as printed.",
            "examples": [
              "100 g"
            ]
          },
          "imageUrl": {
            "type": [
              "null",
              "string"
            ],
            "title": "Image URL",
            "description": "The primary image address Rewalto holds for the listing (the address, never the image file), as the paid listing carries it (contract 0.68.0, issue #217). Null when none is held. Every image comes with the paid listing.",
            "examples": [
              "https://cdn.example/amul-butter.jpg"
            ]
          },
          "productId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "title": "Product id",
            "description": "The Rewalto product this listing is matched to, the same value the paid listing carries (contract 0.68.0, issue #217): listings of one product across retailers share it, and getSeries takes it for the product's history (paid). Null when the listing is not matched to a product.",
            "examples": [
              "0b6f3c1e-8a2d-4e5f-9c1b-2d3e4f5a6b7c"
            ]
          },
          "match": {
            "type": "string",
            "enum": [
              "exact_id",
              "phrase",
              "words",
              "near"
            ],
            "title": "Match",
            "description": "How it matched: exact_id (q is its retailer product id), phrase (the words in order in the name), words (every word starts a word of its name, brand or product id), near (an approximate match of a misspelt word of 5+ letters, only when fewer than 10 listings match by words).",
            "examples": [
              "phrase"
            ]
          },
          "lastSeen": {
            "type": "string",
            "format": "date-time",
            "title": "Last seen",
            "description": "When Rewalto last read the listing.",
            "examples": [
              "2026-10-20T06:10:00Z"
            ]
          },
          "latest": {
            "type": "object",
            "title": "Newest price reading",
            "description": "The listing's newest kept reading in the last 30 days, at the pin code asked for, else at any pin. Never a guess.",
            "additionalProperties": false,
            "required": [
              "state",
              "priceMinor",
              "mrpMinor",
              "currency",
              "inStock",
              "pincode",
              "observedAt"
            ],
            "properties": {
              "state": {
                "type": "string",
                "enum": [
                  "priced",
                  "no_price_shown",
                  "no_recent_reading",
                  "excluded_pin_day"
                ],
                "title": "State",
                "description": "priced: the reading shows a price. no_price_shown: the newest reading had none. no_recent_reading: no kept reading in the last 30 days (at the pin, when one was asked for). excluded_pin_day: the newest reading falls on a pin-day left out of the data (D-1458), so nothing is shown.",
                "examples": [
                  "priced"
                ]
              },
              "priceMinor": {
                "type": [
                  "null",
                  "integer"
                ],
                "title": "Price",
                "description": "Selling price in paise; null when not shown.",
                "examples": [
                  5600
                ]
              },
              "mrpMinor": {
                "type": [
                  "null",
                  "integer"
                ],
                "title": "MRP",
                "description": "MRP in paise; null when not shown.",
                "examples": [
                  6000
                ]
              },
              "currency": {
                "const": "INR",
                "title": "Currency",
                "description": "Always INR.",
                "examples": [
                  "INR"
                ]
              },
              "inStock": {
                "type": [
                  "null",
                  "boolean"
                ],
                "title": "In stock",
                "description": "In stock in that reading; null when the retailer does not say (always null for Flipkart).",
                "examples": [
                  true
                ]
              },
              "pincode": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Pin code",
                "description": "Where the reading was taken.",
                "examples": [
                  "110092"
                ]
              },
              "observedAt": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "Read at",
                "description": "When the reading was taken; null when there is none.",
                "examples": [
                  "2026-10-20T05:55:00Z"
                ]
              }
            }
          }
        }
      },
      "DiscoverRate": {
        "type": "object",
        "title": "Published rate",
        "description": "A published rate from the newest rate card holding the unit (C-012): credits for every perUnits records. Null when no rate is published for the unit yet; that read is then refused with not_for_sale.",
        "additionalProperties": false,
        "required": [
          "unit",
          "credits",
          "perUnits",
          "cardVersion"
        ],
        "properties": {
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "The rate-card unit.",
            "examples": [
              "listings"
            ]
          },
          "credits": {
            "type": "integer",
            "title": "Credits",
            "description": "Credits for every perUnits records.",
            "examples": [
              1
            ],
            "minimum": 0
          },
          "perUnits": {
            "type": "integer",
            "title": "Per units",
            "description": "Records the credits cover.",
            "examples": [
              10
            ],
            "minimum": 1
          },
          "cardVersion": {
            "type": "integer",
            "title": "Rate card",
            "description": "The rate card version the rate is on.",
            "examples": [
              2
            ],
            "minimum": 1
          }
        }
      },
      "DiscoverPreview": {
        "type": "object",
        "title": "Discovery preview",
        "description": "A free preview of a product search, before any paid Fetch (issue #12, D-1830 D-b).",
        "additionalProperties": false,
        "required": [
          "data",
          "counts",
          "fields",
          "freshness",
          "fetch",
          "allowance",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Preview rows",
            "description": "Up to 25 matches, best first (the order of searchListings without AI query understanding). There is no next page: the full list is a paid Fetch.",
            "items": {
              "$ref": "#/components/schemas/DiscoverRow"
            }
          },
          "counts": {
            "type": "object",
            "title": "Counts",
            "description": "Exact counts over every match, not only the rows shown.",
            "additionalProperties": false,
            "required": [
              "total",
              "exact",
              "matching",
              "byRetailer",
              "byBrand",
              "brandsTotal",
              "shown"
            ],
            "properties": {
              "total": {
                "type": "integer",
                "title": "Matches",
                "description": "Every listing that matches, under the same filters.",
                "examples": [
                  214
                ],
                "minimum": 0
              },
              "exact": {
                "const": true,
                "title": "Exact",
                "description": "Always true: the counts are counted, never estimated.",
                "examples": [
                  true
                ]
              },
              "matching": {
                "type": "string",
                "enum": [
                  "words",
                  "words_and_near"
                ],
                "title": "Matching",
                "description": "words: every word of q starts a word of the listing. words_and_near: fewer than 10 matched by words (under the filters and, with filters, in the whole Library), so approximate matches of misspelt words of 5+ letters are included (the searchListings rule).",
                "examples": [
                  "words"
                ]
              },
              "byRetailer": {
                "type": "array",
                "title": "By retailer",
                "description": "Matches per retailer, largest first; every retailer with a match.",
                "items": {
                  "type": "object",
                  "title": "Count",
                  "description": "How many matches have this value.",
                  "additionalProperties": false,
                  "required": [
                    "key",
                    "count"
                  ],
                  "properties": {
                    "key": {
                      "type": "string",
                      "title": "Value",
                      "description": "The retailer key, or the brand as the retailer wrote it.",
                      "examples": [
                        "blinkit"
                      ]
                    },
                    "count": {
                      "type": "integer",
                      "title": "Matches",
                      "description": "Matching listings with this value.",
                      "examples": [
                        42
                      ],
                      "minimum": 1
                    }
                  }
                }
              },
              "byBrand": {
                "type": "array",
                "title": "By brand",
                "description": "Matches per brand as written, largest first: the 20 largest (brandsTotal says how many there are). Listings with no brand are not in it.",
                "items": {
                  "type": "object",
                  "title": "Count",
                  "description": "How many matches have this value.",
                  "additionalProperties": false,
                  "required": [
                    "key",
                    "count"
                  ],
                  "properties": {
                    "key": {
                      "type": "string",
                      "title": "Value",
                      "description": "The retailer key, or the brand as the retailer wrote it.",
                      "examples": [
                        "blinkit"
                      ]
                    },
                    "count": {
                      "type": "integer",
                      "title": "Matches",
                      "description": "Matching listings with this value.",
                      "examples": [
                        42
                      ],
                      "minimum": 1
                    }
                  }
                }
              },
              "brandsTotal": {
                "type": "integer",
                "title": "Brands",
                "description": "How many distinct brands the matches have.",
                "examples": [
                  7
                ],
                "minimum": 0
              },
              "shown": {
                "type": "integer",
                "title": "Shown",
                "description": "Rows in data.",
                "examples": [
                  25
                ],
                "minimum": 0
              }
            }
          },
          "fields": {
            "type": "object",
            "title": "Fields",
            "description": "What is free here, and what a paid Fetch delivers.",
            "additionalProperties": false,
            "required": [
              "preview",
              "delivered"
            ],
            "properties": {
              "preview": {
                "type": "array",
                "title": "Free fields",
                "description": "The fields of each preview row.",
                "items": {
                  "type": "string"
                }
              },
              "delivered": {
                "type": "array",
                "title": "Delivered by a Fetch",
                "description": "Each paid read and its fields.",
                "items": {
                  "type": "object",
                  "title": "Delivered by",
                  "description": "One paid read and the fields it delivers.",
                  "additionalProperties": false,
                  "required": [
                    "operationId",
                    "unit",
                    "fields"
                  ],
                  "properties": {
                    "operationId": {
                      "type": "string",
                      "title": "Operation",
                      "description": "The paid operation.",
                      "examples": [
                        "listListings"
                      ]
                    },
                    "unit": {
                      "type": "string",
                      "title": "Unit",
                      "description": "The rate-card unit it is charged in.",
                      "examples": [
                        "listings"
                      ]
                    },
                    "fields": {
                      "type": "array",
                      "title": "Fields",
                      "description": "The fields of each delivered record.",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "freshness": {
            "type": "object",
            "title": "Freshness",
            "description": "When the matches were last read.",
            "additionalProperties": false,
            "required": [
              "newestSeen",
              "oldestSeen"
            ],
            "properties": {
              "newestSeen": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "Newest",
                "description": "The most recent last-seen time among every match; null when none match.",
                "examples": [
                  "2026-10-20T06:10:00Z"
                ]
              },
              "oldestSeen": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "Oldest",
                "description": "The oldest last-seen time among every match; null when none match.",
                "examples": [
                  "2026-09-30T11:00:00Z"
                ]
              }
            }
          },
          "fetch": {
            "type": "object",
            "title": "Fetch",
            "description": "How to get the data at the published rates. Nothing here is charged.",
            "additionalProperties": false,
            "required": [
              "all",
              "selection",
              "history",
              "notes"
            ],
            "properties": {
              "all": {
                "type": "object",
                "title": "Every match",
                "description": "Fetch every match through the paid search.",
                "additionalProperties": false,
                "required": [
                  "operationId",
                  "query",
                  "records",
                  "rate",
                  "credits"
                ],
                "properties": {
                  "operationId": {
                    "const": "searchListings",
                    "title": "Operation",
                    "description": "The paid search.",
                    "examples": [
                      "searchListings"
                    ]
                  },
                  "query": {
                    "type": "object",
                    "title": "Query",
                    "description": "The query to send it: the same words and filters (a location filter as given here, with the same consent).",
                    "additionalProperties": {
                      "type": "string"
                    },
                    "examples": [
                      {
                        "q": "amul butter",
                        "retailer": "blinkit"
                      }
                    ]
                  },
                  "records": {
                    "type": "integer",
                    "title": "Records",
                    "description": "Listings it would deliver: counts.total.",
                    "examples": [
                      214
                    ],
                    "minimum": 0
                  },
                  "rate": {
                    "type": [
                      "null",
                      "object"
                    ],
                    "title": "Published rate",
                    "description": "A published rate from the newest rate card holding the unit (C-012): credits for every perUnits records. Null when no rate is published for the unit yet; that read is then refused with not_for_sale.",
                    "additionalProperties": false,
                    "required": [
                      "unit",
                      "credits",
                      "perUnits",
                      "cardVersion"
                    ],
                    "properties": {
                      "unit": {
                        "type": "string",
                        "title": "Unit",
                        "description": "The rate-card unit.",
                        "examples": [
                          "listings"
                        ]
                      },
                      "credits": {
                        "type": "integer",
                        "title": "Credits",
                        "description": "Credits for every perUnits records.",
                        "examples": [
                          1
                        ],
                        "minimum": 0
                      },
                      "perUnits": {
                        "type": "integer",
                        "title": "Per units",
                        "description": "Records the credits cover.",
                        "examples": [
                          10
                        ],
                        "minimum": 1
                      },
                      "cardVersion": {
                        "type": "integer",
                        "title": "Rate card",
                        "description": "The rate card version the rate is on.",
                        "examples": [
                          2
                        ],
                        "minimum": 1
                      }
                    }
                  },
                  "credits": {
                    "type": [
                      "null",
                      "integer"
                    ],
                    "title": "Credits",
                    "description": "What every match costs at the rate when each page is fetched once, rounded up per page of 100: the most the plain search costs (a 7-day free re-read costs less; AI query understanding may add the brand's other listings). Null when no rate is published.",
                    "examples": [
                      22
                    ]
                  }
                }
              },
              "selection": {
                "type": "object",
                "title": "Chosen rows",
                "description": "Fetch only the rows chosen here.",
                "additionalProperties": false,
                "required": [
                  "operationId",
                  "parameter",
                  "maxIds",
                  "rate"
                ],
                "properties": {
                  "operationId": {
                    "const": "listListings",
                    "title": "Operation",
                    "description": "The paid listings read.",
                    "examples": [
                      "listListings"
                    ]
                  },
                  "parameter": {
                    "const": "selection",
                    "title": "Parameter",
                    "description": "Comma-separated selection ids.",
                    "examples": [
                      "selection"
                    ]
                  },
                  "maxIds": {
                    "type": "integer",
                    "title": "Most ids",
                    "description": "Selection ids per call.",
                    "examples": [
                      100
                    ]
                  },
                  "rate": {
                    "type": [
                      "null",
                      "object"
                    ],
                    "title": "Published rate",
                    "description": "A published rate from the newest rate card holding the unit (C-012): credits for every perUnits records. Null when no rate is published for the unit yet; that read is then refused with not_for_sale.",
                    "additionalProperties": false,
                    "required": [
                      "unit",
                      "credits",
                      "perUnits",
                      "cardVersion"
                    ],
                    "properties": {
                      "unit": {
                        "type": "string",
                        "title": "Unit",
                        "description": "The rate-card unit.",
                        "examples": [
                          "listings"
                        ]
                      },
                      "credits": {
                        "type": "integer",
                        "title": "Credits",
                        "description": "Credits for every perUnits records.",
                        "examples": [
                          1
                        ],
                        "minimum": 0
                      },
                      "perUnits": {
                        "type": "integer",
                        "title": "Per units",
                        "description": "Records the credits cover.",
                        "examples": [
                          10
                        ],
                        "minimum": 1
                      },
                      "cardVersion": {
                        "type": "integer",
                        "title": "Rate card",
                        "description": "The rate card version the rate is on.",
                        "examples": [
                          2
                        ],
                        "minimum": 1
                      }
                    }
                  }
                }
              },
              "history": {
                "type": "object",
                "title": "Price history",
                "description": "A chosen listing's price and stock history: listObservations with its retailer and retailerSku.",
                "additionalProperties": false,
                "required": [
                  "operationId",
                  "rate"
                ],
                "properties": {
                  "operationId": {
                    "const": "listObservations",
                    "title": "Operation",
                    "description": "The paid history read.",
                    "examples": [
                      "listObservations"
                    ]
                  },
                  "rate": {
                    "type": [
                      "null",
                      "object"
                    ],
                    "title": "Published rate",
                    "description": "A published rate from the newest rate card holding the unit (C-012): credits for every perUnits records. Null when no rate is published for the unit yet; that read is then refused with not_for_sale.",
                    "additionalProperties": false,
                    "required": [
                      "unit",
                      "credits",
                      "perUnits",
                      "cardVersion"
                    ],
                    "properties": {
                      "unit": {
                        "type": "string",
                        "title": "Unit",
                        "description": "The rate-card unit.",
                        "examples": [
                          "listings"
                        ]
                      },
                      "credits": {
                        "type": "integer",
                        "title": "Credits",
                        "description": "Credits for every perUnits records.",
                        "examples": [
                          1
                        ],
                        "minimum": 0
                      },
                      "perUnits": {
                        "type": "integer",
                        "title": "Per units",
                        "description": "Records the credits cover.",
                        "examples": [
                          10
                        ],
                        "minimum": 1
                      },
                      "cardVersion": {
                        "type": "integer",
                        "title": "Rate card",
                        "description": "The rate card version the rate is on.",
                        "examples": [
                          2
                        ],
                        "minimum": 1
                      }
                    }
                  }
                }
              },
              "notes": {
                "type": "string",
                "title": "Notes",
                "description": "How charging works, in one paragraph.",
                "examples": [
                  "Charged on delivery at the published rate, rounded up per page."
                ]
              }
            }
          },
          "allowance": {
            "type": "object",
            "title": "Allowance",
            "description": "Free previews left for your organisation today (IST). A preview that finds nothing does not count.",
            "additionalProperties": false,
            "required": [
              "perDay",
              "usedToday",
              "remainingToday",
              "resetsAt",
              "paid"
            ],
            "properties": {
              "perDay": {
                "type": "integer",
                "title": "Per day",
                "description": "Free previews per organisation per IST day.",
                "examples": [
                  50
                ],
                "minimum": 0
              },
              "usedToday": {
                "type": "integer",
                "title": "Used today",
                "description": "Previews counted today, this one included.",
                "examples": [
                  3
                ],
                "minimum": 0
              },
              "remainingToday": {
                "type": "integer",
                "title": "Left today",
                "description": "Previews left today.",
                "examples": [
                  47
                ],
                "minimum": 0
              },
              "resetsAt": {
                "type": "string",
                "format": "date-time",
                "title": "Resets at",
                "description": "The next IST midnight.",
                "examples": [
                  "2026-10-20T18:30:00Z"
                ]
              },
              "paid": {
                "type": "boolean",
                "title": "Paid",
                "description": "True when today's free previews were used up, so this preview was charged at the listings rate (meta.credits says what it cost). Never true under unlimited credits.",
                "examples": [
                  false
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from, and what it cost: nothing for a free preview.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "credits"
            ],
            "properties": {
              "kind": {
                "const": "kept",
                "title": "Kind",
                "description": "kept: data Rewalto stores.",
                "examples": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "As of",
                "description": "The newest last-seen time among the rows shown; null when none.",
                "examples": [
                  "2026-10-20T06:10:00Z"
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "DatasetSample": {
        "type": "object",
        "title": "Dataset sample",
        "description": "Real rows Rewalto keeps for one dataset, shaped exactly as its paid read delivers them, every one at least 7 days old. Never made up: an empty list means nothing old enough is kept yet.",
        "additionalProperties": false,
        "required": [
          "dataset",
          "operationId",
          "path",
          "unit",
          "catalogueEntryId",
          "rows",
          "notAfter",
          "rate"
        ],
        "properties": {
          "dataset": {
            "type": "string",
            "enum": [
              "listings",
              "price_history",
              "mentions",
              "ratings",
              "banners",
              "storefront_promos",
              "promo_emails",
              "ad_creatives"
            ],
            "title": "Dataset",
            "description": "The dataset.",
            "examples": [
              "listings"
            ]
          },
          "operationId": {
            "type": "string",
            "title": "Operation",
            "description": "The paid read that delivers this dataset.",
            "examples": [
              "listListings"
            ]
          },
          "path": {
            "type": "string",
            "title": "Path",
            "description": "Its path.",
            "examples": [
              "/v1/data/listings"
            ]
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "The rate-card unit it is charged in.",
            "examples": [
              "listings"
            ]
          },
          "catalogueEntryId": {
            "type": [
              "null",
              "string"
            ],
            "title": "Catalogue entry",
            "description": "Its own catalogue entry, where it has one.",
            "examples": [
              "lib_promo_emails"
            ]
          },
          "rows": {
            "type": "array",
            "title": "Rows",
            "description": "Up to 5 real rows, each one record of the paid read.",
            "items": {
              "type": "object",
              "title": "Row",
              "description": "One record, as the paid read delivers it.",
              "additionalProperties": true
            }
          },
          "notAfter": {
            "type": "string",
            "format": "date",
            "title": "Not after",
            "description": "No row is newer than the end of this IST day (7 days before today).",
            "examples": [
              "2026-10-13"
            ]
          },
          "rate": {
            "type": [
              "null",
              "object"
            ],
            "title": "Published rate",
            "description": "A published rate from the newest rate card holding the unit (C-012): credits for every perUnits records. Null when no rate is published for the unit yet; that read is then refused with not_for_sale.",
            "additionalProperties": false,
            "required": [
              "unit",
              "credits",
              "perUnits",
              "cardVersion"
            ],
            "properties": {
              "unit": {
                "type": "string",
                "title": "Unit",
                "description": "The rate-card unit.",
                "examples": [
                  "listings"
                ]
              },
              "credits": {
                "type": "integer",
                "title": "Credits",
                "description": "Credits for every perUnits records.",
                "examples": [
                  1
                ],
                "minimum": 0
              },
              "perUnits": {
                "type": "integer",
                "title": "Per units",
                "description": "Records the credits cover.",
                "examples": [
                  10
                ],
                "minimum": 1
              },
              "cardVersion": {
                "type": "integer",
                "title": "Rate card",
                "description": "The rate card version the rate is on.",
                "examples": [
                  2
                ],
                "minimum": 1
              }
            }
          }
        }
      },
      "TimeToFirstDataRow": {
        "title": "TimeToFirstDataRow",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "level",
          "signupWeek",
          "milestone",
          "accounts",
          "reached",
          "medianSeconds",
          "p75Seconds"
        ],
        "properties": {
          "level": {
            "type": "string",
            "enum": [
              "organisation",
              "user"
            ],
            "description": "Organisations, or the users in them."
          },
          "signupWeek": {
            "type": [
              "null",
              "string"
            ],
            "format": "date",
            "description": "The IST Monday of the sign-up week; null for every week in the window together."
          },
          "milestone": {
            "type": "string",
            "enum": [
              "first_search",
              "first_data_shown",
              "first_purchase"
            ]
          },
          "accounts": {
            "type": "integer",
            "minimum": 0,
            "description": "Accounts that signed up in the week."
          },
          "reached": {
            "type": "integer",
            "minimum": 0,
            "description": "Of those, how many reached the milestone."
          },
          "medianSeconds": {
            "type": [
              "null",
              "number"
            ],
            "description": "Median seconds from sign-up to the milestone, over those that reached it; null if none."
          },
          "p75Seconds": {
            "type": [
              "null",
              "number"
            ],
            "description": "75th percentile seconds from sign-up to the milestone; null if none reached it."
          }
        }
      },
      "TimeToFirstData": {
        "title": "TimeToFirstData",
        "description": "Time from sign-up to first search, first data shown and first purchase, per sign-up week.",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "weeks",
          "data"
        ],
        "properties": {
          "weeks": {
            "type": "integer",
            "minimum": 1,
            "maximum": 104
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeToFirstDataRow"
            }
          }
        }
      },
      "DatasetSamples": {
        "type": "object",
        "title": "Dataset samples",
        "description": "Free real samples, one entry per dataset (D-1830 D-e).",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Datasets",
            "description": "One entry per dataset, in a fixed order.",
            "items": {
              "$ref": "#/components/schemas/DatasetSample"
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "How the samples were chosen; free.",
            "additionalProperties": false,
            "required": [
              "rowsPerDataset",
              "minAgeDays",
              "illustrative",
              "credits"
            ],
            "properties": {
              "rowsPerDataset": {
                "type": "integer",
                "title": "Rows per dataset",
                "description": "The most rows per dataset.",
                "examples": [
                  5
                ]
              },
              "minAgeDays": {
                "type": "integer",
                "title": "Minimum age",
                "description": "Every row is at least this many days old.",
                "examples": [
                  7
                ]
              },
              "illustrative": {
                "const": false,
                "title": "Illustrative",
                "description": "Always false: real kept rows, never made up.",
                "examples": [
                  false
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/NoCharge"
              }
            }
          }
        }
      },
      "NoCharge": {
        "type": "object",
        "title": "No charge",
        "description": "Always nothing: discovery and samples are free and never touch the credit balance.",
        "additionalProperties": false,
        "required": [
          "charged",
          "units",
          "freeReread",
          "rate"
        ],
        "properties": {
          "charged": {
            "const": 0,
            "title": "Credits charged",
            "description": "Always 0.",
            "examples": [
              0
            ]
          },
          "units": {
            "const": 0,
            "title": "Records delivered",
            "description": "Always 0: previews and samples are not delivered data.",
            "examples": [
              0
            ]
          },
          "freeReread": {
            "const": false,
            "title": "Free re-read",
            "description": "Always false.",
            "examples": [
              false
            ]
          },
          "rate": {
            "type": "null",
            "title": "Published rate",
            "description": "Always null: nothing is charged."
          }
        }
      },
      "DemoListing": {
        "type": "object",
        "title": "Demo listing",
        "description": "One real listing and its newest kept reading in the reading window, with its evidence.",
        "additionalProperties": false,
        "required": [
          "retailer",
          "retailerSku",
          "title",
          "brand",
          "packSizeRaw",
          "priceMinor",
          "mrpMinor",
          "currency",
          "inStock",
          "pincode",
          "city",
          "observedAt",
          "sourceUrl",
          "evidenceSha256"
        ],
        "properties": {
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "Retailer key.",
            "examples": [
              "blinkit"
            ],
            "enum": [
              "blinkit",
              "instamart",
              "zepto"
            ]
          },
          "retailerSku": {
            "type": "string",
            "title": "Retailer SKU",
            "description": "The retailer's own product id.",
            "examples": [
              "400001"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ],
            "title": "Title",
            "description": "Title as the retailer showed it.",
            "examples": [
              "Amul Pure Ghee"
            ]
          },
          "brand": {
            "type": [
              "null",
              "string"
            ],
            "title": "Brand",
            "description": "Brand as the retailer showed it; null when none.",
            "examples": [
              "Amul"
            ]
          },
          "packSizeRaw": {
            "type": [
              "null",
              "string"
            ],
            "title": "Pack size",
            "description": "Pack size as shown.",
            "examples": [
              "1 l"
            ]
          },
          "priceMinor": {
            "type": "integer",
            "minimum": 0,
            "title": "Price",
            "description": "Selling price shown, in paise.",
            "examples": [
              65000
            ]
          },
          "mrpMinor": {
            "type": [
              "null",
              "integer"
            ],
            "minimum": 0,
            "title": "MRP",
            "description": "List price shown, in paise; null when none.",
            "examples": [
              69000
            ]
          },
          "currency": {
            "const": "INR",
            "title": "Currency",
            "description": "Always INR.",
            "examples": [
              "INR"
            ]
          },
          "inStock": {
            "type": [
              "null",
              "boolean"
            ],
            "title": "In stock",
            "description": "Whether the retailer showed it in stock at that pin; null when it did not say.",
            "examples": [
              true
            ]
          },
          "pincode": {
            "type": "string",
            "title": "Pin code",
            "description": "The pin the reading was taken at.",
            "examples": [
              "560001"
            ],
            "pattern": "^[1-9][0-9]{5}$"
          },
          "city": {
            "type": [
              "null",
              "string"
            ],
            "title": "City",
            "description": "The pin's city from the India Post directory; null when none.",
            "examples": [
              "Bengaluru"
            ]
          },
          "observedAt": {
            "type": "string",
            "title": "Seen at",
            "description": "When the reading was taken.",
            "examples": [
              "2026-09-27T05:10:00.000000Z"
            ],
            "format": "date-time"
          },
          "sourceUrl": {
            "type": [
              "null",
              "string"
            ],
            "title": "Source URL",
            "description": "Evidence: the page the reading came from.",
            "examples": [
              "https://blinkit.com/prn/x/prid/400001"
            ]
          },
          "evidenceSha256": {
            "type": [
              "null",
              "string"
            ],
            "pattern": "^[0-9a-f]{64}$",
            "title": "Evidence SHA-256",
            "description": "Evidence: SHA-256 of what was fetched.",
            "examples": [
              "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
            ]
          }
        }
      },
      "DemoRetailerSummary": {
        "type": "object",
        "title": "Retailer summary",
        "description": "What the sample shows for one retailer. Counts and ranges only; no brand is ranked.",
        "additionalProperties": false,
        "required": [
          "retailer",
          "listings",
          "brands",
          "pincodes",
          "cities",
          "price",
          "belowMrp",
          "availability"
        ],
        "properties": {
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "Retailer key.",
            "examples": [
              "blinkit"
            ],
            "enum": [
              "blinkit",
              "instamart",
              "zepto"
            ]
          },
          "listings": {
            "type": "integer",
            "minimum": 0,
            "title": "Listings",
            "description": "Listings in the sample.",
            "examples": [
              40
            ]
          },
          "brands": {
            "type": "integer",
            "minimum": 0,
            "title": "Brands",
            "description": "Distinct brands among them.",
            "examples": [
              25
            ]
          },
          "pincodes": {
            "type": "integer",
            "minimum": 0,
            "title": "Pin codes",
            "description": "Distinct pins the readings were taken at.",
            "examples": [
              12
            ]
          },
          "cities": {
            "type": "array",
            "title": "Cities",
            "description": "Cities of those pins, alphabetical.",
            "items": {
              "type": "string",
              "examples": [
                "Bengaluru"
              ]
            }
          },
          "price": {
            "type": [
              "null",
              "object"
            ],
            "title": "Price range",
            "description": "Lowest, middle and highest price shown, in paise.",
            "additionalProperties": false,
            "required": [
              "minMinor",
              "medianMinor",
              "maxMinor"
            ],
            "properties": {
              "minMinor": {
                "type": "integer",
                "minimum": 0,
                "title": "Lowest",
                "description": "Lowest price, paise.",
                "examples": [
                  4500
                ]
              },
              "medianMinor": {
                "type": "integer",
                "minimum": 0,
                "title": "Middle",
                "description": "The middle reading (lower of two when even): a real price, never an average.",
                "examples": [
                  61000
                ]
              },
              "maxMinor": {
                "type": "integer",
                "minimum": 0,
                "title": "Highest",
                "description": "Highest price, paise.",
                "examples": [
                  285000
                ]
              }
            }
          },
          "belowMrp": {
            "type": "integer",
            "minimum": 0,
            "title": "Below MRP",
            "description": "Listings priced below the MRP shown.",
            "examples": [
              18
            ]
          },
          "availability": {
            "type": "object",
            "title": "Availability",
            "description": "Listings shown in stock, out of stock, or with no stock said.",
            "additionalProperties": false,
            "required": [
              "inStock",
              "outOfStock",
              "unknown",
              "inStockShare"
            ],
            "properties": {
              "inStock": {
                "type": "integer",
                "minimum": 0,
                "title": "In stock",
                "description": "Listings shown in stock.",
                "examples": [
                  30
                ]
              },
              "outOfStock": {
                "type": "integer",
                "minimum": 0,
                "title": "Out of stock",
                "description": "Listings shown out of stock.",
                "examples": [
                  4
                ]
              },
              "unknown": {
                "type": "integer",
                "minimum": 0,
                "title": "Not said",
                "description": "Listings with no stock said.",
                "examples": [
                  0
                ]
              },
              "inStockShare": {
                "type": [
                  "null",
                  "number"
                ],
                "minimum": 0,
                "maximum": 1,
                "title": "In-stock share",
                "description": "In stock / (in stock + out of stock), 4 decimals; null when none said.",
                "examples": [
                  0.8824
                ]
              }
            }
          }
        }
      },
      "DemoChart": {
        "type": "object",
        "title": "Demo chart",
        "description": "One chart: its series are exactly the groups of GET /v1/data/series (contract 0.50), grouped by retailer.",
        "additionalProperties": false,
        "required": [
          "id",
          "title",
          "metric",
          "groupBy",
          "firstDay",
          "lastDay",
          "data"
        ],
        "properties": {
          "id": {
            "type": "string",
            "title": "Id",
            "description": "Stable chart id.",
            "examples": [
              "price_by_retailer"
            ]
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "Chart title.",
            "examples": [
              "Ghee price by retailer"
            ]
          },
          "metric": {
            "type": "string",
            "title": "Metric",
            "description": "What to draw from each point.",
            "examples": [
              "price"
            ],
            "enum": [
              "price",
              "availability"
            ]
          },
          "groupBy": {
            "const": "retailer",
            "title": "Group by",
            "description": "Always retailer.",
            "examples": [
              "retailer"
            ]
          },
          "firstDay": {
            "type": "string",
            "title": "First day",
            "description": "First IST day.",
            "examples": [
              "2026-09-14"
            ],
            "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
          },
          "lastDay": {
            "type": "string",
            "title": "Last day",
            "description": "Last IST day (the snapshot day).",
            "examples": [
              "2026-09-27"
            ],
            "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
          },
          "data": {
            "type": "array",
            "title": "Groups",
            "description": "One group per retailer, every IST day, honest gaps.",
            "items": {
              "type": "object",
              "title": "Series group",
              "description": "One group and its days.",
              "additionalProperties": false,
              "required": [
                "key",
                "points"
              ],
              "properties": {
                "key": {
                  "type": "object",
                  "title": "Group",
                  "description": "What the group is along the groupBy dimension; the other fields are null.",
                  "additionalProperties": false,
                  "required": [
                    "retailer",
                    "pincode",
                    "brand",
                    "productId"
                  ],
                  "properties": {
                    "retailer": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Retailer",
                      "description": "The retailer key.",
                      "examples": [
                        "blinkit"
                      ]
                    },
                    "pincode": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Pin code",
                      "description": "The pin code, or national.",
                      "examples": [
                        "110092"
                      ],
                      "pattern": "^([1-9][0-9]{5}|national)$"
                    },
                    "brand": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Brand",
                      "description": "The brand as the retailer wrote it.",
                      "examples": [
                        "Aashirvaad"
                      ]
                    },
                    "productId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Product",
                      "description": "The Rewalto product id.",
                      "examples": [
                        "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
                      ],
                      "format": "uuid"
                    }
                  }
                },
                "points": {
                  "type": "array",
                  "title": "Points",
                  "description": "Every IST day of the window, gaps included.",
                  "items": {
                    "type": "object",
                    "title": "Series point",
                    "description": "One IST day of one group.",
                    "additionalProperties": false,
                    "required": [
                      "day",
                      "gap",
                      "partial",
                      "readings",
                      "price",
                      "availability",
                      "position"
                    ],
                    "properties": {
                      "day": {
                        "type": "string",
                        "title": "Day",
                        "description": "The IST calendar day.",
                        "examples": [
                          "2026-10-14"
                        ],
                        "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                      },
                      "gap": {
                        "type": "boolean",
                        "title": "Gap",
                        "description": "True when no reading exists for this day; the values are null.",
                        "examples": [
                          false
                        ]
                      },
                      "partial": {
                        "type": "boolean",
                        "title": "Partial",
                        "description": "True when the window starts or ends inside this day.",
                        "examples": [
                          false
                        ]
                      },
                      "readings": {
                        "type": "integer",
                        "title": "Readings",
                        "description": "How many readings of the day are in this point.",
                        "examples": [
                          12
                        ],
                        "minimum": 0
                      },
                      "price": {
                        "type": [
                          "null",
                          "object"
                        ],
                        "title": "Price",
                        "description": "The prices readings showed on this day; null on a gap or when no reading showed a price.",
                        "additionalProperties": false,
                        "required": [
                          "minMinor",
                          "medianMinor",
                          "maxMinor",
                          "mrpMedianMinor",
                          "readings"
                        ],
                        "properties": {
                          "minMinor": {
                            "type": "integer",
                            "title": "Lowest price",
                            "description": "Lowest price of the day, in paise.",
                            "examples": [
                              28500
                            ],
                            "minimum": 0
                          },
                          "medianMinor": {
                            "type": "integer",
                            "title": "Middle price",
                            "description": "The middle reading of the day (a real reading, not an average), in paise.",
                            "examples": [
                              28500
                            ],
                            "minimum": 0
                          },
                          "maxMinor": {
                            "type": "integer",
                            "title": "Highest price",
                            "description": "Highest price of the day, in paise.",
                            "examples": [
                              29900
                            ],
                            "minimum": 0
                          },
                          "mrpMedianMinor": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Middle MRP",
                            "description": "The middle list price among readings that showed one, in paise; null when none did.",
                            "examples": [
                              31000
                            ],
                            "minimum": 0
                          },
                          "readings": {
                            "type": "integer",
                            "title": "Priced readings",
                            "description": "How many readings of the day showed a price.",
                            "examples": [
                              12
                            ],
                            "minimum": 1
                          }
                        }
                      },
                      "availability": {
                        "type": [
                          "null",
                          "object"
                        ],
                        "title": "Stock",
                        "description": "Readings counted by what they said; null on a gap.",
                        "additionalProperties": false,
                        "required": [
                          "inStock",
                          "outOfStock",
                          "unknown",
                          "inStockShare"
                        ],
                        "properties": {
                          "inStock": {
                            "type": "integer",
                            "title": "In stock",
                            "description": "Readings that said in stock.",
                            "examples": [
                              10
                            ],
                            "minimum": 0
                          },
                          "outOfStock": {
                            "type": "integer",
                            "title": "Out of stock",
                            "description": "Readings that said out of stock.",
                            "examples": [
                              2
                            ],
                            "minimum": 0
                          },
                          "unknown": {
                            "type": "integer",
                            "title": "Unknown",
                            "description": "Readings that did not say (every Flipkart reading).",
                            "examples": [
                              0
                            ],
                            "minimum": 0
                          },
                          "inStockShare": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "In-stock share",
                            "description": "In stock out of the readings that said; null when none said.",
                            "examples": [
                              0.83
                            ],
                            "minimum": 0,
                            "maximum": 1
                          }
                        }
                      },
                      "position": {
                        "type": [
                          "null",
                          "object"
                        ],
                        "title": "Search position",
                        "description": "The place in the retailer's search results, from readings that recorded one; null when none did. Not a category rank.",
                        "additionalProperties": false,
                        "required": [
                          "best",
                          "average",
                          "readings"
                        ],
                        "properties": {
                          "best": {
                            "type": "integer",
                            "title": "Best place",
                            "description": "The lowest (best) place of the day.",
                            "examples": [
                              2
                            ],
                            "minimum": 1
                          },
                          "average": {
                            "type": "number",
                            "title": "Average place",
                            "description": "The average place of the day, to two decimals.",
                            "examples": [
                              3.5
                            ],
                            "minimum": 1
                          },
                          "readings": {
                            "type": "integer",
                            "title": "Readings",
                            "description": "How many readings recorded a place.",
                            "examples": [
                              4
                            ],
                            "minimum": 1
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "DemoSnapshot": {
        "type": "object",
        "title": "Demo snapshot",
        "description": "A fixed, real sample of one category across Blinkit, Instamart and Zepto, from Rewalto data. Labelled a sample; names no customer; ranks no brand.",
        "additionalProperties": false,
        "required": [
          "version",
          "sample",
          "title",
          "category",
          "snapshotDay",
          "readingWindow",
          "retailers",
          "listings",
          "summary",
          "charts",
          "notes"
        ],
        "properties": {
          "version": {
            "const": 1,
            "title": "Version",
            "description": "Snapshot format version.",
            "examples": [
              1
            ]
          },
          "sample": {
            "const": true,
            "title": "Sample",
            "description": "Always true: a sample, not your own data.",
            "examples": [
              true
            ]
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "Display title.",
            "examples": [
              "Ghee on quick commerce: a Rewalto sample"
            ]
          },
          "category": {
            "type": "object",
            "title": "Category",
            "description": "The category shown.",
            "additionalProperties": false,
            "required": [
              "id",
              "name"
            ],
            "properties": {
              "id": {
                "type": "string",
                "title": "Id",
                "description": "Category id.",
                "examples": [
                  "ghee"
                ]
              },
              "name": {
                "type": "string",
                "title": "Name",
                "description": "Category name.",
                "examples": [
                  "Ghee"
                ]
              }
            }
          },
          "snapshotDay": {
            "type": "string",
            "title": "Snapshot day",
            "description": "The pinned IST day the sample stands for.",
            "examples": [
              "2026-09-27"
            ],
            "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
          },
          "readingWindow": {
            "type": "object",
            "title": "Reading window",
            "description": "The IST days the readings may come from.",
            "additionalProperties": false,
            "required": [
              "firstDay",
              "lastDay"
            ],
            "properties": {
              "firstDay": {
                "type": "string",
                "title": "First day",
                "description": "First IST day.",
                "examples": [
                  "2026-09-25"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              },
              "lastDay": {
                "type": "string",
                "title": "Last day",
                "description": "Last IST day (the snapshot day).",
                "examples": [
                  "2026-09-27"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              }
            }
          },
          "retailers": {
            "type": "array",
            "title": "Retailers",
            "description": "Retailers in the sample, alphabetical.",
            "items": {
              "type": "string",
              "title": "Retailer",
              "description": "Retailer key.",
              "examples": [
                "blinkit"
              ],
              "enum": [
                "blinkit",
                "instamart",
                "zepto"
              ]
            }
          },
          "listings": {
            "type": "array",
            "title": "Listings",
            "description": "The listings, by retailer then brand alphabetically (unbranded last), title and SKU. Never by price.",
            "items": {
              "$ref": "#/components/schemas/DemoListing"
            }
          },
          "summary": {
            "type": "object",
            "title": "Summary",
            "description": "Counts and ranges; no ranking.",
            "additionalProperties": false,
            "required": [
              "listings",
              "brands",
              "byRetailer"
            ],
            "properties": {
              "listings": {
                "type": "integer",
                "minimum": 0,
                "title": "Listings",
                "description": "Listings in the sample.",
                "examples": [
                  120
                ]
              },
              "brands": {
                "type": "array",
                "title": "Brands",
                "description": "Every brand in the sample, alphabetical.",
                "items": {
                  "type": "string",
                  "examples": [
                    "Amul"
                  ]
                }
              },
              "byRetailer": {
                "type": "array",
                "title": "By retailer",
                "description": "One entry per retailer, alphabetical.",
                "items": {
                  "$ref": "#/components/schemas/DemoRetailerSummary"
                }
              }
            }
          },
          "charts": {
            "type": "array",
            "title": "Charts",
            "description": "Chart series, in the GET /v1/data/series shape.",
            "items": {
              "$ref": "#/components/schemas/DemoChart"
            }
          },
          "notes": {
            "type": "array",
            "title": "Notes",
            "description": "How the sample was made, in plain words.",
            "items": {
              "type": "string",
              "examples": [
                "Brands are listed alphabetically."
              ]
            }
          }
        }
      },
      "DemoWorkspace": {
        "type": "object",
        "title": "Demo workspace",
        "description": "The demo snapshot for a new account: real Rewalto data, free and read-only.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/DemoSnapshot"
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Labels and cost.",
            "additionalProperties": false,
            "required": [
              "sample",
              "illustrative",
              "snapshotDay",
              "credits"
            ],
            "properties": {
              "sample": {
                "const": true,
                "title": "Sample",
                "description": "Always true: label it as a sample.",
                "examples": [
                  true
                ]
              },
              "illustrative": {
                "const": false,
                "title": "Illustrative",
                "description": "Always false: real kept readings, never made up.",
                "examples": [
                  false
                ]
              },
              "snapshotDay": {
                "type": "string",
                "title": "Snapshot day",
                "description": "The pinned IST day.",
                "examples": [
                  "2026-09-27"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              },
              "credits": {
                "$ref": "#/components/schemas/NoCharge"
              }
            }
          }
        }
      },
      "Availability": {
        "type": "object",
        "title": "Availability at a pin",
        "description": "One retailer listing at one pin code: in stock, out of stock, or unknown with the reason. Never a guess: a state comes from one kept reading, named by its time and row id.",
        "additionalProperties": false,
        "required": [
          "listingId",
          "retailer",
          "retailerSku",
          "title",
          "pincode",
          "state",
          "reason",
          "exclusion",
          "readingAt",
          "observationId",
          "storeId",
          "storeIdFrom",
          "inventory"
        ],
        "properties": {
          "listingId": {
            "type": "string",
            "title": "Listing",
            "description": "The listing id (as in /v1/data/listings).",
            "examples": [
              "3b8f1c2a-6d4e-4a7b-9c10-2e5f8a1d4b66"
            ],
            "format": "uuid"
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer key.",
            "examples": [
              "blinkit"
            ]
          },
          "retailerSku": {
            "type": "string",
            "title": "Retailer product id",
            "description": "The retailer's own product id.",
            "examples": [
              "481203"
            ]
          },
          "title": {
            "type": [
              "null",
              "string"
            ],
            "title": "Name",
            "description": "The product name as the retailer lists it.",
            "examples": [
              "Aashirvaad Atta 5 kg"
            ]
          },
          "pincode": {
            "type": "string",
            "title": "Pin code",
            "description": "The pin code asked about.",
            "examples": [
              "110092"
            ],
            "pattern": "^[1-9][0-9]{5}$"
          },
          "state": {
            "type": "string",
            "title": "State",
            "description": "in_stock, out_of_stock, or unknown (see reason).",
            "examples": [
              "in_stock"
            ],
            "enum": [
              "in_stock",
              "out_of_stock",
              "unknown"
            ]
          },
          "reason": {
            "type": [
              "null",
              "string"
            ],
            "title": "Why unknown",
            "description": "stale: the newest reading at this pin is older than 48 hours (readingAt says when); no_reading_at_pin: not read at this pin in the last 30 days; stock_not_reported: the retailer's page does not say; excluded_pin_day: the reading falls on a pin-day left out of the data (exclusion says why). Null when the state is known.",
            "examples": [
              null
            ],
            "enum": [
              "stale",
              "no_reading_at_pin",
              "stock_not_reported",
              "excluded_pin_day",
              null
            ]
          },
          "exclusion": {
            "type": [
              "null",
              "object"
            ],
            "title": "Exclusion",
            "description": "For excluded_pin_day: why that pin-day is left out, and the decision.",
            "additionalProperties": false,
            "required": [
              "reason",
              "decision"
            ],
            "properties": {
              "reason": {
                "type": "string",
                "title": "Reason",
                "description": "Why the pin-day is left out.",
                "examples": [
                  "wrong_store_items"
                ]
              },
              "decision": {
                "type": "string",
                "title": "Decision",
                "description": "The decision that left it out.",
                "examples": [
                  "D-1468"
                ]
              }
            },
            "examples": [
              null
            ]
          },
          "readingAt": {
            "type": [
              "null",
              "string"
            ],
            "title": "Reading time",
            "description": "When the reading was taken; for stale and excluded_pin_day, the reading that was not used. Null when there is none.",
            "examples": [
              "2026-10-16T02:00:00Z"
            ],
            "format": "date-time"
          },
          "observationId": {
            "type": [
              "null",
              "string"
            ],
            "title": "Reading id",
            "description": "The id of the reading, as text.",
            "examples": [
              "48210377"
            ]
          },
          "storeId": {
            "type": [
              "null",
              "string"
            ],
            "title": "Store",
            "description": "The retailer's store (dark store) the reading came from, where the reading records it.",
            "examples": [
              "23154"
            ]
          },
          "storeIdFrom": {
            "type": [
              "null",
              "string"
            ],
            "title": "Store id field",
            "description": "Which field of the reading named the store.",
            "examples": [
              "merchant_id"
            ],
            "enum": [
              "store_id",
              "merchant_id",
              null
            ]
          },
          "inventory": {
            "type": [
              "null",
              "integer"
            ],
            "title": "Units shown",
            "description": "Units the retailer showed in stock, where it shows a count.",
            "examples": [
              12
            ]
          }
        }
      },
      "AvailabilityAnswer": {
        "type": "object",
        "title": "Availability answer",
        "description": "The answer, the staleness window it used and what it cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The answer rows.",
            "items": {
              "$ref": "#/components/schemas/Availability"
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from, how fresh it must be, and what the answer cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "staleAfterHours",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ],
                "enum": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "As of",
                "description": "The newest reading time among the rows; null when there is none.",
                "examples": [
                  "2026-10-16T02:00:00Z"
                ],
                "format": "date-time"
              },
              "staleAfterHours": {
                "type": "integer",
                "title": "Stale after (hours)",
                "description": "A reading older than this answers unknown.",
                "examples": [
                  48
                ],
                "minimum": 0
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "PinAvailability": {
        "type": "object",
        "title": "Availability at a pin, one retailer",
        "description": "How many of a retailer's listings read at this pin are in stock, by each listing's newest reading there. A listing counts as in or out of stock only if that reading is at most 48 hours old; the rest are counted as unknown, by reason.",
        "additionalProperties": false,
        "required": [
          "retailer",
          "pincode",
          "inStock",
          "outOfStock",
          "shareInStock",
          "unknown",
          "latestReadingAt"
        ],
        "properties": {
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer key.",
            "examples": [
              "blinkit"
            ]
          },
          "pincode": {
            "type": "string",
            "title": "Pin code",
            "description": "The pin code.",
            "examples": [
              "110092"
            ],
            "pattern": "^[1-9][0-9]{5}$"
          },
          "inStock": {
            "type": "integer",
            "title": "In stock",
            "description": "Listings whose fresh reading says in stock.",
            "examples": [
              3104
            ],
            "minimum": 0
          },
          "outOfStock": {
            "type": "integer",
            "title": "Out of stock",
            "description": "Listings whose fresh reading says out of stock.",
            "examples": [
              153
            ],
            "minimum": 0
          },
          "shareInStock": {
            "type": [
              "null",
              "number"
            ],
            "title": "Share in stock",
            "description": "inStock / (inStock + outOfStock), 0 to 1, 4 decimals; null when neither is known.",
            "examples": [
              0.953
            ],
            "minimum": 0,
            "maximum": 1
          },
          "unknown": {
            "type": "object",
            "title": "Unknown",
            "description": "Listings read at this pin in the last 30 days whose state is unknown, by reason.",
            "additionalProperties": false,
            "required": [
              "stale",
              "stockNotReported",
              "excludedPinDay"
            ],
            "properties": {
              "stale": {
                "type": "integer",
                "title": "Stale",
                "description": "Newest reading older than 48 hours.",
                "examples": [
                  410
                ],
                "minimum": 0
              },
              "stockNotReported": {
                "type": "integer",
                "title": "Stock not reported",
                "description": "The retailer's page does not say.",
                "examples": [
                  0
                ],
                "minimum": 0
              },
              "excludedPinDay": {
                "type": "integer",
                "title": "Excluded pin-day",
                "description": "The reading falls on a pin-day left out of the data.",
                "examples": [
                  0
                ],
                "minimum": 0
              }
            },
            "examples": [
              {
                "stale": 410,
                "stockNotReported": 0,
                "excludedPinDay": 0
              }
            ]
          },
          "latestReadingAt": {
            "type": [
              "null",
              "string"
            ],
            "title": "Newest reading",
            "description": "The newest reading counted in inStock or outOfStock.",
            "examples": [
              "2026-10-16T02:00:00Z"
            ],
            "format": "date-time"
          }
        }
      },
      "PinAvailabilityAnswer": {
        "type": "object",
        "title": "Pin availability answer",
        "description": "The answer, the staleness window it used and what it cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The answer rows.",
            "items": {
              "$ref": "#/components/schemas/PinAvailability"
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from, how fresh it must be, and what the answer cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "staleAfterHours",
              "credits",
              "refreshedAt"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ],
                "enum": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "As of",
                "description": "The newest reading time among the rows; null when there is none.",
                "examples": [
                  "2026-10-16T02:00:00Z"
                ],
                "format": "date-time"
              },
              "staleAfterHours": {
                "type": "integer",
                "title": "Stale after (hours)",
                "description": "A reading older than this answers unknown.",
                "examples": [
                  48
                ],
                "minimum": 0
              },
              "refreshedAt": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Summary refreshed",
                "description": "When the pin summary was last refreshed from the readings (hourly); null when it holds nothing for this pin.",
                "examples": [
                  "2026-10-16T03:05:00Z"
                ],
                "format": "date-time"
              },
              "credits": {
                "$ref": "#/components/schemas/ReadCredits"
              }
            }
          }
        }
      },
      "Location": {
        "type": "object",
        "title": "Location",
        "description": "One pin code with its customer-facing labels, centre point, stable filter ids, the kept coverage (rows we already hold, free to list) and, when a retailer was chosen, whether a fresh collection could run there.",
        "additionalProperties": false,
        "required": [
          "pincode",
          "locationId",
          "areaLocationId",
          "cityLocationId",
          "market",
          "area",
          "matchedArea",
          "city",
          "district",
          "state",
          "lat",
          "lng",
          "matchedOn",
          "kept",
          "fresh",
          "warnings"
        ],
        "properties": {
          "pincode": {
            "type": "string",
            "title": "Pin code",
            "description": "The six-digit pin code.",
            "examples": [
              "560034"
            ],
            "pattern": "^[1-9][0-9]{5}$"
          },
          "locationId": {
            "type": "string",
            "title": "Location id",
            "description": "The stable filter id of exactly this pin.",
            "examples": [
              "IN:pin:560034"
            ],
            "pattern": "^[A-Z]{2}:(pin:[1-9][0-9]{5}|city:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}|area:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}:[a-z0-9]{1,120}|store:[a-z0-9_]{2,40}:[A-Za-z0-9_-]{1,64})$"
          },
          "areaLocationId": {
            "type": [
              "null",
              "string"
            ],
            "title": "Area location id",
            "description": "The filter id of the matched area (every pin of the city with that post office name); null unless matchedOn is area.",
            "examples": [
              "IN:area:karnataka:bengaluru:koramangala"
            ]
          },
          "cityLocationId": {
            "type": [
              "null",
              "string"
            ],
            "title": "City location id",
            "description": "The filter id of the pin city; null when the directory has no city for the pin.",
            "examples": [
              "IN:city:karnataka:bengaluru"
            ]
          },
          "market": {
            "type": "string",
            "title": "Market",
            "description": "ISO 3166-1 country code of the market (Core Retailer.market).",
            "examples": [
              "IN"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "area": {
            "type": [
              "null",
              "string"
            ],
            "title": "Area",
            "description": "The pin main post office name, as a neighbourhood label.",
            "examples": [
              "Koramangala"
            ]
          },
          "matchedArea": {
            "type": [
              "null",
              "string"
            ],
            "title": "Matched area",
            "description": "The area name your query matched, when it matched an area; otherwise null.",
            "examples": [
              "Koramangala"
            ]
          },
          "city": {
            "type": [
              "null",
              "string"
            ],
            "title": "City",
            "description": "The city, as customers say it.",
            "examples": [
              "Bengaluru"
            ]
          },
          "district": {
            "type": [
              "null",
              "string"
            ],
            "title": "District",
            "description": "The India Post district.",
            "examples": [
              "BENGALURU URBAN"
            ]
          },
          "state": {
            "type": [
              "null",
              "string"
            ],
            "title": "State",
            "description": "The state.",
            "examples": [
              "KARNATAKA"
            ]
          },
          "lat": {
            "type": [
              "null",
              "number"
            ],
            "title": "Latitude",
            "description": "Centre latitude of the pin.",
            "examples": [
              12.9352
            ]
          },
          "lng": {
            "type": [
              "null",
              "number"
            ],
            "title": "Longitude",
            "description": "Centre longitude of the pin.",
            "examples": [
              77.6245
            ]
          },
          "matchedOn": {
            "type": "string",
            "enum": [
              "pincode",
              "city",
              "area",
              "district",
              "none"
            ],
            "title": "Matched on",
            "description": "What your words matched; none when no words were given.",
            "examples": [
              "area"
            ]
          },
          "kept": {
            "type": "object",
            "title": "Kept coverage",
            "description": "Rows Rewalto already holds for this pin, free to list. Reading them with a paid read is charged by the records delivered.",
            "additionalProperties": false,
            "required": [
              "retailers",
              "lastSeenDay"
            ],
            "properties": {
              "retailers": {
                "type": "array",
                "title": "Retailers with data",
                "description": "Retailer keys with a reading here on any of the last 30 IST days, sorted.",
                "items": {
                  "type": "string",
                  "examples": [
                    "blinkit"
                  ]
                }
              },
              "lastSeenDay": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Last seen day",
                "description": "The newest IST day any retailer read this place within the data window; null when none did.",
                "examples": [
                  "2026-10-20"
                ]
              }
            }
          },
          "fresh": {
            "type": [
              "null",
              "object"
            ],
            "title": "Fresh collection eligibility",
            "description": "Whether a new on-demand collection could run at this pin for the chosen retailer (the catalogue freshRead). Null when no retailer was chosen. Choosing a place never starts it: a run needs a quote and an explicit approval.",
            "additionalProperties": false,
            "required": [
              "retailer",
              "eligible",
              "reason"
            ],
            "properties": {
              "retailer": {
                "type": "string",
                "title": "Retailer",
                "description": "The retailer asked about.",
                "examples": [
                  "blinkit"
                ]
              },
              "eligible": {
                "type": "boolean",
                "title": "Eligible",
                "description": "True when a fresh run could ask for this pin.",
                "examples": [
                  true
                ]
              },
              "reason": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Reason",
                "description": "Null when eligible; otherwise the catalogue freshRead reason (not_a_recipe, no_recipe, planned, not_published, not_priced, no_running_lane, not_checked) or pin_not_served (the retailer lane does not serve this pin).",
                "examples": [
                  "pin_not_served"
                ]
              }
            }
          },
          "warnings": {
            "type": "array",
            "title": "Warnings",
            "description": "Reasons to confirm with the person choosing: the city name exists in more than one state, the area name exists in more than one city, the pin covers several areas, or the pin centre is an estimate from neighbouring pins.",
            "items": {
              "type": "string",
              "enum": [
                "city_name_in_several_states",
                "area_name_in_several_cities",
                "pin_spans_several_areas",
                "centre_estimated"
              ],
              "examples": [
                "pin_spans_several_areas"
              ]
            }
          }
        }
      },
      "LocationsPage": {
        "type": "object",
        "title": "Locations page",
        "description": "One page of records with paging. Free: nothing is charged.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page.",
            "items": {
              "$ref": "#/components/schemas/Location"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  50
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMTk3MC0wMS0wMVQwMDowMDowMC4wMDBaIiwiaSI6IjU2MDAzNCIsImYiOiJhYmMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from, what the lookup concluded, and that it is free.",
            "additionalProperties": false,
            "required": [
              "kind",
              "market",
              "supported",
              "resolution",
              "notes",
              "dataWindowDays",
              "asOfDay",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "reference"
                ],
                "title": "Kind",
                "description": "reference: India Post pin directory joined with the daily coverage summary.",
                "examples": [
                  "reference"
                ]
              },
              "market": {
                "type": "string",
                "title": "Market",
                "description": "ISO 3166-1 country code of the market (Core Retailer.market).",
                "examples": [
                  "IN"
                ],
                "pattern": "^[A-Z]{2}$"
              },
              "supported": {
                "type": "boolean",
                "title": "Supported",
                "description": "False when the market has no location directory: the answer is then empty on purpose, never a guess.",
                "examples": [
                  true
                ]
              },
              "resolution": {
                "type": "string",
                "enum": [
                  "listing",
                  "unique",
                  "ambiguous",
                  "no_match",
                  "unsupported_market"
                ],
                "title": "Resolution",
                "description": "listing: no words were given. unique: the words point at one place. ambiguous: they point at more than one city or state, so ask the person. no_match: nothing matched. unsupported_market: the market has no location directory.",
                "examples": [
                  "unique"
                ]
              },
              "notes": {
                "type": "array",
                "title": "Notes",
                "description": "pin_not_in_directory: a six-digit pin that India Post does not list. market_has_no_location_directory: see supported.",
                "items": {
                  "type": "string",
                  "enum": [
                    "pin_not_in_directory",
                    "market_has_no_location_directory"
                  ],
                  "examples": [
                    "pin_not_in_directory"
                  ]
                }
              },
              "dataWindowDays": {
                "type": "integer",
                "title": "Data window",
                "description": "Days back that kept coverage looks at.",
                "examples": [
                  30
                ]
              },
              "asOfDay": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Coverage as of",
                "description": "The newest IST day in the coverage summary; null when it is empty.",
                "examples": [
                  "2026-10-20"
                ]
              },
              "credits": {
                "type": "object",
                "title": "Credits",
                "description": "Always free.",
                "additionalProperties": false,
                "required": [
                  "charged",
                  "units",
                  "freeReread",
                  "rate"
                ],
                "properties": {
                  "charged": {
                    "type": "integer",
                    "title": "Charged",
                    "description": "Credits charged: always 0.",
                    "examples": [
                      0
                    ]
                  },
                  "units": {
                    "type": "integer",
                    "title": "Units",
                    "description": "Always 0.",
                    "examples": [
                      0
                    ]
                  },
                  "freeReread": {
                    "type": "boolean",
                    "title": "Free re-read",
                    "description": "Always false.",
                    "examples": [
                      false
                    ]
                  },
                  "rate": {
                    "type": "null",
                    "title": "Rate",
                    "description": "Always null: no rate applies."
                  }
                }
              }
            }
          }
        }
      },
      "LocationCity": {
        "type": "object",
        "title": "City",
        "description": "One city with how many pin codes it has, the kept coverage and, when a retailer was chosen, how many of its pins a fresh collection could serve. Read its pins with GET /v1/data/locations/filter; pick the ones to read.",
        "additionalProperties": false,
        "required": [
          "locationId",
          "market",
          "city",
          "state",
          "pincodes",
          "kept",
          "fresh",
          "warnings"
        ],
        "properties": {
          "locationId": {
            "type": "string",
            "title": "Location id",
            "description": "The stable filter id of the city (one per state when a name repeats).",
            "examples": [
              "IN:city:karnataka:bengaluru"
            ],
            "pattern": "^[A-Z]{2}:(pin:[1-9][0-9]{5}|city:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}|area:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}:[a-z0-9]{1,120}|store:[a-z0-9_]{2,40}:[A-Za-z0-9_-]{1,64})$"
          },
          "market": {
            "type": "string",
            "title": "Market",
            "description": "ISO 3166-1 country code of the market (Core Retailer.market).",
            "examples": [
              "IN"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "city": {
            "type": "string",
            "title": "City",
            "description": "The city.",
            "examples": [
              "Bengaluru"
            ]
          },
          "state": {
            "type": [
              "null",
              "string"
            ],
            "title": "State",
            "description": "The state.",
            "examples": [
              "KARNATAKA"
            ]
          },
          "pincodes": {
            "type": "integer",
            "title": "Pin codes",
            "description": "How many pin codes the city has.",
            "examples": [
              112
            ]
          },
          "kept": {
            "type": "object",
            "title": "Kept coverage",
            "description": "Rows already held, free to list.",
            "additionalProperties": false,
            "required": [
              "retailers",
              "lastSeenDay",
              "pincodesWithData"
            ],
            "properties": {
              "retailers": {
                "type": "array",
                "title": "Retailers with data",
                "description": "Retailer keys with a reading here on any of the last 30 IST days, sorted.",
                "items": {
                  "type": "string",
                  "examples": [
                    "blinkit"
                  ]
                }
              },
              "lastSeenDay": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Last seen day",
                "description": "The newest IST day any retailer read this place within the data window; null when none did.",
                "examples": [
                  "2026-10-20"
                ]
              },
              "pincodesWithData": {
                "type": "integer",
                "title": "Pin codes with data",
                "description": "How many of the city pins have readings in the window (for the chosen retailer, when one is chosen).",
                "examples": [
                  4
                ]
              }
            }
          },
          "fresh": {
            "type": [
              "null",
              "object"
            ],
            "title": "Fresh collection eligibility",
            "description": "For the chosen retailer: how many of the city pins a fresh collection could serve. Null when no retailer was chosen.",
            "additionalProperties": false,
            "required": [
              "retailer",
              "eligiblePincodes",
              "reason"
            ],
            "properties": {
              "retailer": {
                "type": "string",
                "title": "Retailer",
                "description": "The retailer asked about.",
                "examples": [
                  "blinkit"
                ]
              },
              "eligiblePincodes": {
                "type": "integer",
                "title": "Eligible pin codes",
                "description": "Pins a fresh run could ask for.",
                "examples": [
                  112
                ]
              },
              "reason": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Reason",
                "description": "Why none are eligible (the catalogue freshRead reason); null when some are.",
                "examples": [
                  "no_running_lane"
                ]
              }
            }
          },
          "warnings": {
            "type": "array",
            "title": "Warnings",
            "description": "Reasons to confirm with the person choosing: the city name exists in more than one state, the area name exists in more than one city, the pin covers several areas, or the pin centre is an estimate from neighbouring pins.",
            "items": {
              "type": "string",
              "enum": [
                "city_name_in_several_states",
                "area_name_in_several_cities",
                "pin_spans_several_areas",
                "centre_estimated"
              ],
              "examples": [
                "pin_spans_several_areas"
              ]
            }
          }
        }
      },
      "LocationCitiesPage": {
        "type": "object",
        "title": "Cities page",
        "description": "One page of records with paging. Free: nothing is charged.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page.",
            "items": {
              "$ref": "#/components/schemas/LocationCity"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  50
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMTk3MC0wMS0wMVQwMDowMDowMC4wMDBaIiwiaSI6IjU2MDAzNCIsImYiOiJhYmMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from, what the lookup concluded, and that it is free.",
            "additionalProperties": false,
            "required": [
              "kind",
              "market",
              "supported",
              "resolution",
              "notes",
              "dataWindowDays",
              "asOfDay",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "reference"
                ],
                "title": "Kind",
                "description": "reference: India Post pin directory joined with the daily coverage summary.",
                "examples": [
                  "reference"
                ]
              },
              "market": {
                "type": "string",
                "title": "Market",
                "description": "ISO 3166-1 country code of the market (Core Retailer.market).",
                "examples": [
                  "IN"
                ],
                "pattern": "^[A-Z]{2}$"
              },
              "supported": {
                "type": "boolean",
                "title": "Supported",
                "description": "False when the market has no location directory: the answer is then empty on purpose, never a guess.",
                "examples": [
                  true
                ]
              },
              "resolution": {
                "type": "string",
                "enum": [
                  "listing",
                  "unique",
                  "ambiguous",
                  "no_match",
                  "unsupported_market"
                ],
                "title": "Resolution",
                "description": "listing: no words were given. unique: the words point at one place. ambiguous: they point at more than one city or state, so ask the person. no_match: nothing matched. unsupported_market: the market has no location directory.",
                "examples": [
                  "unique"
                ]
              },
              "notes": {
                "type": "array",
                "title": "Notes",
                "description": "pin_not_in_directory: a six-digit pin that India Post does not list. market_has_no_location_directory: see supported.",
                "items": {
                  "type": "string",
                  "enum": [
                    "pin_not_in_directory",
                    "market_has_no_location_directory"
                  ],
                  "examples": [
                    "pin_not_in_directory"
                  ]
                }
              },
              "dataWindowDays": {
                "type": "integer",
                "title": "Data window",
                "description": "Days back that kept coverage looks at.",
                "examples": [
                  30
                ]
              },
              "asOfDay": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Coverage as of",
                "description": "The newest IST day in the coverage summary; null when it is empty.",
                "examples": [
                  "2026-10-20"
                ]
              },
              "credits": {
                "type": "object",
                "title": "Credits",
                "description": "Always free.",
                "additionalProperties": false,
                "required": [
                  "charged",
                  "units",
                  "freeReread",
                  "rate"
                ],
                "properties": {
                  "charged": {
                    "type": "integer",
                    "title": "Charged",
                    "description": "Credits charged: always 0.",
                    "examples": [
                      0
                    ]
                  },
                  "units": {
                    "type": "integer",
                    "title": "Units",
                    "description": "Always 0.",
                    "examples": [
                      0
                    ]
                  },
                  "freeReread": {
                    "type": "boolean",
                    "title": "Free re-read",
                    "description": "Always false.",
                    "examples": [
                      false
                    ]
                  },
                  "rate": {
                    "type": "null",
                    "title": "Rate",
                    "description": "Always null: no rate applies."
                  }
                }
              }
            }
          }
        }
      },
      "LocationFilter": {
        "type": "object",
        "title": "Location filter",
        "description": "One location id resolved to its explicit pin codes, what is kept there, where a fresh collection could run, and exactly what a paid read of it needs. Nothing here is charged and nothing is started.",
        "additionalProperties": false,
        "required": [
          "location",
          "pincodes",
          "pincodeCount",
          "maxPincodes",
          "readable",
          "notReadableReason",
          "kept",
          "fresh",
          "paidRead"
        ],
        "properties": {
          "location": {
            "type": "object",
            "title": "Location",
            "description": "The place the id names.",
            "additionalProperties": false,
            "required": [
              "id",
              "kind",
              "label",
              "market",
              "country",
              "city",
              "state",
              "area"
            ],
            "properties": {
              "id": {
                "type": "string",
                "title": "Location id",
                "description": "The stable filter id.",
                "examples": [
                  "IN:city:karnataka:bengaluru"
                ],
                "pattern": "^[A-Z]{2}:(pin:[1-9][0-9]{5}|city:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}|area:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}:[a-z0-9]{1,120}|store:[a-z0-9_]{2,40}:[A-Za-z0-9_-]{1,64})$"
              },
              "kind": {
                "type": "string",
                "enum": [
                  "pin",
                  "city",
                  "area",
                  "store"
                ],
                "title": "Kind",
                "description": "What the id names. A store id (IN:store:<retailer>:<store id>) means the pin codes that dark store serves (its catchment as the sweeps saw it). Readings are kept per pin code, not per store, so it reads every kept reading at those pin codes, whichever store served them; no reading is attributed to the store itself.",
                "examples": [
                  "city"
                ]
              },
              "label": {
                "type": "string",
                "title": "Label",
                "description": "A customer-facing label.",
                "examples": [
                  "Bengaluru, Karnataka"
                ]
              },
              "market": {
                "type": "string",
                "title": "Market",
                "description": "ISO 3166-1 country code of the market (Core Retailer.market).",
                "examples": [
                  "IN"
                ],
                "pattern": "^[A-Z]{2}$"
              },
              "country": {
                "type": "string",
                "title": "Country",
                "description": "ISO 3166-1 country code.",
                "examples": [
                  "IN"
                ]
              },
              "city": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "City",
                "description": "The city, when the id names one.",
                "examples": [
                  "Bengaluru"
                ]
              },
              "state": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "State",
                "description": "The state.",
                "examples": [
                  "KARNATAKA"
                ]
              },
              "area": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Area",
                "description": "The area, when the id names one; for a store, the area of the lowest pin code it serves.",
                "examples": [
                  "Koramangala"
                ]
              }
            }
          },
          "pincodes": {
            "type": "array",
            "title": "Pin codes",
            "description": "Every pin code the id resolves to, ascending: the exact list a paid read with this location covers. Never cut: a place with more than maxPincodes is not readable.",
            "items": {
              "type": "string",
              "pattern": "^[1-9][0-9]{5}$",
              "examples": [
                "560034"
              ]
            }
          },
          "pincodeCount": {
            "type": "integer",
            "title": "Pin code count",
            "description": "How many pins the list holds (the value for confirmPins).",
            "examples": [
              112
            ]
          },
          "maxPincodes": {
            "type": "integer",
            "title": "Most pins",
            "description": "The most pins one paid read may cover.",
            "examples": [
              200
            ]
          },
          "readable": {
            "type": "boolean",
            "title": "Readable",
            "description": "True when a paid read of this location is allowed.",
            "examples": [
              true
            ]
          },
          "notReadableReason": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "no_pins",
              "too_many_pins",
              null
            ],
            "title": "Not readable reason",
            "description": "Why not, when not readable.",
            "examples": [
              null
            ]
          },
          "kept": {
            "type": "object",
            "title": "Kept coverage",
            "description": "Rows already held for these pins, free to list. Per retailer, within the window.",
            "additionalProperties": false,
            "required": [
              "pincodesWithData",
              "retailers",
              "lastSeenDay",
              "byRetailer"
            ],
            "properties": {
              "pincodesWithData": {
                "type": "integer",
                "title": "Pins with data",
                "description": "Pins with readings by any retailer.",
                "examples": [
                  4
                ]
              },
              "retailers": {
                "type": "array",
                "title": "Retailers with data",
                "description": "Retailer keys with a reading here on any of the last 30 IST days, sorted.",
                "items": {
                  "type": "string",
                  "examples": [
                    "blinkit"
                  ]
                }
              },
              "lastSeenDay": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Last seen day",
                "description": "The newest IST day any retailer read this place within the data window; null when none did.",
                "examples": [
                  "2026-10-20"
                ]
              },
              "byRetailer": {
                "type": "array",
                "title": "By retailer",
                "description": "Per retailer: pins read and the newest day.",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "retailer",
                    "pincodes",
                    "lastSeenDay"
                  ],
                  "properties": {
                    "retailer": {
                      "type": "string",
                      "title": "Retailer",
                      "description": "The retailer.",
                      "examples": [
                        "blinkit"
                      ]
                    },
                    "pincodes": {
                      "type": "integer",
                      "title": "Pins",
                      "description": "Pins of this location the retailer read.",
                      "examples": [
                        4
                      ]
                    },
                    "lastSeenDay": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Last seen day",
                      "description": "Newest day.",
                      "examples": [
                        "2026-10-20"
                      ]
                    }
                  }
                }
              }
            }
          },
          "fresh": {
            "type": "array",
            "title": "Fresh collection eligibility",
            "description": "Per retailer (the chosen one, else every retailer of the market the catalogue can run): whether a fresh run could cover these pins. A run needs a quote and an explicit approval; this lookup starts nothing.",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "retailer",
                "eligible",
                "reason",
                "pinScope",
                "eligiblePincodes",
                "maxPincodesPerRun",
                "runsNeeded"
              ],
              "properties": {
                "retailer": {
                  "type": "string",
                  "title": "Retailer",
                  "description": "The retailer.",
                  "examples": [
                    "blinkit"
                  ]
                },
                "eligible": {
                  "type": "boolean",
                  "title": "Eligible",
                  "description": "True when at least one pin can be run.",
                  "examples": [
                    true
                  ]
                },
                "reason": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "title": "Reason",
                  "description": "Why not, when not eligible.",
                  "examples": [
                    "no_running_lane"
                  ]
                },
                "pinScope": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "enum": [
                    "any",
                    "listed",
                    null
                  ],
                  "title": "Pin scope",
                  "description": "any: every pin; listed: only the lane pins; null: not offered.",
                  "examples": [
                    "any"
                  ]
                },
                "eligiblePincodes": {
                  "type": "integer",
                  "title": "Eligible pins",
                  "description": "How many of these pins a run could ask for.",
                  "examples": [
                    112
                  ]
                },
                "maxPincodesPerRun": {
                  "type": "integer",
                  "title": "Most pins per run",
                  "description": "The most pins one run may ask for.",
                  "examples": [
                    20
                  ]
                },
                "runsNeeded": {
                  "type": "integer",
                  "title": "Runs needed",
                  "description": "Runs needed to cover the eligible pins.",
                  "examples": [
                    6
                  ]
                }
              }
            }
          },
          "paidRead": {
            "type": "object",
            "title": "Paid read",
            "description": "What a paid read of this location needs. Choosing the place does none of it.",
            "additionalProperties": false,
            "required": [
              "selectionStartsPaidWork",
              "filterParam",
              "endpoints",
              "consent",
              "paging",
              "charging"
            ],
            "properties": {
              "selectionStartsPaidWork": {
                "type": "boolean",
                "title": "Selection starts paid work",
                "description": "Always false.",
                "examples": [
                  false
                ]
              },
              "filterParam": {
                "type": "string",
                "title": "Filter parameter",
                "description": "Send the id as this query parameter.",
                "examples": [
                  "location"
                ]
              },
              "endpoints": {
                "type": "array",
                "title": "Endpoints",
                "description": "The paid reads that accept the location filter.",
                "items": {
                  "type": "string",
                  "examples": [
                    "/v1/data/observations"
                  ]
                }
              },
              "consent": {
                "type": "object",
                "title": "Consent",
                "description": "A multi-pin read is refused unless confirmPins equals the number of pins shown here, so the person has seen the list. If the directory changed meanwhile, the read is refused with the new count.",
                "additionalProperties": false,
                "required": [
                  "param",
                  "value",
                  "required"
                ],
                "properties": {
                  "param": {
                    "type": "string",
                    "title": "Parameter",
                    "description": "The query parameter that carries the consent.",
                    "examples": [
                      "confirmPins"
                    ]
                  },
                  "value": {
                    "type": "integer",
                    "title": "Value",
                    "description": "The count to send (the current number of pins).",
                    "examples": [
                      112
                    ]
                  },
                  "required": {
                    "type": "boolean",
                    "title": "Required",
                    "description": "False only for a single pin.",
                    "examples": [
                      true
                    ]
                  }
                }
              },
              "paging": {
                "type": "string",
                "title": "Paging",
                "description": "How pages work for this read.",
                "examples": [
                  "Keyset pages of the read’s own page size over all the pins together; send the same location and confirmPins with every cursor."
                ]
              },
              "charging": {
                "type": "object",
                "title": "Charging",
                "description": "Charged exactly as the same read at one pin: by the records delivered on each page, at the published rate. The number of pins does not multiply the price. A page with no records, and a re-read within the free window, cost nothing.",
                "additionalProperties": false,
                "required": [
                  "basis",
                  "multipliedByPins",
                  "observations",
                  "listings"
                ],
                "properties": {
                  "basis": {
                    "type": "string",
                    "title": "Basis",
                    "description": "What is counted.",
                    "examples": [
                      "records_delivered"
                    ]
                  },
                  "multipliedByPins": {
                    "type": "boolean",
                    "title": "Multiplied by pins",
                    "description": "Always false.",
                    "examples": [
                      false
                    ]
                  },
                  "observations": {
                    "type": "object",
                    "title": "Observations rate",
                    "description": "The published rate this read is charged at (read the price on the rate card; it is never hard-coded in a client).",
                    "additionalProperties": false,
                    "required": [
                      "recipe",
                      "unit"
                    ],
                    "properties": {
                      "recipe": {
                        "type": "string",
                        "title": "Rate recipe",
                        "description": "The rate-card recipe.",
                        "examples": [
                          "library.commerce_history"
                        ]
                      },
                      "unit": {
                        "type": "string",
                        "title": "Rate unit",
                        "description": "What one unit is.",
                        "examples": [
                          "history_points"
                        ]
                      }
                    }
                  },
                  "listings": {
                    "type": "object",
                    "title": "Listings rate",
                    "description": "The published rate this read is charged at (read the price on the rate card; it is never hard-coded in a client).",
                    "additionalProperties": false,
                    "required": [
                      "recipe",
                      "unit"
                    ],
                    "properties": {
                      "recipe": {
                        "type": "string",
                        "title": "Rate recipe",
                        "description": "The rate-card recipe.",
                        "examples": [
                          "library.commerce_history"
                        ]
                      },
                      "unit": {
                        "type": "string",
                        "title": "Rate unit",
                        "description": "What one unit is.",
                        "examples": [
                          "history_points"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "LocationFilterAnswer": {
        "type": "object",
        "title": "Location filter answer",
        "description": "A resolved location filter. Free: nothing is charged.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/LocationFilter"
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from, what the lookup concluded, and that it is free.",
            "additionalProperties": false,
            "required": [
              "kind",
              "market",
              "supported",
              "resolution",
              "notes",
              "dataWindowDays",
              "asOfDay",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "reference"
                ],
                "title": "Kind",
                "description": "reference: India Post pin directory joined with the daily coverage summary.",
                "examples": [
                  "reference"
                ]
              },
              "market": {
                "type": "string",
                "title": "Market",
                "description": "ISO 3166-1 country code of the market (Core Retailer.market).",
                "examples": [
                  "IN"
                ],
                "pattern": "^[A-Z]{2}$"
              },
              "supported": {
                "type": "boolean",
                "title": "Supported",
                "description": "False when the market has no location directory: the answer is then empty on purpose, never a guess.",
                "examples": [
                  true
                ]
              },
              "resolution": {
                "type": "string",
                "enum": [
                  "listing",
                  "unique",
                  "ambiguous",
                  "no_match",
                  "unsupported_market"
                ],
                "title": "Resolution",
                "description": "listing: no words were given. unique: the words point at one place. ambiguous: they point at more than one city or state, so ask the person. no_match: nothing matched. unsupported_market: the market has no location directory.",
                "examples": [
                  "unique"
                ]
              },
              "notes": {
                "type": "array",
                "title": "Notes",
                "description": "pin_not_in_directory: a six-digit pin that India Post does not list. market_has_no_location_directory: see supported.",
                "items": {
                  "type": "string",
                  "enum": [
                    "pin_not_in_directory",
                    "market_has_no_location_directory"
                  ],
                  "examples": [
                    "pin_not_in_directory"
                  ]
                }
              },
              "dataWindowDays": {
                "type": "integer",
                "title": "Data window",
                "description": "Days back that kept coverage looks at.",
                "examples": [
                  30
                ]
              },
              "asOfDay": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Coverage as of",
                "description": "The newest IST day in the coverage summary; null when it is empty.",
                "examples": [
                  "2026-10-20"
                ]
              },
              "credits": {
                "type": "object",
                "title": "Credits",
                "description": "Always free.",
                "additionalProperties": false,
                "required": [
                  "charged",
                  "units",
                  "freeReread",
                  "rate"
                ],
                "properties": {
                  "charged": {
                    "type": "integer",
                    "title": "Charged",
                    "description": "Credits charged: always 0.",
                    "examples": [
                      0
                    ]
                  },
                  "units": {
                    "type": "integer",
                    "title": "Units",
                    "description": "Always 0.",
                    "examples": [
                      0
                    ]
                  },
                  "freeReread": {
                    "type": "boolean",
                    "title": "Free re-read",
                    "description": "Always false.",
                    "examples": [
                      false
                    ]
                  },
                  "rate": {
                    "type": "null",
                    "title": "Rate",
                    "description": "Always null: no rate applies."
                  }
                }
              }
            }
          }
        }
      },
      "LocationStore": {
        "type": "object",
        "title": "Dark store",
        "description": "One dark store of a quick-commerce retailer in a city, as Rewalto's sweeps found it, with the pin codes it serves and the kept coverage at those pins. A store id (IN:store:<retailer>:<store id>) means the pin codes that dark store serves (its catchment as the sweeps saw it). Readings are kept per pin code, not per store, so it reads every kept reading at those pin codes, whichever store served them; no reading is attributed to the store itself.",
        "additionalProperties": false,
        "required": [
          "locationId",
          "market",
          "retailer",
          "storeId",
          "label",
          "name",
          "area",
          "city",
          "state",
          "status",
          "sweepStatus",
          "firstSeenAt",
          "lastSeenAt",
          "closedAt",
          "pincodes",
          "kept"
        ],
        "properties": {
          "locationId": {
            "type": "string",
            "title": "Location id",
            "description": "The stable filter id of the store. Send it as location (with confirmPins) wherever a location is accepted.",
            "examples": [
              "IN:store:blinkit:35548"
            ],
            "pattern": "^[A-Z]{2}:(pin:[1-9][0-9]{5}|city:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}|area:[a-z0-9-]{1,100}:[a-z0-9-]{1,100}:[a-z0-9]{1,120}|store:[a-z0-9_]{2,40}:[A-Za-z0-9_-]{1,64})$"
          },
          "market": {
            "type": "string",
            "title": "Market",
            "description": "ISO 3166-1 country code of the market (Core Retailer.market).",
            "examples": [
              "IN"
            ],
            "pattern": "^[A-Z]{2}$"
          },
          "retailer": {
            "type": "string",
            "title": "Retailer",
            "description": "The retailer the store belongs to.",
            "examples": [
              "blinkit"
            ]
          },
          "storeId": {
            "type": "string",
            "title": "Store id",
            "description": "The retailer’s own id of the store.",
            "examples": [
              "35548"
            ]
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "A customer-facing label: the store name when the retailer gives one, else the area of the first pin it serves and the store id, then the city.",
            "examples": [
              "Andheri West · store 35548, Mumbai"
            ]
          },
          "name": {
            "type": [
              "null",
              "string"
            ],
            "title": "Name",
            "description": "The store name, when known; usually null.",
            "examples": [
              "Andheri West"
            ]
          },
          "area": {
            "type": [
              "null",
              "string"
            ],
            "title": "Area",
            "description": "The main post office name of the lowest pin code the store serves, as a neighbourhood label.",
            "examples": [
              "Andheri West"
            ]
          },
          "city": {
            "type": "string",
            "title": "City",
            "description": "The city the sweep that found the store covered.",
            "examples": [
              "Mumbai"
            ]
          },
          "state": {
            "type": [
              "null",
              "string"
            ],
            "title": "State",
            "description": "The state of the pin codes it serves.",
            "examples": [
              "MAHARASHTRA"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ],
            "title": "Status",
            "description": "closed once a sweep marked it closed; else open.",
            "examples": [
              "open"
            ]
          },
          "sweepStatus": {
            "type": "string",
            "title": "Sweep status",
            "description": "The sweep’s own word: active (seen again), opened (new since the last sweep), flicker (missed, then seen), closed.",
            "examples": [
              "active"
            ]
          },
          "firstSeenAt": {
            "type": "string",
            "title": "First seen",
            "description": "When a sweep first saw the store.",
            "examples": [
              "2026-10-13T06:00:00.000Z"
            ]
          },
          "lastSeenAt": {
            "type": "string",
            "title": "Last seen",
            "description": "When a sweep last saw the store.",
            "examples": [
              "2026-10-15T06:00:00.000Z"
            ]
          },
          "closedAt": {
            "type": [
              "null",
              "string"
            ],
            "title": "Closed at",
            "description": "When it was marked closed; null when open.",
            "examples": [
              "2026-10-20T06:00:00.000Z"
            ]
          },
          "pincodes": {
            "type": "array",
            "title": "Pin codes served",
            "description": "The pin codes the store serves, ascending (only those the pin directory lists): the exact list a filter by this store reads, and the count confirmPins needs.",
            "items": {
              "type": "string",
              "pattern": "^[1-9][0-9]{5}$",
              "examples": [
                "400053"
              ]
            }
          },
          "kept": {
            "type": "object",
            "title": "Kept coverage",
            "description": "Rows already held at the pin codes the store serves, free to list. Kept per pin code, not per store.",
            "additionalProperties": false,
            "required": [
              "retailers",
              "lastSeenDay",
              "pincodesWithData"
            ],
            "properties": {
              "retailers": {
                "type": "array",
                "title": "Retailers with data",
                "description": "Retailer keys with a reading here on any of the last 30 IST days, sorted.",
                "items": {
                  "type": "string",
                  "examples": [
                    "blinkit"
                  ]
                }
              },
              "lastSeenDay": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Last seen day",
                "description": "The newest IST day any retailer read this place within the data window; null when none did.",
                "examples": [
                  "2026-10-20"
                ]
              },
              "pincodesWithData": {
                "type": "integer",
                "title": "Pin codes with data",
                "description": "How many of the store pin codes have readings of the store’s retailer in the window.",
                "examples": [
                  2
                ]
              }
            }
          }
        }
      },
      "LocationStoresPage": {
        "type": "object",
        "title": "Dark stores page",
        "description": "One page of records with paging. Free: nothing is charged.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Records",
            "description": "The records of this page.",
            "items": {
              "$ref": "#/components/schemas/LocationStore"
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging state.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  50
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Opaque. Send it back as cursor, with the same filters, for the next page; null on the last page.",
                "examples": [
                  "eyJ0IjoiMTk3MC0wMS0wMVQwMDowMDowMC4wMDBaIiwiaSI6IjU2MDAzNCIsImYiOiJhYmMifQ"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Where the data comes from, what the lookup concluded, and that it is free.",
            "additionalProperties": false,
            "required": [
              "kind",
              "market",
              "supported",
              "resolution",
              "notes",
              "dataWindowDays",
              "asOfDay",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "reference"
                ],
                "title": "Kind",
                "description": "reference: India Post pin directory joined with the daily coverage summary.",
                "examples": [
                  "reference"
                ]
              },
              "market": {
                "type": "string",
                "title": "Market",
                "description": "ISO 3166-1 country code of the market (Core Retailer.market).",
                "examples": [
                  "IN"
                ],
                "pattern": "^[A-Z]{2}$"
              },
              "supported": {
                "type": "boolean",
                "title": "Supported",
                "description": "False when the market has no location directory: the answer is then empty on purpose, never a guess.",
                "examples": [
                  true
                ]
              },
              "resolution": {
                "type": "string",
                "enum": [
                  "listing",
                  "unique",
                  "ambiguous",
                  "no_match",
                  "unsupported_market"
                ],
                "title": "Resolution",
                "description": "listing: no words were given. unique: the words point at one place. ambiguous: they point at more than one city or state, so ask the person. no_match: nothing matched. unsupported_market: the market has no location directory.",
                "examples": [
                  "unique"
                ]
              },
              "notes": {
                "type": "array",
                "title": "Notes",
                "description": "pin_not_in_directory: a six-digit pin that India Post does not list. market_has_no_location_directory: see supported.",
                "items": {
                  "type": "string",
                  "enum": [
                    "pin_not_in_directory",
                    "market_has_no_location_directory"
                  ],
                  "examples": [
                    "pin_not_in_directory"
                  ]
                }
              },
              "dataWindowDays": {
                "type": "integer",
                "title": "Data window",
                "description": "Days back that kept coverage looks at.",
                "examples": [
                  30
                ]
              },
              "asOfDay": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Coverage as of",
                "description": "The newest IST day in the coverage summary; null when it is empty.",
                "examples": [
                  "2026-10-20"
                ]
              },
              "credits": {
                "type": "object",
                "title": "Credits",
                "description": "Always free.",
                "additionalProperties": false,
                "required": [
                  "charged",
                  "units",
                  "freeReread",
                  "rate"
                ],
                "properties": {
                  "charged": {
                    "type": "integer",
                    "title": "Charged",
                    "description": "Credits charged: always 0.",
                    "examples": [
                      0
                    ]
                  },
                  "units": {
                    "type": "integer",
                    "title": "Units",
                    "description": "Always 0.",
                    "examples": [
                      0
                    ]
                  },
                  "freeReread": {
                    "type": "boolean",
                    "title": "Free re-read",
                    "description": "Always false.",
                    "examples": [
                      false
                    ]
                  },
                  "rate": {
                    "type": "null",
                    "title": "Rate",
                    "description": "Always null: no rate applies."
                  }
                }
              }
            }
          }
        }
      },
      "MarketFigure": {
        "type": "object",
        "title": "Market figure",
        "description": "One public figure about the Indian market for this category, as published by its source on the accessed day.",
        "additionalProperties": false,
        "required": [
          "label",
          "value",
          "unit",
          "period",
          "source",
          "title",
          "url",
          "accessed"
        ],
        "properties": {
          "label": {
            "type": "string",
            "title": "Label",
            "description": "What the figure measures.",
            "examples": [
              "Smartwatch shipments, India"
            ]
          },
          "value": {
            "type": "number",
            "title": "Value",
            "description": "The figure, in its unit.",
            "examples": [
              12.3
            ]
          },
          "unit": {
            "type": "string",
            "title": "Unit",
            "description": "The unit of the value.",
            "examples": [
              "million units"
            ]
          },
          "period": {
            "type": "string",
            "title": "Period",
            "description": "The period the figure covers.",
            "examples": [
              "CY2024"
            ]
          },
          "source": {
            "type": "string",
            "title": "Source",
            "description": "The body that published it.",
            "examples": [
              "IDC"
            ]
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "The title of the source page.",
            "examples": [
              "India wearables market ..."
            ]
          },
          "url": {
            "type": "string",
            "title": "URL",
            "description": "The source page.",
            "examples": [
              "https://www.idc.com/..."
            ],
            "format": "uri"
          },
          "accessed": {
            "type": "string",
            "title": "Accessed",
            "description": "The day the figure was checked on the page.",
            "examples": [
              "2026-10-22"
            ],
            "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
          }
        }
      },
      "CategoryMarketContext": {
        "type": "object",
        "title": "Market context",
        "description": "Reviewed public market figures for a category, each with its primary source. Free.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Market context",
            "description": "The figures for one category (may be empty).",
            "additionalProperties": false,
            "required": [
              "category",
              "figures"
            ],
            "properties": {
              "category": {
                "type": "string",
                "title": "Category",
                "description": "The public category slug.",
                "examples": [
                  "wearables"
                ]
              },
              "figures": {
                "type": "array",
                "title": "Figures",
                "description": "One to three figures; empty when none could be confirmed.",
                "items": {
                  "$ref": "#/components/schemas/MarketFigure"
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "The reviewed file this came from.",
            "additionalProperties": false,
            "required": [
              "reviewed",
              "version",
              "credits"
            ],
            "properties": {
              "reviewed": {
                "type": "string",
                "title": "Reviewed",
                "description": "The day the file was last reviewed.",
                "examples": [
                  "2026-10-22"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              },
              "version": {
                "type": "integer",
                "minimum": 0,
                "title": "Version",
                "description": "The file version.",
                "examples": [
                  1
                ]
              },
              "credits": {
                "$ref": "#/components/schemas/NoCharge"
              }
            }
          }
        }
      },
      "CategoryPriceLadder": {
        "type": "object",
        "title": "Price ladder",
        "description": "Entry, mid and premium unit-price bands for a category, all platforms and each platform. Free.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Price ladder",
            "description": "The newest price ladder build for the category.",
            "additionalProperties": false,
            "required": [
              "type",
              "schemaVersion",
              "method",
              "category",
              "asOf",
              "window",
              "ladders",
              "declined"
            ],
            "properties": {
              "type": {
                "const": "price-ladder",
                "title": "Type",
                "description": "The signal type."
              },
              "schemaVersion": {
                "const": 1,
                "title": "Schema version",
                "description": "The shape of this document."
              },
              "method": {
                "type": "string",
                "title": "Method",
                "description": "The method version the numbers were built with.",
                "examples": [
                  "price-ladder-v1"
                ]
              },
              "category": {
                "type": "string",
                "title": "Category",
                "description": "The public category slug.",
                "examples": [
                  "fitness-nutrition"
                ],
                "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
              },
              "asOf": {
                "type": "string",
                "title": "As of",
                "description": "The last IST day the build read.",
                "examples": [
                  "2026-10-21"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              },
              "window": {
                "type": "object",
                "title": "Window",
                "description": "The IST days read, inclusive.",
                "additionalProperties": false,
                "required": [
                  "from",
                  "to",
                  "days"
                ],
                "properties": {
                  "from": {
                    "type": "string",
                    "title": "From",
                    "description": "First IST day.",
                    "examples": [
                      "2026-10-15"
                    ],
                    "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                  },
                  "to": {
                    "type": "string",
                    "title": "To",
                    "description": "Last IST day.",
                    "examples": [
                      "2026-10-21"
                    ],
                    "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                  },
                  "days": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Days",
                    "description": "Days in the window.",
                    "examples": [
                      7
                    ]
                  }
                }
              },
              "ladders": {
                "type": "array",
                "title": "Ladders",
                "description": "One per platform and basis that clears the floor.",
                "items": {
                  "type": "object",
                  "title": "Ladder",
                  "description": "Unit-price percentiles and bands for one platform and basis.",
                  "additionalProperties": false,
                  "required": [
                    "platform",
                    "basis",
                    "listings",
                    "brands",
                    "p25",
                    "p50",
                    "p75",
                    "p90",
                    "min",
                    "max",
                    "bands"
                  ],
                  "properties": {
                    "platform": {
                      "type": "string",
                      "title": "Platform",
                      "description": "'all' or a retailer key.",
                      "examples": [
                        "all"
                      ]
                    },
                    "basis": {
                      "type": "string",
                      "enum": [
                        "per_100g",
                        "per_100ml",
                        "per_piece",
                        "per_item"
                      ],
                      "title": "Basis",
                      "description": "The unit price basis: per_100g / per_100ml (rupees per 100 g or 100 ml), per_piece (rupees per piece of a count pack) or per_item (the shelf price, for goods sold one at a time).",
                      "examples": [
                        "per_100g"
                      ]
                    },
                    "listings": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Listings",
                      "description": "Listings priced on this basis (each once, at its latest day).",
                      "examples": [
                        412
                      ]
                    },
                    "brands": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Brands",
                      "description": "Distinct brands among them.",
                      "examples": [
                        87
                      ]
                    },
                    "p25": {
                      "type": "number",
                      "title": "P25",
                      "description": "25th percentile unit price, rupees.",
                      "examples": [
                        189.5
                      ]
                    },
                    "p50": {
                      "type": "number",
                      "title": "P50",
                      "description": "Median unit price, rupees.",
                      "examples": [
                        262
                      ]
                    },
                    "p75": {
                      "type": "number",
                      "title": "P75",
                      "description": "75th percentile unit price, rupees.",
                      "examples": [
                        349
                      ]
                    },
                    "p90": {
                      "type": "number",
                      "title": "P90",
                      "description": "90th percentile unit price, rupees.",
                      "examples": [
                        480
                      ]
                    },
                    "min": {
                      "type": "number",
                      "title": "Min",
                      "description": "Lowest unit price, rupees.",
                      "examples": [
                        40
                      ]
                    },
                    "max": {
                      "type": "number",
                      "title": "Max",
                      "description": "Highest unit price, rupees.",
                      "examples": [
                        1999
                      ]
                    },
                    "bands": {
                      "type": "array",
                      "title": "Bands",
                      "description": "Entry (up to p25), mid (above p25 up to p75), premium (above p75), with listing counts.",
                      "items": {
                        "type": "object",
                        "title": "Band",
                        "description": "One price band.",
                        "additionalProperties": false,
                        "required": [
                          "band",
                          "above",
                          "upTo",
                          "listings"
                        ],
                        "properties": {
                          "band": {
                            "type": "string",
                            "enum": [
                              "entry",
                              "mid",
                              "premium"
                            ],
                            "title": "Band",
                            "description": "The band."
                          },
                          "above": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Above",
                            "description": "Lower bound, exclusive; null for entry.",
                            "examples": [
                              189.5
                            ]
                          },
                          "upTo": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Up to",
                            "description": "Upper bound, inclusive; null for premium.",
                            "examples": [
                              349
                            ]
                          },
                          "listings": {
                            "type": "integer",
                            "minimum": 0,
                            "title": "Listings",
                            "description": "Listings in the band.",
                            "examples": [
                              206
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              },
              "declined": {
                "type": "array",
                "title": "Declined",
                "description": "Platform and basis pairs below the floor, with their counts.",
                "items": {
                  "type": "object",
                  "title": "Declined ladder",
                  "description": "A ladder not shown, and why.",
                  "additionalProperties": false,
                  "required": [
                    "platform",
                    "basis",
                    "listings",
                    "reason"
                  ],
                  "properties": {
                    "platform": {
                      "type": "string",
                      "title": "Platform",
                      "description": "'all' or a retailer key.",
                      "examples": [
                        "zepto"
                      ]
                    },
                    "basis": {
                      "type": "string",
                      "enum": [
                        "per_100g",
                        "per_100ml",
                        "per_piece",
                        "per_item"
                      ],
                      "title": "Basis",
                      "description": "The unit price basis: per_100g / per_100ml (rupees per 100 g or 100 ml), per_piece (rupees per piece of a count pack) or per_item (the shelf price, for goods sold one at a time).",
                      "examples": [
                        "per_100g"
                      ]
                    },
                    "listings": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Listings",
                      "description": "Listings priced on this basis.",
                      "examples": [
                        7
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "title": "Reason",
                      "description": "Why it is not shown.",
                      "examples": [
                        "fewer than 20 priced listings"
                      ]
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "When this build was stored, and the (zero) charge.",
            "additionalProperties": false,
            "required": [
              "builtAt",
              "credits"
            ],
            "properties": {
              "builtAt": {
                "type": "string",
                "title": "Built at",
                "description": "When the build was stored (UTC).",
                "examples": [
                  "2026-10-22T02:10:00.000Z"
                ],
                "format": "date-time"
              },
              "credits": {
                "$ref": "#/components/schemas/NoCharge"
              }
            }
          }
        }
      },
      "CategoryCities": {
        "type": "object",
        "title": "City test view",
        "description": "Per city: products and brands on the shelf, availability, median unit price and discount, ranked. Free.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "City test view",
            "description": "The newest city test build for the category.",
            "additionalProperties": false,
            "required": [
              "type",
              "schemaVersion",
              "method",
              "category",
              "asOf",
              "window",
              "basis",
              "cities",
              "declined",
              "unplacedReadings"
            ],
            "properties": {
              "type": {
                "const": "city-test",
                "title": "Type",
                "description": "The signal type."
              },
              "schemaVersion": {
                "const": 1,
                "title": "Schema version",
                "description": "The shape of this document."
              },
              "method": {
                "type": "string",
                "title": "Method",
                "description": "The method version the numbers were built with.",
                "examples": [
                  "city-test-v1"
                ]
              },
              "category": {
                "type": "string",
                "title": "Category",
                "description": "The public category slug.",
                "examples": [
                  "fitness-nutrition"
                ],
                "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
              },
              "asOf": {
                "type": "string",
                "title": "As of",
                "description": "The last IST day the build read.",
                "examples": [
                  "2026-10-21"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              },
              "window": {
                "type": "object",
                "title": "Window",
                "description": "The IST days read, inclusive.",
                "additionalProperties": false,
                "required": [
                  "from",
                  "to",
                  "days"
                ],
                "properties": {
                  "from": {
                    "type": "string",
                    "title": "From",
                    "description": "First IST day.",
                    "examples": [
                      "2026-10-15"
                    ],
                    "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                  },
                  "to": {
                    "type": "string",
                    "title": "To",
                    "description": "Last IST day.",
                    "examples": [
                      "2026-10-21"
                    ],
                    "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                  },
                  "days": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Days",
                    "description": "Days in the window.",
                    "examples": [
                      7
                    ]
                  }
                }
              },
              "basis": {
                "type": [
                  "null",
                  "string"
                ],
                "enum": [
                  "per_100g",
                  "per_100ml",
                  "per_piece",
                  "per_item",
                  null
                ],
                "title": "Basis",
                "description": "The unit price basis: per_100g / per_100ml (rupees per 100 g or 100 ml), per_piece (rupees per piece of a count pack) or per_item (the shelf price, for goods sold one at a time).",
                "examples": [
                  "per_100g"
                ]
              },
              "cities": {
                "type": "array",
                "title": "Cities",
                "description": "Cities that clear the floor, by competition rank.",
                "items": {
                  "type": "object",
                  "title": "City",
                  "description": "One city on the shelf for this category.",
                  "additionalProperties": false,
                  "required": [
                    "city",
                    "state",
                    "locationId",
                    "platforms",
                    "pins",
                    "days",
                    "productsSeen",
                    "brandsSeen",
                    "availabilityRate",
                    "stockKnownReadings",
                    "medianUnitPrice",
                    "medianDiscountPct",
                    "competitionRank",
                    "availabilityRank"
                  ],
                  "properties": {
                    "city": {
                      "type": "string",
                      "title": "City",
                      "description": "The city (India Post pin directory).",
                      "examples": [
                        "Bengaluru"
                      ]
                    },
                    "state": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "State",
                      "description": "The state.",
                      "examples": [
                        "KARNATAKA"
                      ]
                    },
                    "locationId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Location id",
                      "description": "The city location id (GET /v1/data/locations/cities).",
                      "examples": [
                        "IN:city:karnataka:bengaluru"
                      ]
                    },
                    "platforms": {
                      "type": "array",
                      "title": "Platforms",
                      "description": "Retailer keys seen in the city.",
                      "items": {
                        "type": "string"
                      }
                    },
                    "pins": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Pin codes",
                      "description": "Pin codes read in the city.",
                      "examples": [
                        4
                      ]
                    },
                    "days": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Days",
                      "description": "IST days with readings.",
                      "examples": [
                        7
                      ]
                    },
                    "productsSeen": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Products seen",
                      "description": "Distinct listings seen.",
                      "examples": [
                        812
                      ]
                    },
                    "brandsSeen": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Brands seen",
                      "description": "Distinct brands seen.",
                      "examples": [
                        143
                      ]
                    },
                    "availabilityRate": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "title": "Availability rate",
                      "description": "Listing-pin-days in stock over those with a known stock state, 0 to 1.",
                      "examples": [
                        0.91
                      ]
                    },
                    "stockKnownReadings": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Stock-known readings",
                      "description": "Listing-pin-days with a known stock state.",
                      "examples": [
                        5120
                      ]
                    },
                    "medianUnitPrice": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "title": "Median unit price",
                      "description": "Median unit price on the signal basis, rupees.",
                      "examples": [
                        248
                      ]
                    },
                    "medianDiscountPct": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "title": "Median discount",
                      "description": "Median discount below MRP, percent, over in-stock readings with an MRP.",
                      "examples": [
                        18.5
                      ]
                    },
                    "competitionRank": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Competition rank",
                      "description": "1 = most brands, then most products, on the shelf.",
                      "examples": [
                        1
                      ]
                    },
                    "availabilityRank": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Availability rank",
                      "description": "1 = highest availability rate.",
                      "examples": [
                        3
                      ]
                    }
                  }
                }
              },
              "declined": {
                "type": "array",
                "title": "Declined",
                "description": "Cities below the floor.",
                "items": {
                  "type": "object",
                  "title": "Declined city",
                  "description": "A city not shown, and why.",
                  "additionalProperties": false,
                  "required": [
                    "city",
                    "state",
                    "productsSeen",
                    "days",
                    "reason"
                  ],
                  "properties": {
                    "city": {
                      "type": "string",
                      "title": "City",
                      "description": "The city.",
                      "examples": [
                        "Chennai"
                      ]
                    },
                    "state": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "State",
                      "description": "The state.",
                      "examples": [
                        "TAMIL NADU"
                      ]
                    },
                    "productsSeen": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Products seen",
                      "description": "Distinct listings seen.",
                      "examples": [
                        4
                      ]
                    },
                    "days": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Days",
                      "description": "IST days with readings.",
                      "examples": [
                        1
                      ]
                    },
                    "reason": {
                      "type": "string",
                      "title": "Reason",
                      "description": "Why it is not shown.",
                      "examples": [
                        "fewer than 10 products seen"
                      ]
                    }
                  }
                }
              },
              "unplacedReadings": {
                "type": "integer",
                "minimum": 0,
                "title": "Unplaced readings",
                "description": "Readings at pins with no city (national listings, pins not in the directory): counted in the ladder, not here.",
                "examples": [
                  20311
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "When this build was stored, and the (zero) charge.",
            "additionalProperties": false,
            "required": [
              "builtAt",
              "credits"
            ],
            "properties": {
              "builtAt": {
                "type": "string",
                "title": "Built at",
                "description": "When the build was stored (UTC).",
                "examples": [
                  "2026-10-22T02:10:00.000Z"
                ],
                "format": "date-time"
              },
              "credits": {
                "$ref": "#/components/schemas/NoCharge"
              }
            }
          }
        }
      },
      "CategoryFeatureTags": {
        "type": "object",
        "title": "Feature tags",
        "description": "Monthly share of listings and median unit price for each feature tag of a category. Free.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Feature tags",
            "description": "The newest feature tag build for the category.",
            "additionalProperties": false,
            "required": [
              "type",
              "schemaVersion",
              "method",
              "category",
              "asOf",
              "months",
              "tags"
            ],
            "properties": {
              "type": {
                "const": "feature-tags",
                "title": "Type",
                "description": "The signal type."
              },
              "schemaVersion": {
                "const": 1,
                "title": "Schema version",
                "description": "The shape of this document."
              },
              "method": {
                "type": "string",
                "title": "Method",
                "description": "The method version the numbers were built with.",
                "examples": [
                  "feature-tags-v1"
                ]
              },
              "category": {
                "type": "string",
                "title": "Category",
                "description": "The public category slug.",
                "examples": [
                  "fitness-nutrition"
                ],
                "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$"
              },
              "asOf": {
                "type": "string",
                "title": "As of",
                "description": "The last IST day the build read.",
                "examples": [
                  "2026-10-21"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              },
              "months": {
                "type": "array",
                "title": "Months",
                "description": "The calendar months read; the current one is cut at asOf.",
                "items": {
                  "type": "object",
                  "title": "Month",
                  "description": "One month read.",
                  "additionalProperties": false,
                  "required": [
                    "month",
                    "from",
                    "to",
                    "complete",
                    "listings"
                  ],
                  "properties": {
                    "month": {
                      "type": "string",
                      "title": "Month",
                      "description": "YYYY-MM.",
                      "examples": [
                        "2026-10"
                      ],
                      "pattern": "^[0-9]{4}-[0-9]{2}$"
                    },
                    "from": {
                      "type": "string",
                      "title": "From",
                      "description": "First day read.",
                      "examples": [
                        "2026-10-01"
                      ],
                      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                    },
                    "to": {
                      "type": "string",
                      "title": "To",
                      "description": "Last day read.",
                      "examples": [
                        "2026-10-21"
                      ],
                      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                    },
                    "complete": {
                      "type": "boolean",
                      "title": "Complete",
                      "description": "Whether the whole month was read."
                    },
                    "listings": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Listings",
                      "description": "Listings on the shelf in the category that month.",
                      "examples": [
                        3120
                      ]
                    }
                  }
                }
              },
              "tags": {
                "type": "array",
                "title": "Tags",
                "description": "Each tag of the dictionary, in order.",
                "items": {
                  "type": "object",
                  "title": "Tag",
                  "description": "One feature tag and its monthly series.",
                  "additionalProperties": false,
                  "required": [
                    "tag",
                    "label",
                    "scope",
                    "series"
                  ],
                  "properties": {
                    "tag": {
                      "type": "string",
                      "title": "Tag",
                      "description": "Stable tag id.",
                      "examples": [
                        "anc"
                      ]
                    },
                    "label": {
                      "type": "string",
                      "title": "Label",
                      "description": "Display label.",
                      "examples": [
                        "Active noise cancellation (ANC)"
                      ]
                    },
                    "scope": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "title": "Scope",
                      "description": "The listings the share is counted among (e.g. coffee); null = the whole category.",
                      "additionalProperties": false,
                      "required": [
                        "id",
                        "label"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "title": "Id",
                          "description": "Scope id.",
                          "examples": [
                            "coffee"
                          ]
                        },
                        "label": {
                          "type": "string",
                          "title": "Label",
                          "description": "Scope label.",
                          "examples": [
                            "Coffee"
                          ]
                        }
                      }
                    },
                    "series": {
                      "type": "array",
                      "title": "Series",
                      "description": "One point per month.",
                      "items": {
                        "type": "object",
                        "title": "Point",
                        "description": "One tag in one month.",
                        "additionalProperties": false,
                        "required": [
                          "month",
                          "scopeListings",
                          "tagged",
                          "share",
                          "basis",
                          "medianUnitPrice"
                        ],
                        "properties": {
                          "month": {
                            "type": "string",
                            "title": "Month",
                            "description": "YYYY-MM.",
                            "examples": [
                              "2026-10"
                            ]
                          },
                          "scopeListings": {
                            "type": "integer",
                            "minimum": 0,
                            "title": "Scope listings",
                            "description": "Listings on the shelf in the scope.",
                            "examples": [
                              1840
                            ]
                          },
                          "tagged": {
                            "type": "integer",
                            "minimum": 0,
                            "title": "Tagged",
                            "description": "Of those, listings carrying the tag.",
                            "examples": [
                              402
                            ]
                          },
                          "share": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Share",
                            "description": "tagged / scopeListings, 0 to 1; null below 20 scope listings.",
                            "examples": [
                              0.2185
                            ]
                          },
                          "basis": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "enum": [
                              "per_100g",
                              "per_100ml",
                              "per_piece",
                              "per_item",
                              null
                            ],
                            "title": "Basis",
                            "description": "The unit price basis: per_100g / per_100ml (rupees per 100 g or 100 ml), per_piece (rupees per piece of a count pack) or per_item (the shelf price, for goods sold one at a time).",
                            "examples": [
                              "per_100g"
                            ]
                          },
                          "medianUnitPrice": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "Median unit price",
                            "description": "Median unit price of tagged listings, rupees.",
                            "examples": [
                              2499
                            ]
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "When this build was stored, and the (zero) charge.",
            "additionalProperties": false,
            "required": [
              "builtAt",
              "credits"
            ],
            "properties": {
              "builtAt": {
                "type": "string",
                "title": "Built at",
                "description": "When the build was stored (UTC).",
                "examples": [
                  "2026-10-22T02:10:00.000Z"
                ],
                "format": "date-time"
              },
              "credits": {
                "$ref": "#/components/schemas/NoCharge"
              }
            }
          }
        }
      },
      "SiteFigures": {
        "type": "object",
        "title": "Site figures",
        "description": "Rewalto's headline figures and when they were measured.",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Site figures",
            "description": "Rewalto's headline figures, counted from its own readings as they land. Every figure only grows: readings are never removed.",
            "additionalProperties": false,
            "required": [
              "pricesCaptured",
              "productsTracked",
              "platformsTracked",
              "darkStores",
              "darkStoreCities",
              "pinCodes",
              "measuredAt"
            ],
            "properties": {
              "pricesCaptured": {
                "type": "integer",
                "minimum": 0,
                "title": "Prices captured",
                "description": "Every reading Rewalto has captured that carried a price, all time.",
                "examples": [
                  23250000
                ]
              },
              "productsTracked": {
                "type": "integer",
                "minimum": 0,
                "title": "Products tracked",
                "description": "Distinct products read: one per platform and the platform's product id; on Zepto, whose product id is per store, one per title and pack size.",
                "examples": [
                  620000
                ]
              },
              "platformsTracked": {
                "type": "integer",
                "minimum": 0,
                "title": "Platforms tracked",
                "description": "Apps and stores Rewalto reads itself: platforms with at least one reading.",
                "examples": [
                  13
                ]
              },
              "darkStores": {
                "type": "integer",
                "minimum": 0,
                "title": "Dark stores",
                "description": "Open dark stores: every store not marked closed, as GET /v1/dark-stores/summary counts them.",
                "examples": [
                  3050
                ]
              },
              "darkStoreCities": {
                "type": "integer",
                "minimum": 0,
                "title": "Dark store cities",
                "description": "Cities with an open dark store, each counted once in its canonical spelling (Gurgaon and Gurugram are one city).",
                "examples": [
                  92
                ]
              },
              "pinCodes": {
                "type": "integer",
                "minimum": 0,
                "title": "Pin codes",
                "description": "Pin codes an open dark store serves (its catchment) or stands in.",
                "examples": [
                  9000
                ]
              },
              "measuredAt": {
                "type": "string",
                "format": "date-time",
                "title": "Measured at",
                "description": "Every reading ingested before this moment is counted. The totals are brought up to date every few minutes, so this is normally under 15 minutes old and kept within the hour.",
                "examples": [
                  "2026-10-23T09:50:00.000Z"
                ]
              }
            }
          }
        }
      },
      "CoveragePins": {
        "type": "object",
        "title": "Coverage by pin code",
        "description": "Which source read which pin code in the last few IST days, and when. Free.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Coverage",
            "description": "Per source and pin code, with when it was measured.",
            "additionalProperties": false,
            "required": [
              "measuredAt",
              "computedAt",
              "from",
              "to",
              "days",
              "lastObservedAt",
              "sources",
              "pins",
              "national"
            ],
            "properties": {
              "measuredAt": {
                "type": "string",
                "format": "date-time",
                "title": "Measured at",
                "description": "When this answer was read (UTC).",
                "examples": [
                  "2026-10-24T05:00:00.000Z"
                ]
              },
              "computedAt": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "Computed at",
                "description": "When the hourly coverage summary behind it was last written, for these days (UTC); null when nothing was read.",
                "examples": [
                  "2026-10-24T04:07:00.000Z"
                ]
              },
              "from": {
                "type": "string",
                "format": "date",
                "title": "From",
                "description": "The first IST day counted.",
                "examples": [
                  "2026-10-21"
                ]
              },
              "to": {
                "type": "string",
                "format": "date",
                "title": "To",
                "description": "The last IST day counted (today, IST).",
                "examples": [
                  "2026-10-24"
                ]
              },
              "days": {
                "type": "integer",
                "minimum": 0,
                "title": "Days",
                "description": "The days asked for.",
                "examples": [
                  3
                ]
              },
              "lastObservedAt": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "title": "Last observed at",
                "description": "The newest reading of any source at any pin code here (UTC); null when there is none.",
                "examples": [
                  "2026-10-24T04:01:12.000Z"
                ]
              },
              "sources": {
                "type": "array",
                "title": "Sources",
                "description": "Every source with readings at a pin code here, sorted.",
                "items": {
                  "type": "string",
                  "title": "Source",
                  "description": "The retailer or app, by its Core source key (blinkit, zepto, instamart, dmart, jiomart, tata_1mg, amazon_in, flipkart ...).",
                  "examples": [
                    "blinkit"
                  ]
                }
              },
              "pins": {
                "type": "array",
                "title": "Pins",
                "description": "One row per source and pin code with readings in the days counted; sorted by source, then pin code.",
                "items": {
                  "type": "object",
                  "title": "Pin",
                  "description": "One source at one pin code.",
                  "additionalProperties": false,
                  "required": [
                    "source",
                    "pincode",
                    "city",
                    "area",
                    "latitude",
                    "longitude",
                    "readings",
                    "daysRead",
                    "lastObservedAt",
                    "storePresent"
                  ],
                  "properties": {
                    "source": {
                      "type": "string",
                      "title": "Source",
                      "description": "The retailer or app, by its Core source key (blinkit, zepto, instamart, dmart, jiomart, tata_1mg, amazon_in, flipkart ...).",
                      "examples": [
                        "blinkit"
                      ]
                    },
                    "pincode": {
                      "type": "string",
                      "title": "Pin code",
                      "description": "A six-digit Indian pin code.",
                      "examples": [
                        "110001"
                      ],
                      "pattern": "^[1-9][0-9]{5}$"
                    },
                    "city": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "City",
                      "description": "The pin code’s city, in one spelling per city (Gurugram, not Gurgaon); null when the registry has none.",
                      "examples": [
                        "Delhi"
                      ]
                    },
                    "area": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Area",
                      "description": "The pin code’s area (its main delivery post office or locality); null when unknown.",
                      "examples": [
                        "Connaught Place"
                      ]
                    },
                    "latitude": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "title": "Latitude",
                      "description": "Latitude of the centre (WGS84). Null when the pin has no centre on record.",
                      "examples": [
                        28.6328
                      ]
                    },
                    "longitude": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "title": "Longitude",
                      "description": "Longitude of the centre (WGS84). Null when the pin has no centre on record.",
                      "examples": [
                        77.2197
                      ]
                    },
                    "readings": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Readings",
                      "description": "Readings of this source at this pin code in the days counted.",
                      "examples": [
                        18575
                      ]
                    },
                    "daysRead": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Days read",
                      "description": "IST days in the window with at least one reading.",
                      "examples": [
                        4
                      ]
                    },
                    "lastObservedAt": {
                      "type": "string",
                      "format": "date-time",
                      "title": "Last observed at",
                      "description": "The newest reading of this source at this pin code (UTC).",
                      "examples": [
                        "2026-10-23T18:53:58.000Z"
                      ]
                    },
                    "storePresent": {
                      "type": "boolean",
                      "title": "Store present",
                      "description": "Whether an open dark store of this app (same key as the source) stands at or is seen serving this pin code. Always false for a source that is not a quick-commerce app.",
                      "examples": [
                        true
                      ]
                    }
                  }
                }
              },
              "national": {
                "type": "array",
                "title": "National",
                "description": "Sources with readings not tied to a pin code (national catalogues) in the days counted; sorted by source. Regulatory notice feeds are not listed.",
                "items": {
                  "type": "object",
                  "title": "National source",
                  "description": "One source’s national readings.",
                  "additionalProperties": false,
                  "required": [
                    "source",
                    "readings",
                    "lastObservedAt"
                  ],
                  "properties": {
                    "source": {
                      "type": "string",
                      "title": "Source",
                      "description": "The retailer or app, by its Core source key (blinkit, zepto, instamart, dmart, jiomart, tata_1mg, amazon_in, flipkart ...).",
                      "examples": [
                        "blinkit"
                      ]
                    },
                    "readings": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Readings",
                      "description": "National readings in the days counted.",
                      "examples": [
                        290000
                      ]
                    },
                    "lastObservedAt": {
                      "type": "string",
                      "format": "date-time",
                      "title": "Last observed at",
                      "description": "The newest of them (UTC).",
                      "examples": [
                        "2026-10-24T03:59:00.000Z"
                      ]
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "The (zero) charge.",
            "additionalProperties": false,
            "required": [
              "credits"
            ],
            "properties": {
              "credits": {
                "$ref": "#/components/schemas/NoCharge"
              }
            }
          }
        }
      },
      "CoverageLayers": {
        "type": "object",
        "title": "Coverage map layers",
        "description": "Cities, pin codes and open dark stores on record, for the coverage map. Free.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Layers",
            "description": "The layers, with when they were measured.",
            "additionalProperties": false,
            "required": [
              "measuredAt",
              "totals",
              "cities",
              "darkStoreCities",
              "pinCentres"
            ],
            "properties": {
              "measuredAt": {
                "type": "string",
                "format": "date-time",
                "title": "Measured at",
                "description": "When these layers were read (UTC).",
                "examples": [
                  "2026-10-24T05:00:00.000Z"
                ]
              },
              "totals": {
                "type": "object",
                "title": "Totals",
                "description": "The figures beside the map.",
                "additionalProperties": false,
                "required": [
                  "cities",
                  "pincodes",
                  "darkStores"
                ],
                "properties": {
                  "cities": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Cities",
                    "description": "Distinct cities on record: those of the pin codes on record and those with an open dark store, each counted once in one spelling.",
                    "examples": [
                      1500
                    ]
                  },
                  "pincodes": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Pin codes",
                    "description": "Pin codes on record with a centre: Rewalto’s pin registry (the old site’s pin table) and every pin code a dark store was found at.",
                    "examples": [
                      7887
                    ]
                  },
                  "darkStores": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Dark stores",
                    "description": "Open dark stores, all apps (as GET /v1/dark-stores/summary and GET /v1/figures count them).",
                    "examples": [
                      22983
                    ]
                  }
                }
              },
              "cities": {
                "type": "array",
                "title": "Cities",
                "description": "One mark per city of the pin codes on record, at the centre of its pin codes; sorted by city.",
                "items": {
                  "type": "object",
                  "title": "City",
                  "description": "A city and where its pin codes are centred.",
                  "additionalProperties": false,
                  "required": [
                    "city",
                    "pincodes",
                    "latitude",
                    "longitude"
                  ],
                  "properties": {
                    "city": {
                      "type": "string",
                      "title": "City",
                      "description": "The city, in one spelling per city.",
                      "examples": [
                        "Gurugram"
                      ]
                    },
                    "pincodes": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Pin codes",
                      "description": "Its pin codes on record.",
                      "examples": [
                        29
                      ]
                    },
                    "latitude": {
                      "type": "number",
                      "title": "Latitude",
                      "description": "Latitude of the centre (WGS84).",
                      "examples": [
                        28.4595
                      ]
                    },
                    "longitude": {
                      "type": "number",
                      "title": "Longitude",
                      "description": "Longitude of the centre (WGS84).",
                      "examples": [
                        77.0266
                      ]
                    }
                  }
                }
              },
              "darkStoreCities": {
                "type": "array",
                "title": "Dark-store cities",
                "description": "Open dark stores counted per city, most first. Placed at the centre of the city’s pin codes on record (placedBy pin_codes), else, for a city with at least 5 open stores that have a point, at the centre of those points rounded to 0.1 degree, about 11 km (placedBy stores), else not placed (null). Store points are paid data: no single store can be located from this. Stores whose city is not known are counted under city null.",
                "items": {
                  "type": "object",
                  "title": "Dark-store city",
                  "description": "Open stores in one city.",
                  "additionalProperties": false,
                  "required": [
                    "city",
                    "stores",
                    "latitude",
                    "longitude",
                    "placedBy"
                  ],
                  "properties": {
                    "city": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "City",
                      "description": "The city, in one spelling per city; null when unknown.",
                      "examples": [
                        "Mumbai"
                      ]
                    },
                    "stores": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Stores",
                      "description": "Open dark stores there, all apps.",
                      "examples": [
                        812
                      ]
                    },
                    "latitude": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "title": "Latitude",
                      "description": "Latitude of the centre (WGS84). Null when not placed.",
                      "examples": [
                        19.076
                      ]
                    },
                    "longitude": {
                      "type": [
                        "null",
                        "number"
                      ],
                      "title": "Longitude",
                      "description": "Longitude of the centre (WGS84). Null when not placed.",
                      "examples": [
                        72.8777
                      ]
                    },
                    "placedBy": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "enum": [
                        "pin_codes",
                        "stores",
                        null
                      ],
                      "title": "Placed by",
                      "description": "What the position is the centre of: the city’s pin codes on record, its stores’ points (at least 5 stores with a point, rounded to 0.1 degree), or null when not placed.",
                      "examples": [
                        "pin_codes"
                      ]
                    }
                  }
                }
              },
              "pinCentres": {
                "type": "array",
                "title": "Pin centres",
                "description": "The centre of each pin code asked for in pins that has one on record; empty when pins is not sent.",
                "items": {
                  "type": "object",
                  "title": "Pin centre",
                  "description": "A pin code’s centre.",
                  "additionalProperties": false,
                  "required": [
                    "pincode",
                    "latitude",
                    "longitude"
                  ],
                  "properties": {
                    "pincode": {
                      "type": "string",
                      "title": "Pin code",
                      "description": "A six-digit Indian pin code.",
                      "examples": [
                        "110001"
                      ],
                      "pattern": "^[1-9][0-9]{5}$"
                    },
                    "latitude": {
                      "type": "number",
                      "title": "Latitude",
                      "description": "Latitude of the centre (WGS84).",
                      "examples": [
                        28.6328
                      ]
                    },
                    "longitude": {
                      "type": "number",
                      "title": "Longitude",
                      "description": "Longitude of the centre (WGS84).",
                      "examples": [
                        77.2197
                      ]
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "The (zero) charge.",
            "additionalProperties": false,
            "required": [
              "credits"
            ],
            "properties": {
              "credits": {
                "$ref": "#/components/schemas/NoCharge"
              }
            }
          }
        }
      },
      "FreePinAvailability": {
        "type": "object",
        "title": "Free pin-code check",
        "description": "One brand at one pin code, per quick-commerce app. Free.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Answer",
            "description": "Per app: the brand’s listings read at the pin code in the window.",
            "additionalProperties": false,
            "required": [
              "status",
              "brand",
              "brandChoices",
              "brandChoicesCapped",
              "window",
              "asOf",
              "pincode",
              "retailers"
            ],
            "properties": {
              "status": {
                "type": "string",
                "title": "Status",
                "description": "measured: the brand was read. choose_brand: the text matches several tracked brands; ask which (brandChoices). no_brand_match: no tracked brand on these apps contains every word typed.",
                "examples": [
                  "measured"
                ],
                "enum": [
                  "measured",
                  "choose_brand",
                  "no_brand_match"
                ]
              },
              "brand": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Brand",
                "description": "The brand read, as the apps write it; null unless measured.",
                "examples": [
                  "Amul"
                ]
              },
              "brandChoices": {
                "type": "array",
                "title": "Brand choices",
                "description": "Up to 8 tracked brands matching the text, alphabetical, when choose_brand; else empty.",
                "items": {
                  "type": "string",
                  "title": "Brand",
                  "description": "A tracked brand.",
                  "examples": [
                    "Amul Gold"
                  ]
                }
              },
              "brandChoicesCapped": {
                "type": "boolean",
                "title": "More brands match",
                "description": "True when more brands match than are listed: type more of the name.",
                "examples": [
                  false
                ]
              },
              "window": {
                "type": "object",
                "title": "Window",
                "description": "The readings counted: from and to (UTC).",
                "additionalProperties": false,
                "required": [
                  "hours",
                  "from",
                  "to"
                ],
                "properties": {
                  "hours": {
                    "type": "integer",
                    "title": "Hours",
                    "description": "The window length.",
                    "examples": [
                      24
                    ],
                    "minimum": 0
                  },
                  "from": {
                    "type": "string",
                    "title": "From",
                    "description": "Oldest reading time counted.",
                    "examples": [
                      "2026-10-23T06:00:00.000Z"
                    ],
                    "format": "date-time"
                  },
                  "to": {
                    "type": "string",
                    "title": "To",
                    "description": "When the read was made.",
                    "examples": [
                      "2026-10-24T06:00:00.000Z"
                    ],
                    "format": "date-time"
                  }
                }
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "As of",
                "description": "The newest reading counted (UTC); null when none.",
                "examples": [
                  "2026-10-24T05:12:00.000000Z"
                ],
                "format": "date-time"
              },
              "pincode": {
                "type": "string",
                "title": "Pin code",
                "description": "The pin code asked about.",
                "examples": [
                  "110001"
                ]
              },
              "retailers": {
                "type": "array",
                "title": "Apps",
                "description": "One row per app, in the order blinkit, instamart, zepto; empty unless measured.",
                "items": {
                  "type": "object",
                  "title": "App",
                  "description": "One app at the pin code.",
                  "additionalProperties": false,
                  "required": [
                    "retailer",
                    "state",
                    "listings",
                    "readingsLeftOut",
                    "shown"
                  ],
                  "properties": {
                    "retailer": {
                      "type": "string",
                      "title": "App",
                      "description": "The quick-commerce app (source): blinkit, instamart, zepto.",
                      "examples": [
                        "blinkit"
                      ]
                    },
                    "state": {
                      "type": "string",
                      "title": "State",
                      "description": "found: readings in the window. no_recent_reading: Rewalto reads this app here, but nothing for this brand (and product) in the window; not evidence of an empty shelf. not_collected: Rewalto reads no listing at this pin code on this app (in the last 30 days); not evidence either way. Only given with a pin code.",
                      "examples": [
                        "found"
                      ],
                      "enum": [
                        "found",
                        "no_recent_reading",
                        "not_collected"
                      ]
                    },
                    "listings": {
                      "type": "integer",
                      "title": "Listings",
                      "description": "Listings of the brand read here in the window.",
                      "examples": [
                        12
                      ],
                      "minimum": 0
                    },
                    "readingsLeftOut": {
                      "type": "integer",
                      "title": "Readings left out",
                      "description": "Readings in the window on a pin-day left out of the data (D-1458, D-1468); not counted or shown.",
                      "examples": [
                        0
                      ],
                      "minimum": 0
                    },
                    "shown": {
                      "type": "array",
                      "title": "Listings shown",
                      "description": "The 8 most recently read listings, newest first: each one’s newest reading here.",
                      "items": {
                        "type": "object",
                        "title": "Listing",
                        "description": "One listing’s newest reading at the pin code.",
                        "additionalProperties": false,
                        "required": [
                          "retailerSku",
                          "title",
                          "pincode",
                          "stock",
                          "priceMinor",
                          "mrpMinor",
                          "currency",
                          "observedAt"
                        ],
                        "properties": {
                          "retailerSku": {
                            "type": "string",
                            "title": "Retailer product id",
                            "description": "The app’s own product id.",
                            "examples": [
                              "40107"
                            ]
                          },
                          "title": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Name",
                            "description": "The listing’s name as the app shows it; null when not read.",
                            "examples": [
                              "Amul Salted Butter 100 g"
                            ]
                          },
                          "pincode": {
                            "type": "string",
                            "title": "Pin code",
                            "description": "Where the reading was taken.",
                            "examples": [
                              "110001"
                            ]
                          },
                          "stock": {
                            "type": "string",
                            "title": "Stock",
                            "description": "in_stock or out_of_stock as the app showed it; not_reported when the reading did not say.",
                            "examples": [
                              "in_stock"
                            ],
                            "enum": [
                              "in_stock",
                              "out_of_stock",
                              "not_reported"
                            ]
                          },
                          "priceMinor": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Price",
                            "description": "Selling price in paise; null when not shown.",
                            "examples": [
                              5600
                            ],
                            "minimum": 0
                          },
                          "mrpMinor": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "MRP",
                            "description": "MRP in paise; null when not shown.",
                            "examples": [
                              6000
                            ],
                            "minimum": 0
                          },
                          "currency": {
                            "type": "string",
                            "title": "Currency",
                            "description": "Always INR.",
                            "examples": [
                              "INR"
                            ],
                            "enum": [
                              "INR"
                            ]
                          },
                          "observedAt": {
                            "type": "string",
                            "title": "Read at",
                            "description": "When the reading was taken (UTC).",
                            "examples": [
                              "2026-10-24T05:12:00.000000Z"
                            ],
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "The (zero) charge.",
            "additionalProperties": false,
            "required": [
              "credits"
            ],
            "properties": {
              "credits": {
                "$ref": "#/components/schemas/NoCharge"
              }
            }
          }
        }
      },
      "FreePriceParity": {
        "type": "object",
        "title": "Free price-parity check",
        "description": "One brand’s selling prices against MRP, per quick-commerce app. Free.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Answer",
            "description": "Per app: each listing’s newest priced reading per pin code in the window.",
            "additionalProperties": false,
            "required": [
              "status",
              "brand",
              "brandChoices",
              "brandChoicesCapped",
              "window",
              "asOf",
              "product",
              "pincode",
              "discountFlagPct",
              "retailers"
            ],
            "properties": {
              "status": {
                "type": "string",
                "title": "Status",
                "description": "measured: the brand was read. choose_brand: the text matches several tracked brands; ask which (brandChoices). no_brand_match: no tracked brand on these apps contains every word typed.",
                "examples": [
                  "measured"
                ],
                "enum": [
                  "measured",
                  "choose_brand",
                  "no_brand_match"
                ]
              },
              "brand": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Brand",
                "description": "The brand read, as the apps write it; null unless measured.",
                "examples": [
                  "Amul"
                ]
              },
              "brandChoices": {
                "type": "array",
                "title": "Brand choices",
                "description": "Up to 8 tracked brands matching the text, alphabetical, when choose_brand; else empty.",
                "items": {
                  "type": "string",
                  "title": "Brand",
                  "description": "A tracked brand.",
                  "examples": [
                    "Amul Gold"
                  ]
                }
              },
              "brandChoicesCapped": {
                "type": "boolean",
                "title": "More brands match",
                "description": "True when more brands match than are listed: type more of the name.",
                "examples": [
                  false
                ]
              },
              "window": {
                "type": "object",
                "title": "Window",
                "description": "The readings counted: from and to (UTC).",
                "additionalProperties": false,
                "required": [
                  "hours",
                  "from",
                  "to"
                ],
                "properties": {
                  "hours": {
                    "type": "integer",
                    "title": "Hours",
                    "description": "The window length.",
                    "examples": [
                      24
                    ],
                    "minimum": 0
                  },
                  "from": {
                    "type": "string",
                    "title": "From",
                    "description": "Oldest reading time counted.",
                    "examples": [
                      "2026-10-23T06:00:00.000Z"
                    ],
                    "format": "date-time"
                  },
                  "to": {
                    "type": "string",
                    "title": "To",
                    "description": "When the read was made.",
                    "examples": [
                      "2026-10-24T06:00:00.000Z"
                    ],
                    "format": "date-time"
                  }
                }
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "As of",
                "description": "The newest reading counted (UTC); null when none.",
                "examples": [
                  "2026-10-24T05:12:00.000000Z"
                ],
                "format": "date-time"
              },
              "product": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Product",
                "description": "The product text the names were narrowed by; null when none.",
                "examples": [
                  "butter"
                ]
              },
              "pincode": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Pin code",
                "description": "The pin code asked about; null: every pin code read in the window.",
                "examples": [
                  null
                ]
              },
              "discountFlagPct": {
                "type": "integer",
                "title": "Flag at",
                "description": "A price this many percent or more below MRP is flagged.",
                "examples": [
                  10
                ],
                "minimum": 0
              },
              "retailers": {
                "type": "array",
                "title": "Apps",
                "description": "One row per app, in the order blinkit, instamart, zepto; empty unless measured.",
                "items": {
                  "type": "object",
                  "title": "App",
                  "description": "One app.",
                  "additionalProperties": false,
                  "required": [
                    "retailer",
                    "state",
                    "readings",
                    "flagged",
                    "readingsLeftOut",
                    "shown"
                  ],
                  "properties": {
                    "retailer": {
                      "type": "string",
                      "title": "App",
                      "description": "The quick-commerce app (source): blinkit, instamart, zepto.",
                      "examples": [
                        "blinkit"
                      ]
                    },
                    "state": {
                      "type": "string",
                      "title": "State",
                      "description": "found: readings in the window. no_recent_reading: Rewalto reads this app here, but nothing for this brand (and product) in the window; not evidence of an empty shelf. not_collected: Rewalto reads no listing at this pin code on this app (in the last 30 days); not evidence either way. Only given with a pin code.",
                      "examples": [
                        "found"
                      ],
                      "enum": [
                        "found",
                        "no_recent_reading",
                        "not_collected"
                      ]
                    },
                    "readings": {
                      "type": "integer",
                      "title": "Readings",
                      "description": "Listing and pin-code pairs read in the window (each pair’s newest reading).",
                      "examples": [
                        30
                      ],
                      "minimum": 0
                    },
                    "flagged": {
                      "type": "integer",
                      "title": "Flagged",
                      "description": "Of those, how many are flagged.",
                      "examples": [
                        4
                      ],
                      "minimum": 0
                    },
                    "readingsLeftOut": {
                      "type": "integer",
                      "title": "Readings left out",
                      "description": "Readings in the window on a pin-day left out of the data (D-1458, D-1468); not counted or shown.",
                      "examples": [
                        0
                      ],
                      "minimum": 0
                    },
                    "shown": {
                      "type": "array",
                      "title": "Readings shown",
                      "description": "The 10 newest, newest first.",
                      "items": {
                        "type": "object",
                        "title": "Reading",
                        "description": "One listing’s newest reading at one pin code.",
                        "additionalProperties": false,
                        "required": [
                          "retailerSku",
                          "title",
                          "pincode",
                          "priceMinor",
                          "mrpMinor",
                          "currency",
                          "discountPct",
                          "flagged",
                          "observedAt"
                        ],
                        "properties": {
                          "retailerSku": {
                            "type": "string",
                            "title": "Retailer product id",
                            "description": "The app’s own product id.",
                            "examples": [
                              "40107"
                            ]
                          },
                          "title": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Name",
                            "description": "The listing’s name as the app shows it; null when not read.",
                            "examples": [
                              "Amul Salted Butter 100 g"
                            ]
                          },
                          "pincode": {
                            "type": "string",
                            "title": "Pin code",
                            "description": "Where the reading was taken.",
                            "examples": [
                              "110001"
                            ]
                          },
                          "priceMinor": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Price",
                            "description": "Selling price in paise; null when not shown.",
                            "examples": [
                              5400
                            ],
                            "minimum": 0
                          },
                          "mrpMinor": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "MRP",
                            "description": "MRP in paise; null when not shown.",
                            "examples": [
                              6000
                            ],
                            "minimum": 0
                          },
                          "currency": {
                            "type": "string",
                            "title": "Currency",
                            "description": "Always INR.",
                            "examples": [
                              "INR"
                            ],
                            "enum": [
                              "INR"
                            ]
                          },
                          "discountPct": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Below MRP, %",
                            "description": "Whole percent below MRP, rounded down; null when either figure is missing or the price is above MRP.",
                            "examples": [
                              10
                            ],
                            "minimum": 0
                          },
                          "flagged": {
                            "type": "boolean",
                            "title": "Flagged",
                            "description": "discountPct is at least discountFlagPct.",
                            "examples": [
                              true
                            ]
                          },
                          "observedAt": {
                            "type": "string",
                            "title": "Read at",
                            "description": "When the reading was taken (UTC).",
                            "examples": [
                              "2026-10-24T05:12:00.000000Z"
                            ],
                            "format": "date-time"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "The (zero) charge.",
            "additionalProperties": false,
            "required": [
              "credits"
            ],
            "properties": {
              "credits": {
                "$ref": "#/components/schemas/NoCharge"
              }
            }
          }
        }
      },
      "OnboardingState": {
        "title": "OnboardingState",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "version",
          "updatedAt",
          "accountType",
          "company",
          "referral",
          "referralOther",
          "goals",
          "preferredAgent",
          "agentSetupReviewed",
          "defaults",
          "progress"
        ],
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0
          },
          "updatedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "accountType": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "personal",
              "company",
              null
            ],
            "description": "Personal or company, as the user states it; never inferred from their email."
          },
          "company": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "name",
              "domainHint"
            ],
            "properties": {
              "name": {
                "type": [
                  "null",
                  "string"
                ],
                "maxLength": 120
              },
              "domainHint": {
                "type": [
                  "null",
                  "string"
                ],
                "maxLength": 253,
                "description": "A hint from a company email; never a verified domain."
              }
            }
          },
          "referral": {
            "type": [
              "null",
              "string"
            ],
            "maxLength": 100,
            "description": "How the user heard of Rewalto (an option id)."
          },
          "referralOther": {
            "type": [
              "null",
              "string"
            ],
            "maxLength": 200
          },
          "goals": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "ids",
              "text"
            ],
            "properties": {
              "ids": {
                "type": "array",
                "maxItems": 7,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "description": "Chosen goal option ids."
              },
              "text": {
                "type": [
                  "null",
                  "string"
                ],
                "maxLength": 300
              }
            }
          },
          "preferredAgent": {
            "type": [
              "null",
              "string"
            ],
            "maxLength": 50
          },
          "agentSetupReviewed": {
            "type": "boolean"
          },
          "defaults": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "retailers",
              "pincodes",
              "locationIds",
              "categories",
              "brand"
            ],
            "description": "The defaults the user picked; the dashboard pre-fills searches and watches with them.",
            "properties": {
              "retailers": {
                "type": "array",
                "maxItems": 50,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "description": "Retailer slugs the user chose as their default set (e.g. blinkit, zepto)."
              },
              "pincodes": {
                "type": "array",
                "maxItems": 50,
                "items": {
                  "type": "string",
                  "pattern": "^[0-9]{6}$",
                  "description": "A six-digit Indian pin code."
                }
              },
              "locationIds": {
                "type": "array",
                "maxItems": 50,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "description": "Core location ids (GET /v1/locations) of the default areas, when chosen by name."
              },
              "categories": {
                "type": "array",
                "maxItems": 50,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                }
              },
              "brand": {
                "type": [
                  "null",
                  "string"
                ],
                "maxLength": 200,
                "description": "The user’s own brand, if they have one."
              }
            }
          },
          "progress": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "step",
              "completedSteps",
              "completedAt"
            ],
            "properties": {
              "step": {
                "type": "string",
                "enum": [
                  "account",
                  "goals",
                  "defaults",
                  "agent",
                  "done"
                ],
                "description": "Where to resume. `done`: onboarding is finished."
              },
              "completedSteps": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "account",
                    "goals",
                    "defaults",
                    "agent"
                  ]
                },
                "description": "The steps finished so far, in step order."
              },
              "completedAt": {
                "type": [
                  "null",
                  "string"
                ],
                "format": "date-time",
                "description": "When onboarding was finished; null until then."
              }
            }
          }
        }
      },
      "SaveOnboarding": {
        "title": "SaveOnboarding",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "version"
        ],
        "description": "A partial save: send only what changed. Objects (company, goals, defaults) merge field by field; an array you send replaces that array.",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0,
            "description": "The version you read (0 for a user who has never saved). A stale one is refused."
          },
          "accountType": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "personal",
              "company",
              null
            ],
            "description": "Personal or company, as the user states it; never inferred from their email."
          },
          "company": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "name": {
                "type": [
                  "null",
                  "string"
                ],
                "maxLength": 120
              },
              "domainHint": {
                "type": [
                  "null",
                  "string"
                ],
                "maxLength": 253,
                "description": "A hint from a company email; never a verified domain."
              }
            }
          },
          "referral": {
            "type": [
              "null",
              "string"
            ],
            "maxLength": 100,
            "description": "How the user heard of Rewalto (an option id)."
          },
          "referralOther": {
            "type": [
              "null",
              "string"
            ],
            "maxLength": 200
          },
          "goals": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "ids": {
                "type": "array",
                "maxItems": 7,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "description": "Chosen goal option ids."
              },
              "text": {
                "type": [
                  "null",
                  "string"
                ],
                "maxLength": 300
              }
            }
          },
          "preferredAgent": {
            "type": [
              "null",
              "string"
            ],
            "maxLength": 50
          },
          "agentSetupReviewed": {
            "type": "boolean"
          },
          "defaults": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "retailers": {
                "type": "array",
                "maxItems": 50,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "description": "Retailer slugs the user chose as their default set (e.g. blinkit, zepto)."
              },
              "pincodes": {
                "type": "array",
                "maxItems": 50,
                "items": {
                  "type": "string",
                  "pattern": "^[0-9]{6}$",
                  "description": "A six-digit Indian pin code."
                }
              },
              "locationIds": {
                "type": "array",
                "maxItems": 50,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                },
                "description": "Core location ids (GET /v1/locations) of the default areas, when chosen by name."
              },
              "categories": {
                "type": "array",
                "maxItems": 50,
                "items": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 100
                }
              },
              "brand": {
                "type": [
                  "null",
                  "string"
                ],
                "maxLength": 200,
                "description": "The user’s own brand, if they have one."
              }
            }
          },
          "step": {
            "type": "string",
            "enum": [
              "account",
              "goals",
              "defaults",
              "agent",
              "done"
            ],
            "description": "Move the resume point. `done` finishes onboarding (same as finish: true)."
          },
          "completeSteps": {
            "type": "array",
            "maxItems": 4,
            "items": {
              "type": "string",
              "enum": [
                "account",
                "goals",
                "defaults",
                "agent"
              ]
            },
            "description": "Mark these steps finished (added to the ones already finished)."
          },
          "finish": {
            "type": "boolean",
            "description": "true: onboarding is finished now (progress.step done, completedAt set once)."
          }
        }
      },
      "NotificationPreferences": {
        "title": "NotificationPreferences",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "version",
          "updatedAt",
          "categories",
          "quietHours",
          "digest"
        ],
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0
          },
          "updatedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "categories": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "price_alerts",
              "watch_changes",
              "report_ready",
              "data_requests",
              "credits_billing",
              "product_news"
            ],
            "description": "Per kind of notification: whether it shows in the feed (inApp) and may be emailed (email). product_news.email is the product-news consent. credits_billing mail about money is sent regardless; this controls only the optional kinds.",
            "properties": {
              "price_alerts": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "inApp",
                  "email"
                ],
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              },
              "watch_changes": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "inApp",
                  "email"
                ],
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              },
              "report_ready": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "inApp",
                  "email"
                ],
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              },
              "data_requests": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "inApp",
                  "email"
                ],
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              },
              "credits_billing": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "inApp",
                  "email"
                ],
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              },
              "product_news": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "inApp",
                  "email"
                ],
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "quietHours": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "enabled",
              "start",
              "end",
              "timezone"
            ],
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "start": {
                "type": "string",
                "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
                "description": "Local time, 24-hour HH:MM."
              },
              "end": {
                "type": "string",
                "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
                "description": "Local time, 24-hour HH:MM. May be earlier than start (overnight)."
              },
              "timezone": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64,
                "description": "An IANA time zone name, e.g. Asia/Kolkata."
              }
            }
          },
          "digest": {
            "type": "string",
            "enum": [
              "off",
              "daily",
              "weekly"
            ],
            "description": "off: each email on its own. daily/weekly: batch the optional emails."
          }
        }
      },
      "IntakeEnquiryCreate": {
        "title": "IntakeEnquiryCreate",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "visitorHash",
          "name",
          "workEmail",
          "topic",
          "message"
        ],
        "properties": {
          "visitorHash": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$",
            "description": "The visitor's salted SHA-256 (64 lowercase hex characters), made by the site from the visitor's IP address with its own salt (the old `sourceHash`). Never send the address. Counts the per-visitor limit: five an hour and twenty a day, shared by every door.",
            "examples": [
              "3f0c9a6b2d4e8f1a7c5b9d3e6f2a8c4b1d7e9f3a5c8b2d6e4f1a9c7b3d5e8f2a"
            ]
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "The sender's name (trimmed; 1 to 200 characters).",
            "examples": [
              "Asha Rao"
            ]
          },
          "workEmail": {
            "type": "string",
            "minLength": 3,
            "maxLength": 320,
            "pattern": "^[^\\s@]+@[^\\s@.]+(?:\\.[^\\s@.]+)+$",
            "description": "The sender's work email. Also limited: five an hour and twenty a day per address, across every door.",
            "examples": [
              "asha@brand.example"
            ]
          },
          "topic": {
            "type": "string",
            "enum": [
              "partnership",
              "press",
              "method",
              "other"
            ],
            "description": "What the message is about; it routes the message."
          },
          "message": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4000,
            "description": "The message (trimmed; 1 to 4,000 characters).",
            "examples": [
              "We would like to partner."
            ]
          }
        }
      },
      "IntakeLeadCreate": {
        "title": "IntakeLeadCreate",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "visitorHash",
          "source",
          "name",
          "brand",
          "website",
          "category",
          "workEmail"
        ],
        "properties": {
          "visitorHash": {
            "type": "string",
            "pattern": "^[0-9a-f]{64}$",
            "description": "The visitor's salted SHA-256 (64 lowercase hex characters), made by the site from the visitor's IP address with its own salt (the old `sourceHash`). Never send the address. Counts the per-visitor limit: five an hour and twenty a day, shared by every door.",
            "examples": [
              "3f0c9a6b2d4e8f1a7c5b9d3e6f2a8c4b1d7e9f3a5c8b2d6e4f1a9c7b3d5e8f2a"
            ]
          },
          "source": {
            "type": "string",
            "enum": [
              "scan",
              "portfolio",
              "data",
              "services"
            ],
            "description": "The door: `scan` (/talk and /site-audit), `portfolio`, `data`, `services` (/talk, and /for-startups). The old form turned an unknown value into `scan`; send one of these."
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "The sender's name (on /for-startups, the signed-in account's own name).",
            "examples": [
              "Asha Rao"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 32,
            "description": "A phone number with its dial code, e.g. `+91 98765 43210`: digits, spaces and + ( ) . - only, 7 to 15 digits. Null or left out on a door where it is optional (/for-startups' WhatsApp number).",
            "examples": [
              "+91 98765 43210"
            ]
          },
          "brand": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "The brand or store name.",
            "examples": [
              "Acme Foods"
            ]
          },
          "website": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500,
            "description": "The website to crawl, or the brand or store URL.",
            "examples": [
              "acme.example"
            ]
          },
          "category": {
            "type": "string",
            "minLength": 1,
            "maxLength": 300,
            "description": "The category someone would search for (on /for-startups: where the brand sells today).",
            "examples": [
              "cold-pressed juice"
            ]
          },
          "workEmail": {
            "type": "string",
            "minLength": 3,
            "maxLength": 320,
            "pattern": "^[^\\s@]+@[^\\s@.]+(?:\\.[^\\s@.]+)+$",
            "description": "The sender's work email. Also limited: five an hour and twenty a day per address, across every door.",
            "examples": [
              "asha@brand.example"
            ]
          },
          "role": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 100,
            "description": "The sender's role (on /for-startups: the brand's age). Optional; empty or null stores nothing."
          },
          "losesTo": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 500,
            "description": "Who the brand loses to (on /for-startups: the main problem). Optional; empty or null stores nothing."
          },
          "skus": {
            "type": [
              "string",
              "null"
            ],
            "maxLength": 4000,
            "description": "Up to 25 products, one a line (on /for-startups: the referral source and ref code, labelled). Optional; empty or null stores nothing."
          },
          "consent": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "textVersion"
            ],
            "description": "Send only when a consent box was shown AND ticked. Core stamps `consent_given_at` with its own clock in the same insert. Leave it out on a door with no consent box: consent is never invented.",
            "properties": {
              "textVersion": {
                "type": "string",
                "minLength": 1,
                "maxLength": 100,
                "description": "The version of the exact consent wording ticked (lib/consent-copy.ts)."
              },
              "confirmTokenHash": {
                "type": "string",
                "pattern": "^[0-9a-f]{64}$",
                "description": "The double opt-in token's SHA-256 (hex), never the token: the site mints the token, mails the link, and redeems it with POST /v1/service/intake/leads/confirm within 7 days."
              }
            }
          }
        }
      },
      "IntakeReceipt": {
        "title": "IntakeReceipt",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "receivedAt"
        ],
        "description": "What was stored: its id and time only. No submitted field is echoed back.",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "description": "The stored row (for the staff mail, and /site-audit's report and claim links)."
          },
          "receivedAt": {
            "type": "string",
            "format": "date-time",
            "description": "When Core stored it."
          }
        }
      },
      "IntakeLeadConfirm": {
        "title": "IntakeLeadConfirm",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "token"
        ],
        "properties": {
          "token": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{43}$",
            "description": "The token from the confirmation link (32 random bytes, base64url, 43 characters). Core hashes it; call this from the confirm page's button (a POST), never on a GET a mail scanner can follow."
          }
        }
      },
      "IntakeLeadConfirmAnswer": {
        "title": "IntakeLeadConfirmAnswer",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "status",
          "leadId"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "confirmed",
              "invalid"
            ],
            "description": "`confirmed`: the address is confirmed now. `invalid`: unknown, already used, older than 7 days, or scrubbed; deliberately one answer for all four."
          },
          "leadId": {
            "type": [
              "null",
              "string"
            ],
            "format": "uuid",
            "description": "The confirmed lead, for the staff note; null when invalid."
          }
        }
      },
      "SaveNotificationPreferences": {
        "title": "SaveNotificationPreferences",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "version"
        ],
        "description": "A partial save: send only what changed; each object merges field by field.",
        "properties": {
          "version": {
            "type": "integer",
            "minimum": 0,
            "description": "The version you read. A stale one is refused."
          },
          "categories": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "price_alerts": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              },
              "watch_changes": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              },
              "report_ready": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              },
              "data_requests": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              },
              "credits_billing": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              },
              "product_news": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "inApp": {
                    "type": "boolean"
                  },
                  "email": {
                    "type": "boolean"
                  }
                }
              }
            }
          },
          "quietHours": {
            "type": "object",
            "additionalProperties": false,
            "properties": {
              "enabled": {
                "type": "boolean"
              },
              "start": {
                "type": "string",
                "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
                "description": "Local time, 24-hour HH:MM."
              },
              "end": {
                "type": "string",
                "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
                "description": "Local time, 24-hour HH:MM. May be earlier than start (overnight)."
              },
              "timezone": {
                "type": "string",
                "minLength": 1,
                "maxLength": 64,
                "description": "An IANA time zone name, e.g. Asia/Kolkata."
              }
            }
          },
          "digest": {
            "type": "string",
            "enum": [
              "off",
              "daily",
              "weekly"
            ]
          }
        }
      },
      "AppNotification": {
        "title": "AppNotification",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "kind",
          "title",
          "body",
          "linkPath",
          "createdAt",
          "read",
          "readAt"
        ],
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid"
          },
          "kind": {
            "type": "string",
            "enum": [
              "price_alerts",
              "watch_changes",
              "report_ready",
              "data_requests",
              "credits_billing",
              "product_news"
            ]
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": [
              "null",
              "string"
            ]
          },
          "linkPath": {
            "type": [
              "null",
              "string"
            ],
            "description": "A path inside the dashboard to open when it is clicked."
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "read": {
            "type": "boolean"
          },
          "readAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          }
        }
      },
      "NotificationFeed": {
        "title": "NotificationFeed",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "unreadCount",
          "nextCursor"
        ],
        "properties": {
          "data": {
            "type": "array",
            "description": "Newest first.",
            "items": {
              "$ref": "#/components/schemas/AppNotification"
            }
          },
          "unreadCount": {
            "type": "integer",
            "minimum": 0,
            "description": "All unread notifications for the user, not only this page."
          },
          "nextCursor": {
            "type": [
              "null",
              "string"
            ],
            "description": "Pass as `before` for the next page; null when there is no more."
          }
        }
      },
      "MarkNotificationsRead": {
        "title": "MarkNotificationsRead",
        "type": "object",
        "additionalProperties": false,
        "description": "Send `ids`, or `all: true`.",
        "properties": {
          "ids": {
            "type": "array",
            "minItems": 1,
            "maxItems": 100,
            "items": {
              "type": "string",
              "format": "uuid"
            }
          },
          "all": {
            "type": "boolean",
            "description": "true: mark every unread notification read."
          }
        }
      },
      "MarkNotificationsReadResult": {
        "title": "MarkNotificationsReadResult",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "marked",
          "unreadCount"
        ],
        "properties": {
          "marked": {
            "type": "integer",
            "minimum": 0,
            "description": "How many were newly marked read."
          },
          "unreadCount": {
            "type": "integer",
            "minimum": 0
          }
        }
      },
      "WatchNotifyTarget": {
        "title": "WatchNotifyTarget",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "channel"
        ],
        "description": "One place a watch sends its changes. in_app needs no destination. email without a destinationId is the signed-in user's own verified address. slack, telegram and webhook need a destinationId.",
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "in_app",
              "email",
              "slack",
              "telegram",
              "webhook"
            ],
            "title": "Channel",
            "description": "in_app, email, slack, telegram or webhook."
          },
          "destinationId": {
            "type": [
              "string",
              "null"
            ],
            "pattern": "^dst_[0-9a-f]{32}$",
            "title": "Destination id",
            "description": "A destination from listNotificationDestinations; null or absent for in_app and your own email.",
            "examples": [
              "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
            ]
          }
        }
      },
      "WatchNotify": {
        "title": "WatchNotify",
        "type": "array",
        "maxItems": 10,
        "description": "Where this watch sends what changed, once per check that found new or gone listings. Default [{\"channel\":\"in_app\"}]. An empty list sends nothing. Changing it does not return a watch to draft: it changes no cost. Delivery is free.",
        "items": {
          "$ref": "#/components/schemas/WatchNotifyTarget"
        }
      },
      "NotificationDestination": {
        "title": "NotificationDestination",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "channel",
          "label",
          "status",
          "lastError",
          "lastCheckedAt",
          "telegramLink",
          "createdAt"
        ],
        "description": "One of your organisation's alert destinations. Its URL, secret, chat or address is never returned. status: pending (not linked or not tried yet), working (the last send or test went through), failing (the last one did not; lastError says why).",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^dst_[0-9a-f]{32}$",
            "title": "Destination id",
            "description": "A destination from listNotificationDestinations.",
            "examples": [
              "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
            ]
          },
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "slack",
              "telegram",
              "webhook"
            ],
            "title": "Channel",
            "description": "email, slack, telegram or webhook."
          },
          "label": {
            "type": "string",
            "title": "Label",
            "description": "A readable name, e.g. \"#pricing on Slack\".",
            "examples": [
              "#pricing on Slack"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "working",
              "failing"
            ],
            "title": "Status",
            "description": "pending, working or failing."
          },
          "lastError": {
            "type": [
              "null",
              "string"
            ],
            "title": "Last error",
            "description": "Why the last send failed; null otherwise.",
            "examples": [
              "chat not found"
            ]
          },
          "lastCheckedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "title": "Last checked",
            "description": "When it was last sent to or tested; null if never.",
            "examples": [
              "2026-10-22T07:38:00.000Z"
            ]
          },
          "telegramLink": {
            "type": [
              "null",
              "object"
            ],
            "title": "Telegram link",
            "description": "For a Telegram destination not linked yet: open one of these links (a chat with the bot, or add it to a group), press Start, then call testNotificationDestination. Null otherwise.",
            "additionalProperties": false,
            "required": [
              "code",
              "chatUrl",
              "groupUrl"
            ],
            "properties": {
              "code": {
                "type": "string",
                "title": "Code",
                "description": "The link code.",
                "examples": [
                  "k3J9aQ2mX7pL0vB5"
                ]
              },
              "chatUrl": {
                "type": "string",
                "title": "Chat link",
                "description": "Link a private chat with the bot.",
                "examples": [
                  "https://t.me/rewalto_bot?start=k3J9aQ2mX7pL0vB5"
                ]
              },
              "groupUrl": {
                "type": "string",
                "title": "Group link",
                "description": "Add the bot to a group and link that group.",
                "examples": [
                  "https://t.me/rewalto_bot?startgroup=k3J9aQ2mX7pL0vB5"
                ]
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "title": "Created",
            "description": "When it was added.",
            "examples": [
              "2026-10-22T07:38:00.000Z"
            ]
          }
        }
      },
      "NotificationDestinationsPage": {
        "title": "NotificationDestinationsPage",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Destinations",
            "description": "The organisation's destinations, newest first.",
            "items": {
              "$ref": "#/components/schemas/NotificationDestination"
            }
          }
        }
      },
      "CreateNotificationDestination": {
        "title": "CreateNotificationDestination",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "channel"
        ],
        "description": "Add a destination. slack: an incoming webhook URL (https://hooks.slack.com/services/...). webhook: your https URL; the answer carries its signing secret ONCE. telegram: no URL; the answer carries the links to press Start with. email: no URL; your own verified sign-in address (a signed-in session only). label is optional.",
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "email",
              "slack",
              "telegram",
              "webhook"
            ],
            "title": "Channel",
            "description": "email, slack, telegram or webhook."
          },
          "label": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "title": "Label",
            "description": "How it is shown, e.g. \"#pricing\". A default is made from the channel.",
            "examples": [
              "#pricing"
            ]
          },
          "url": {
            "type": "string",
            "minLength": 12,
            "maxLength": 2000,
            "title": "URL",
            "description": "For slack and webhook only.",
            "examples": [
              "https://example.com/rewalto/alerts"
            ]
          }
        }
      },
      "NotificationDestinationCreated": {
        "title": "NotificationDestinationCreated",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "signingSecret"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/NotificationDestination"
          },
          "signingSecret": {
            "type": [
              "null",
              "string"
            ],
            "title": "Signing secret",
            "description": "For a webhook only, shown this once: every delivery carries Rewalto-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256 of \"<t>.<body>\" with this secret>. Null for other channels.",
            "examples": [
              "whsec_EXAMPLEONLYEXAMPLEONLYEXAMPLEONLY"
            ]
          }
        }
      },
      "NotificationDestinationAnswer": {
        "title": "NotificationDestinationAnswer",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "$ref": "#/components/schemas/NotificationDestination"
          }
        }
      },
      "WatchDelivery": {
        "title": "WatchDelivery",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "id",
          "runId",
          "channel",
          "destinationId",
          "destinationLabel",
          "state",
          "skipReason",
          "error",
          "notBefore",
          "sentAt",
          "createdAt"
        ],
        "description": "One send of one check to one destination: sent, failed (error says why; the check itself is unaffected), queued (waiting for quiet hours to end) or skipped (a notification preference turned it off).",
        "properties": {
          "id": {
            "type": "string",
            "format": "uuid",
            "title": "Id",
            "description": "The delivery."
          },
          "runId": {
            "type": "string",
            "format": "uuid",
            "title": "Refresh",
            "description": "The check it reports."
          },
          "channel": {
            "type": "string",
            "enum": [
              "in_app",
              "email",
              "slack",
              "telegram",
              "webhook"
            ],
            "title": "Channel",
            "description": "The channel."
          },
          "destinationId": {
            "type": [
              "null",
              "string"
            ],
            "pattern": "^dst_[0-9a-f]{32}$",
            "title": "Destination id",
            "description": "Null for in_app.",
            "examples": [
              "dst_3f2a9c1e5b7d4e8f9a0b1c2d3e4f5a6b"
            ]
          },
          "destinationLabel": {
            "type": "string",
            "title": "Destination",
            "description": "The destination as named when sent.",
            "examples": [
              "#pricing on Slack"
            ]
          },
          "state": {
            "type": "string",
            "enum": [
              "queued",
              "sent",
              "failed",
              "skipped"
            ],
            "title": "State",
            "description": "queued, sent, failed or skipped."
          },
          "skipReason": {
            "type": [
              "null",
              "string"
            ],
            "enum": [
              "preference_off",
              null
            ],
            "title": "Skip reason",
            "description": "preference_off when the notification preferences turned it off; null otherwise."
          },
          "error": {
            "type": [
              "null",
              "string"
            ],
            "title": "Error",
            "description": "Why it failed; null otherwise.",
            "examples": [
              "Telegram: chat not found"
            ]
          },
          "notBefore": {
            "type": "string",
            "format": "date-time",
            "title": "Not before",
            "description": "When it may be sent (later than the check during quiet hours).",
            "examples": [
              "2026-10-22T07:38:00.000Z"
            ]
          },
          "sentAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "title": "Sent",
            "description": "When it was sent; null if not.",
            "examples": [
              "2026-10-22T07:38:00.000Z"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time",
            "title": "Created",
            "description": "When the check queued it.",
            "examples": [
              "2026-10-22T07:38:00.000Z"
            ]
          }
        }
      },
      "WatchDeliveriesPage": {
        "title": "WatchDeliveriesPage",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "data",
          "page"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Deliveries",
            "description": "Newest first.",
            "items": {
              "$ref": "#/components/schemas/WatchDelivery"
            }
          },
          "page": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "Page size."
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Pass as cursor; null at the end.",
                "examples": [
                  "eyJvIjoyMH0"
                ]
              }
            }
          }
        }
      },
      "SeriesAnswer": {
        "type": "object",
        "title": "Series",
        "description": "Daily series per group with honest gaps, and what the read cost.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Groups",
            "description": "One entry per group; every group lists every IST day of the window in order.",
            "items": {
              "type": "object",
              "title": "Series group",
              "description": "One group and its days.",
              "additionalProperties": false,
              "required": [
                "key",
                "points"
              ],
              "properties": {
                "key": {
                  "type": "object",
                  "title": "Group",
                  "description": "What the group is along the groupBy dimension; the other fields are null.",
                  "additionalProperties": false,
                  "required": [
                    "retailer",
                    "pincode",
                    "brand",
                    "productId"
                  ],
                  "properties": {
                    "retailer": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Retailer",
                      "description": "The retailer key.",
                      "examples": [
                        "blinkit"
                      ]
                    },
                    "pincode": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Pin code",
                      "description": "The pin code, or national.",
                      "examples": [
                        "110092"
                      ],
                      "pattern": "^([1-9][0-9]{5}|national)$"
                    },
                    "brand": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Brand",
                      "description": "The brand as the retailer wrote it.",
                      "examples": [
                        "Aashirvaad"
                      ]
                    },
                    "productId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Product",
                      "description": "The Rewalto product id.",
                      "examples": [
                        "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
                      ],
                      "format": "uuid"
                    }
                  }
                },
                "points": {
                  "type": "array",
                  "title": "Points",
                  "description": "Every IST day of the window, gaps included.",
                  "items": {
                    "type": "object",
                    "title": "Series point",
                    "description": "One IST day of one group.",
                    "additionalProperties": false,
                    "required": [
                      "day",
                      "gap",
                      "partial",
                      "readings",
                      "price",
                      "availability",
                      "position"
                    ],
                    "properties": {
                      "day": {
                        "type": "string",
                        "title": "Day",
                        "description": "The IST calendar day.",
                        "examples": [
                          "2026-10-14"
                        ],
                        "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                      },
                      "gap": {
                        "type": "boolean",
                        "title": "Gap",
                        "description": "True when no reading exists for this day; the values are null.",
                        "examples": [
                          false
                        ]
                      },
                      "partial": {
                        "type": "boolean",
                        "title": "Partial",
                        "description": "True when the window starts or ends inside this day.",
                        "examples": [
                          false
                        ]
                      },
                      "readings": {
                        "type": "integer",
                        "title": "Readings",
                        "description": "How many readings of the day are in this point.",
                        "examples": [
                          12
                        ],
                        "minimum": 0
                      },
                      "price": {
                        "type": [
                          "null",
                          "object"
                        ],
                        "title": "Price",
                        "description": "The prices readings showed on this day; null on a gap or when no reading showed a price.",
                        "additionalProperties": false,
                        "required": [
                          "minMinor",
                          "medianMinor",
                          "maxMinor",
                          "mrpMedianMinor",
                          "readings"
                        ],
                        "properties": {
                          "minMinor": {
                            "type": "integer",
                            "title": "Lowest price",
                            "description": "Lowest price of the day, in paise.",
                            "examples": [
                              28500
                            ],
                            "minimum": 0
                          },
                          "medianMinor": {
                            "type": "integer",
                            "title": "Middle price",
                            "description": "The middle reading of the day (a real reading, not an average), in paise.",
                            "examples": [
                              28500
                            ],
                            "minimum": 0
                          },
                          "maxMinor": {
                            "type": "integer",
                            "title": "Highest price",
                            "description": "Highest price of the day, in paise.",
                            "examples": [
                              29900
                            ],
                            "minimum": 0
                          },
                          "mrpMedianMinor": {
                            "type": [
                              "null",
                              "integer"
                            ],
                            "title": "Middle MRP",
                            "description": "The middle list price among readings that showed one, in paise; null when none did.",
                            "examples": [
                              31000
                            ],
                            "minimum": 0
                          },
                          "readings": {
                            "type": "integer",
                            "title": "Priced readings",
                            "description": "How many readings of the day showed a price.",
                            "examples": [
                              12
                            ],
                            "minimum": 1
                          }
                        }
                      },
                      "availability": {
                        "type": [
                          "null",
                          "object"
                        ],
                        "title": "Stock",
                        "description": "Readings counted by what they said; null on a gap.",
                        "additionalProperties": false,
                        "required": [
                          "inStock",
                          "outOfStock",
                          "unknown",
                          "inStockShare"
                        ],
                        "properties": {
                          "inStock": {
                            "type": "integer",
                            "title": "In stock",
                            "description": "Readings that said in stock.",
                            "examples": [
                              10
                            ],
                            "minimum": 0
                          },
                          "outOfStock": {
                            "type": "integer",
                            "title": "Out of stock",
                            "description": "Readings that said out of stock.",
                            "examples": [
                              2
                            ],
                            "minimum": 0
                          },
                          "unknown": {
                            "type": "integer",
                            "title": "Unknown",
                            "description": "Readings that did not say (every Flipkart reading).",
                            "examples": [
                              0
                            ],
                            "minimum": 0
                          },
                          "inStockShare": {
                            "type": [
                              "null",
                              "number"
                            ],
                            "title": "In-stock share",
                            "description": "In stock out of the readings that said; null when none said.",
                            "examples": [
                              0.83
                            ],
                            "minimum": 0,
                            "maximum": 1
                          }
                        }
                      },
                      "position": {
                        "type": [
                          "null",
                          "object"
                        ],
                        "title": "Search position",
                        "description": "The place in the retailer's search results, from readings that recorded one; null when none did. Not a category rank.",
                        "additionalProperties": false,
                        "required": [
                          "best",
                          "average",
                          "readings"
                        ],
                        "properties": {
                          "best": {
                            "type": "integer",
                            "title": "Best place",
                            "description": "The lowest (best) place of the day.",
                            "examples": [
                              2
                            ],
                            "minimum": 1
                          },
                          "average": {
                            "type": "number",
                            "title": "Average place",
                            "description": "The average place of the day, to two decimals.",
                            "examples": [
                              3.5
                            ],
                            "minimum": 1
                          },
                          "readings": {
                            "type": "integer",
                            "title": "Readings",
                            "description": "How many readings recorded a place.",
                            "examples": [
                              4
                            ],
                            "minimum": 1
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "The window, the counts and the cost.",
            "additionalProperties": false,
            "required": [
              "kind",
              "asOf",
              "firstDay",
              "lastDay",
              "groupBy",
              "days",
              "points",
              "gaps",
              "credits"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "title": "Kind",
                "description": "kept: read from data Rewalto stores as history.",
                "examples": [
                  "kept"
                ],
                "enum": [
                  "kept"
                ]
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "As of",
                "description": "The newest ingestion time among the readings; null when none.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ],
                "format": "date-time"
              },
              "firstDay": {
                "type": "string",
                "title": "First day",
                "description": "First IST day of the window.",
                "examples": [
                  "2026-09-15"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              },
              "lastDay": {
                "type": "string",
                "title": "Last day",
                "description": "Last IST day of the window.",
                "examples": [
                  "2026-10-14"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              },
              "groupBy": {
                "type": "string",
                "title": "Group by",
                "description": "The dimension the groups are along.",
                "examples": [
                  "none"
                ],
                "enum": [
                  "none",
                  "retailer",
                  "pincode",
                  "brand",
                  "product"
                ]
              },
              "days": {
                "type": "integer",
                "title": "Days",
                "description": "IST days in the window.",
                "examples": [
                  30
                ],
                "minimum": 1
              },
              "points": {
                "type": "integer",
                "title": "Points with readings",
                "description": "Points that hold at least one reading, across groups: what is charged.",
                "examples": [
                  30
                ],
                "minimum": 0
              },
              "gaps": {
                "type": "integer",
                "title": "Gaps",
                "description": "Points with no reading, across groups.",
                "examples": [
                  0
                ],
                "minimum": 0
              },
              "credits": {
                "type": "object",
                "title": "Credits",
                "description": "What this response cost, at the published history rate. Gaps and a free re-read cost nothing.",
                "additionalProperties": false,
                "required": [
                  "charged",
                  "units",
                  "freeReread",
                  "rate"
                ],
                "properties": {
                  "charged": {
                    "type": "integer",
                    "title": "Credits charged",
                    "description": "Credits taken for this response.",
                    "examples": [
                      3
                    ],
                    "minimum": 0
                  },
                  "units": {
                    "type": "integer",
                    "title": "Points delivered",
                    "description": "Points with readings.",
                    "examples": [
                      30
                    ],
                    "minimum": 0
                  },
                  "freeReread": {
                    "type": "boolean",
                    "title": "Free re-read",
                    "description": "True when identical data was read within 7 days.",
                    "examples": [
                      false
                    ]
                  },
                  "rate": {
                    "type": [
                      "null",
                      "object"
                    ],
                    "title": "Published rate",
                    "description": "Credits per number of points, and the rate version; null when nothing was charged.",
                    "additionalProperties": false,
                    "required": [
                      "credits",
                      "perUnits",
                      "version"
                    ],
                    "properties": {
                      "credits": {
                        "type": "integer",
                        "title": "Credits",
                        "description": "Credits per perUnits.",
                        "examples": [
                          1
                        ],
                        "minimum": 1
                      },
                      "perUnits": {
                        "type": "integer",
                        "title": "Per units",
                        "description": "Points the credits cover.",
                        "examples": [
                          10
                        ],
                        "minimum": 1
                      },
                      "version": {
                        "type": "string",
                        "title": "Version",
                        "description": "The rate card version.",
                        "examples": [
                          "2"
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "SeriesCountAnswer": {
        "type": "object",
        "title": "Series count",
        "description": "What a series read would deliver; free, no prices.",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Count",
            "description": "The scope counted.",
            "additionalProperties": false,
            "required": [
              "firstDay",
              "lastDay",
              "groupBy",
              "groups",
              "days",
              "points",
              "gaps",
              "readings",
              "asOf"
            ],
            "properties": {
              "firstDay": {
                "type": "string",
                "title": "First day",
                "description": "First IST day.",
                "examples": [
                  "2026-09-15"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              },
              "lastDay": {
                "type": "string",
                "title": "Last day",
                "description": "Last IST day.",
                "examples": [
                  "2026-10-14"
                ],
                "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
              },
              "groupBy": {
                "type": "string",
                "title": "Group by",
                "description": "The dimension.",
                "examples": [
                  "none"
                ],
                "enum": [
                  "none",
                  "retailer",
                  "pincode",
                  "brand",
                  "product"
                ]
              },
              "groups": {
                "type": "integer",
                "title": "Groups",
                "description": "How many groups.",
                "examples": [
                  1
                ],
                "minimum": 0
              },
              "days": {
                "type": "integer",
                "title": "Days",
                "description": "IST days in the window.",
                "examples": [
                  30
                ],
                "minimum": 1
              },
              "points": {
                "type": "integer",
                "title": "Points with readings",
                "description": "What a series read is charged on.",
                "examples": [
                  30
                ],
                "minimum": 0
              },
              "gaps": {
                "type": "integer",
                "title": "Gaps",
                "description": "Points with no reading.",
                "examples": [
                  0
                ],
                "minimum": 0
              },
              "readings": {
                "type": "integer",
                "title": "Readings",
                "description": "Readings in scope.",
                "examples": [
                  360
                ],
                "minimum": 0
              },
              "asOf": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "As of",
                "description": "Newest ingestion time; null when none.",
                "examples": [
                  "2026-10-14T10:40:00Z"
                ],
                "format": "date-time"
              }
            }
          }
        }
      },
      "ReportArchivePage": {
        "type": "object",
        "title": "Report archive",
        "description": "One page of the files behind your reports. Free.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Files",
            "description": "Files in order: newest edition first, report files before supporting files, then by name.",
            "items": {
              "type": "object",
              "title": "Archive file",
              "description": "One file of one report edition. Ask POST /v1/reports/{id}/link with file for a signed link.",
              "additionalProperties": false,
              "required": [
                "editionId",
                "editionTitle",
                "editionKind",
                "subject",
                "window",
                "name",
                "role",
                "format",
                "contentType",
                "bytes",
                "sha256",
                "createdAt",
                "availableUntil",
                "expired"
              ],
              "properties": {
                "editionId": {
                  "type": "string",
                  "title": "Report",
                  "description": "The edition (GET /v1/reports/{id}).",
                  "examples": [
                    "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
                  ],
                  "format": "uuid"
                },
                "editionTitle": {
                  "type": "string",
                  "title": "Report title",
                  "description": "The report the file belongs to.",
                  "examples": [
                    "The Love Co. - Shelf Watch report"
                  ]
                },
                "editionKind": {
                  "type": "string",
                  "title": "Report kind",
                  "description": "The report type.",
                  "examples": [
                    "brand_shelf"
                  ]
                },
                "subject": {
                  "type": "object",
                  "title": "Subject",
                  "description": "What the report is about.",
                  "additionalProperties": false,
                  "required": [
                    "kind",
                    "name"
                  ],
                  "properties": {
                    "kind": {
                      "type": "string",
                      "title": "Kind",
                      "description": "brand, category, retailer or dataset.",
                      "examples": [
                        "brand"
                      ]
                    },
                    "name": {
                      "type": "string",
                      "title": "Name",
                      "description": "As the report names it.",
                      "examples": [
                        "The Love Co."
                      ]
                    }
                  }
                },
                "window": {
                  "type": "object",
                  "title": "Window",
                  "description": "The data period of the report.",
                  "additionalProperties": false,
                  "required": [
                    "from",
                    "to"
                  ],
                  "properties": {
                    "from": {
                      "type": "string",
                      "title": "From",
                      "description": "First day.",
                      "examples": [
                        "2026-09-01"
                      ],
                      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                    },
                    "to": {
                      "type": "string",
                      "title": "To",
                      "description": "Last day.",
                      "examples": [
                        "2026-09-30"
                      ],
                      "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}$"
                    }
                  }
                },
                "name": {
                  "type": "string",
                  "title": "Name",
                  "description": "The file name within the report.",
                  "examples": [
                    "data/prices.csv"
                  ]
                },
                "role": {
                  "type": "string",
                  "title": "Role",
                  "description": "report or data.",
                  "examples": [
                    "data"
                  ],
                  "enum": [
                    "report",
                    "data"
                  ]
                },
                "format": {
                  "type": "string",
                  "title": "Format",
                  "description": "The file format.",
                  "examples": [
                    "csv"
                  ]
                },
                "contentType": {
                  "type": "string",
                  "title": "Content type",
                  "description": "The media type.",
                  "examples": [
                    "text/csv; charset=utf-8"
                  ]
                },
                "bytes": {
                  "type": "integer",
                  "title": "Bytes",
                  "description": "Size in bytes.",
                  "examples": [
                    20481
                  ],
                  "minimum": 0
                },
                "sha256": {
                  "type": "string",
                  "title": "SHA-256",
                  "description": "Checksum of the file.",
                  "examples": [
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                  ],
                  "pattern": "^[0-9a-f]{64}$"
                },
                "createdAt": {
                  "type": "string",
                  "title": "Made",
                  "description": "When the edition was made.",
                  "examples": [
                    "2026-10-17T10:00:00Z"
                  ],
                  "format": "date-time"
                },
                "availableUntil": {
                  "type": "string",
                  "title": "Available until",
                  "description": "Edition expiry (12 months).",
                  "examples": [
                    "2027-10-17T10:00:00Z"
                  ],
                  "format": "date-time"
                },
                "expired": {
                  "type": "boolean",
                  "title": "Expired",
                  "description": "True once the edition has expired; listed, not linkable.",
                  "examples": [
                    false
                  ]
                }
              }
            }
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "title": "Limit",
                "description": "Page size.",
                "examples": [
                  50
                ],
                "minimum": 1
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Send back with the same filters; null on the last page.",
                "examples": [
                  "eyJ0IjoiMjAyNi0xMC0xNCJ9"
                ]
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "Totals over the whole filter, not just this page.",
            "additionalProperties": false,
            "required": [
              "totalFiles",
              "totalBytes"
            ],
            "properties": {
              "totalFiles": {
                "type": "integer",
                "title": "Files",
                "description": "All files matching.",
                "examples": [
                  91
                ],
                "minimum": 0
              },
              "totalBytes": {
                "type": "integer",
                "title": "Bytes",
                "description": "Their total size.",
                "examples": [
                  1048576
                ],
                "minimum": 0
              }
            }
          }
        }
      },
      "GlobalSearchAnswer": {
        "type": "object",
        "title": "Global search results",
        "description": "Free, read-only. No prices and no counts of paid data.",
        "additionalProperties": false,
        "required": [
          "data",
          "meta"
        ],
        "properties": {
          "data": {
            "type": "array",
            "title": "Groups",
            "description": "One entry per searched group, in the order reports, saved, products, brands.",
            "items": {
              "type": "object",
              "title": "Group result",
              "description": "Matches in one group.",
              "additionalProperties": false,
              "required": [
                "group",
                "status",
                "items",
                "more"
              ],
              "properties": {
                "group": {
                  "type": "string",
                  "title": "Group",
                  "description": "The group.",
                  "examples": [
                    "reports"
                  ],
                  "enum": [
                    "reports",
                    "saved",
                    "products",
                    "brands"
                  ]
                },
                "status": {
                  "type": "string",
                  "title": "Status",
                  "description": "searched, or not_available when this caller cannot see the group (an API key sees products and brands only; reports and saved items are staff-only until customers are enabled).",
                  "examples": [
                    "searched"
                  ],
                  "enum": [
                    "searched",
                    "not_available"
                  ]
                },
                "items": {
                  "type": "array",
                  "title": "Items",
                  "description": "The best matches.",
                  "items": {
                    "type": "object",
                    "title": "Item",
                    "description": "One match.",
                    "additionalProperties": false,
                    "required": [
                      "group",
                      "type",
                      "id",
                      "title",
                      "subtitle",
                      "href",
                      "imageUrl"
                    ],
                    "properties": {
                      "group": {
                        "type": "string",
                        "title": "Group",
                        "description": "The group.",
                        "examples": [
                          "reports"
                        ],
                        "enum": [
                          "reports",
                          "saved",
                          "products",
                          "brands"
                        ]
                      },
                      "type": {
                        "type": "string",
                        "title": "Type",
                        "description": "What it is.",
                        "examples": [
                          "report"
                        ],
                        "enum": [
                          "report",
                          "report_schedule",
                          "data_request",
                          "product",
                          "brand"
                        ]
                      },
                      "id": {
                        "type": "string",
                        "title": "Id",
                        "description": "Its id or reference.",
                        "examples": [
                          "0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
                        ]
                      },
                      "title": {
                        "type": "string",
                        "title": "Title",
                        "description": "What to show.",
                        "examples": [
                          "The Love Co. - Shelf Watch report"
                        ]
                      },
                      "subtitle": {
                        "type": [
                          "null",
                          "string"
                        ],
                        "title": "Subtitle",
                        "description": "A second line; null when none.",
                        "examples": [
                          "brand - 2026-09-01 to 2026-09-30"
                        ]
                      },
                      "href": {
                        "type": "string",
                        "title": "Route",
                        "description": "The API route that opens it.",
                        "examples": [
                          "/v1/reports/0d6b4a52-4b6e-4c1a-9a7e-5b0d2f8f1a11"
                        ]
                      },
                      "imageUrl": {
                        "type": [
                          "null",
                          "string"
                        ],
                        "title": "Image",
                        "description": "An image address; null when none.",
                        "examples": [
                          "https://cdn.example.com/atta.jpg"
                        ]
                      }
                    }
                  }
                },
                "more": {
                  "type": "boolean",
                  "title": "More",
                  "description": "True when more matches exist than shown.",
                  "examples": [
                    false
                  ]
                }
              }
            }
          },
          "meta": {
            "type": "object",
            "title": "Meta",
            "description": "The words searched.",
            "additionalProperties": false,
            "required": [
              "q"
            ],
            "properties": {
              "q": {
                "type": "string",
                "title": "Words",
                "description": "The words as searched.",
                "examples": [
                  "love co"
                ]
              }
            }
          }
        }
      },
      "CreateRecipeDraftRequest": {
        "title": "CreateRecipeDraftRequest",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "entry"
        ],
        "properties": {
          "entry": {
            "type": "object",
            "description": "The complete recipe entry (catalogue data, snake_case): checked against the recipe entry schema (@rewalto/contracts RECIPE_ENTRY_SCHEMA); a problem is `invalid_request` with the paths that failed. `recipe_id` must be the recipe in the path."
          },
          "recipe": {
            "description": "Needed only for a recipe's first version: where it comes from and, for a keep recipe, the collection its results are kept in. For a recipe that exists it must match, or be left out.",
            "type": "object",
            "additionalProperties": false,
            "required": [
              "providerId"
            ],
            "properties": {
              "providerId": {
                "type": "string",
                "pattern": "^[a-z][a-z0-9_]{1,63}$"
              },
              "collectionId": {
                "type": [
                  "string",
                  "null"
                ],
                "pattern": "^[a-z][a-z0-9_]{1,63}$"
              }
            }
          }
        }
      },
      "RetireRecipeRequest": {
        "title": "RetireRecipeRequest",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "reason"
        ],
        "properties": {
          "reason": {
            "type": "string",
            "minLength": 1,
            "maxLength": 500
          }
        }
      },
      "RecipeSmokeRun": {
        "title": "RecipeSmokeRun",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "ranAt",
          "passed",
          "reason",
          "records",
          "refused",
          "missingKeys",
          "newKeys"
        ],
        "properties": {
          "ranAt": {
            "type": "string",
            "format": "date-time"
          },
          "passed": {
            "type": "boolean"
          },
          "reason": {
            "type": "string"
          },
          "records": {
            "type": "integer",
            "minimum": 0
          },
          "refused": {
            "type": "integer",
            "minimum": 0
          },
          "missingKeys": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "T0h: keys the last run with records had and this one lacked."
          },
          "newKeys": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "RecipeVersion": {
        "title": "RecipeVersion",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "recipeId",
          "version",
          "status",
          "mode",
          "runner",
          "testsPassedAt",
          "smokePassedAt",
          "statusChangedAt",
          "publishedAt",
          "retiredAt",
          "createdBy",
          "createdAt",
          "lastSmokeRun",
          "entry"
        ],
        "properties": {
          "recipeId": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "tested",
              "published",
              "degraded",
              "retired"
            ]
          },
          "mode": {
            "type": "string",
            "enum": [
              "keep",
              "live"
            ]
          },
          "runner": {
            "type": "string"
          },
          "testsPassedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "When its fixture and output-schema tests last passed."
          },
          "smokePassedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time",
            "description": "When its live smoke check last passed."
          },
          "statusChangedAt": {
            "type": "string",
            "format": "date-time"
          },
          "publishedAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "retiredAt": {
            "type": [
              "null",
              "string"
            ],
            "format": "date-time"
          },
          "createdBy": {
            "type": "string"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastSmokeRun": {
            "title": "RecipeSmokeRunOrNone",
            "type": [
              "null",
              "object"
            ],
            "additionalProperties": false,
            "required": [
              "ranAt",
              "passed",
              "reason",
              "records",
              "refused",
              "missingKeys",
              "newKeys"
            ],
            "properties": {
              "ranAt": {
                "type": "string",
                "format": "date-time"
              },
              "passed": {
                "type": "boolean"
              },
              "reason": {
                "type": "string"
              },
              "records": {
                "type": "integer",
                "minimum": 0
              },
              "refused": {
                "type": "integer",
                "minimum": 0
              },
              "missingKeys": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "T0h: keys the last run with records had and this one lacked."
              },
              "newKeys": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            },
            "description": "Its latest smoke check run, or null before the first."
          },
          "entry": {
            "type": "object",
            "description": "The recipe entry, as stored (snake_case catalogue data)."
          }
        }
      },
      "RecipeVersionAnswer": {
        "title": "RecipeVersionAnswer",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "version"
        ],
        "properties": {
          "version": {
            "$ref": "#/components/schemas/RecipeVersion"
          }
        }
      },
      "RecipeTestReport": {
        "title": "RecipeTestReport",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "recipeId",
          "version",
          "passed",
          "fixtureTest",
          "outputSchemaTest"
        ],
        "properties": {
          "recipeId": {
            "type": "string"
          },
          "version": {
            "type": "string"
          },
          "passed": {
            "type": "boolean"
          },
          "fixtureTest": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "passed",
              "problems",
              "rowsByFixture"
            ],
            "properties": {
              "passed": {
                "type": "boolean"
              },
              "problems": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "rowsByFixture": {
                "type": "object",
                "additionalProperties": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            }
          },
          "outputSchemaTest": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "passed",
              "problems",
              "rowsChecked"
            ],
            "properties": {
              "passed": {
                "type": "boolean"
              },
              "problems": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "rowsChecked": {
                "type": "integer",
                "minimum": 0
              }
            }
          }
        }
      },
      "RecipeTestAnswer": {
        "title": "RecipeTestAnswer",
        "type": "object",
        "additionalProperties": false,
        "required": [
          "report",
          "version"
        ],
        "properties": {
          "report": {
            "$ref": "#/components/schemas/RecipeTestReport"
          },
          "version": {
            "$ref": "#/components/schemas/RecipeVersion"
          }
        }
      },
      "ReportDataRequest": {
        "type": "object",
        "title": "Report data request",
        "description": "The data one report needs: the datasets, for each its fields (default: all) and filters, and the reporting period. Free to count and quote.",
        "additionalProperties": false,
        "required": [
          "datasets",
          "period"
        ],
        "properties": {
          "datasets": {
            "type": "array",
            "items": {
              "type": "object",
              "title": "Dataset request",
              "description": "One dataset, narrowed.",
              "additionalProperties": false,
              "required": [
                "dataset"
              ],
              "properties": {
                "dataset": {
                  "type": "string",
                  "enum": [
                    "listings",
                    "observations",
                    "rating_changes",
                    "banner_placements",
                    "brand_mentions",
                    "promo_emails",
                    "storefront_promos",
                    "ad_creatives",
                    "brands",
                    "retailers"
                  ],
                  "title": "Dataset",
                  "description": "Which dataset.",
                  "examples": [
                    "listings"
                  ]
                },
                "fields": {
                  "type": "array",
                  "items": {
                    "type": "string",
                    "pattern": "^[a-zA-Z][a-zA-Z0-9_]{0,60}$"
                  },
                  "title": "Fields",
                  "description": "Only these fields of each record (the record id and its source fields are always included). Default: all.",
                  "maxItems": 100,
                  "uniqueItems": true,
                  "examples": [
                    [
                      "retailer",
                      "priceMinor",
                      "mrpMinor",
                      "observedAt"
                    ]
                  ]
                },
                "filters": {
                  "type": "object",
                  "title": "Report data filters",
                  "description": "Narrow a dataset. Values are exact (brands as retailers write them). Each dataset supports only some filters.",
                  "additionalProperties": false,
                  "required": [],
                  "properties": {
                    "retailers": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200,
                        "pattern": "^[a-z0-9_]{1,40}$"
                      },
                      "title": "Retailers",
                      "description": "Retailer ids.",
                      "minItems": 1,
                      "maxItems": 200,
                      "uniqueItems": true,
                      "examples": [
                        [
                          "blinkit",
                          "zepto"
                        ]
                      ]
                    },
                    "brands": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      "title": "Brands",
                      "description": "Brands, exactly as written.",
                      "minItems": 1,
                      "maxItems": 200,
                      "uniqueItems": true,
                      "examples": [
                        [
                          "The Love Co."
                        ]
                      ]
                    },
                    "pincodes": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200,
                        "pattern": "^[1-9][0-9]{5}$"
                      },
                      "title": "Pin codes",
                      "description": "Six-digit pin codes.",
                      "minItems": 1,
                      "maxItems": 200,
                      "uniqueItems": true,
                      "examples": [
                        [
                          "560001"
                        ]
                      ]
                    },
                    "productIds": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200,
                        "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                      },
                      "title": "Products",
                      "description": "Core product ids.",
                      "minItems": 1,
                      "maxItems": 200,
                      "uniqueItems": true,
                      "examples": [
                        [
                          "8d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a"
                        ]
                      ]
                    },
                    "retailerSkus": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      "title": "Retailer SKUs",
                      "description": "Retailers' own product ids.",
                      "minItems": 1,
                      "maxItems": 200,
                      "uniqueItems": true,
                      "examples": [
                        [
                          "15739354"
                        ]
                      ]
                    },
                    "searchTerms": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      "title": "Search terms",
                      "description": "Search terms, as typed in the app.",
                      "minItems": 1,
                      "maxItems": 200,
                      "uniqueItems": true,
                      "examples": [
                        [
                          "hand wash"
                        ]
                      ]
                    },
                    "advertisers": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      "title": "Advertisers",
                      "description": "Advertiser names, as the ad library shows them.",
                      "minItems": 1,
                      "maxItems": 200,
                      "uniqueItems": true,
                      "examples": [
                        [
                          "The Love Co"
                        ]
                      ]
                    },
                    "domains": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "minLength": 1,
                        "maxLength": 200
                      },
                      "title": "Domains",
                      "description": "Brands' own store domains.",
                      "minItems": 1,
                      "maxItems": 200,
                      "uniqueItems": true,
                      "examples": [
                        [
                          "theloveco.in"
                        ]
                      ]
                    }
                  }
                }
              }
            },
            "title": "Datasets",
            "description": "One entry per dataset; each dataset at most once.",
            "minItems": 1,
            "maxItems": 10
          },
          "period": {
            "type": "object",
            "title": "Reporting period",
            "description": "IST dates, inclusive, at most 366 days.",
            "additionalProperties": false,
            "required": [
              "from",
              "to"
            ],
            "properties": {
              "from": {
                "type": "string",
                "title": "From",
                "description": "First day.",
                "examples": [
                  "2026-08-26"
                ],
                "format": "date"
              },
              "to": {
                "type": "string",
                "title": "To",
                "description": "Last day.",
                "examples": [
                  "2026-10-16"
                ],
                "format": "date"
              },
              "tz": {
                "type": "string",
                "enum": [
                  "Asia/Kolkata"
                ],
                "title": "Time zone",
                "description": "Asia/Kolkata."
              }
            }
          }
        }
      },
      "ReportDataQuoteAnswer": {
        "type": "object",
        "title": "Report data quote",
        "description": "The data request counted and priced at the published rates (C-012, D-1760). Approve the quote (POST /v1/quotes/{id}/approve), then build the package with it.",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Quote",
            "description": "The estimate and its quote.",
            "additionalProperties": false,
            "required": [
              "request",
              "estimates",
              "credits",
              "quote"
            ],
            "properties": {
              "request": {
                "$ref": "#/components/schemas/ReportDataRequest"
              },
              "estimates": {
                "type": "array",
                "items": {
                  "type": "object",
                  "title": "Dataset estimate",
                  "description": "One dataset, counted before reading (free).",
                  "additionalProperties": false,
                  "required": [
                    "dataset",
                    "records",
                    "unit",
                    "units",
                    "credits",
                    "rateVersion",
                    "coverage",
                    "freshness",
                    "refusals"
                  ],
                  "properties": {
                    "dataset": {
                      "type": "string",
                      "enum": [
                        "listings",
                        "observations",
                        "rating_changes",
                        "banner_placements",
                        "brand_mentions",
                        "promo_emails",
                        "storefront_promos",
                        "ad_creatives",
                        "brands",
                        "retailers"
                      ],
                      "title": "Dataset",
                      "description": "Which dataset.",
                      "examples": [
                        "listings"
                      ]
                    },
                    "records": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Records",
                      "description": "Records the request matches now.",
                      "examples": [
                        8701
                      ]
                    },
                    "unit": {
                      "type": "string",
                      "title": "Unit",
                      "description": "The rate-card unit it is charged in.",
                      "examples": [
                        "history_points"
                      ]
                    },
                    "units": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Units",
                      "description": "Billable units.",
                      "examples": [
                        8701
                      ]
                    },
                    "credits": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Credits",
                      "description": "At the published rate (0 for the free lists).",
                      "examples": [
                        871
                      ]
                    },
                    "rateVersion": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Rate version",
                      "description": "The rate card version; null for a free list.",
                      "examples": [
                        "4"
                      ]
                    },
                    "coverage": {
                      "type": "object",
                      "title": "Coverage",
                      "description": "What the dataset covers in the period, from Core's own collection only.",
                      "additionalProperties": false,
                      "required": [
                        "retailers",
                        "pincodes",
                        "days",
                        "note"
                      ],
                      "properties": {
                        "retailers": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "title": "Retailers",
                          "description": "Retailers with at least one record."
                        },
                        "pincodes": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Pin codes",
                          "description": "Distinct pin codes with records (0 where not pin-scoped).",
                          "examples": [
                            28
                          ]
                        },
                        "days": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Days",
                          "description": "Distinct IST days with records.",
                          "examples": [
                            52
                          ]
                        },
                        "note": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Note",
                          "description": "Plain-English coverage note; null when there is none.",
                          "examples": [
                            "Flipkart is read at 6 pins only."
                          ]
                        }
                      }
                    },
                    "freshness": {
                      "type": "object",
                      "title": "Freshness",
                      "description": "How recent the dataset is.",
                      "additionalProperties": false,
                      "required": [
                        "oldestRecordAt",
                        "newestRecordAt",
                        "asOf"
                      ],
                      "properties": {
                        "oldestRecordAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Oldest record",
                          "description": "The oldest record in the period; null when none.",
                          "examples": [
                            "2026-08-26T03:10:00Z"
                          ],
                          "format": "date-time"
                        },
                        "newestRecordAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Newest record",
                          "description": "The newest record in the period; null when none.",
                          "examples": [
                            "2026-10-16T17:55:00Z"
                          ],
                          "format": "date-time"
                        },
                        "asOf": {
                          "type": "string",
                          "title": "As of",
                          "description": "When Core last loaded data for this dataset.",
                          "examples": [
                            "2026-10-18T06:00:00Z"
                          ],
                          "format": "date-time"
                        }
                      }
                    },
                    "refusals": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "title": "Refusal",
                        "description": "A part of the request that cannot be answered, with its reason.",
                        "examples": [
                          "filter pincodes: not supported by brand_mentions"
                        ]
                      },
                      "title": "Refusals",
                      "description": "Nothing here means everything asked for can be read."
                    }
                  }
                },
                "title": "Estimates",
                "description": "One per dataset, in request order."
              },
              "credits": {
                "type": "integer",
                "minimum": 0,
                "title": "Credits",
                "description": "The total, at published rates; no report fee (D-1760).",
                "examples": [
                  1
                ]
              },
              "quote": {
                "$ref": "#/components/schemas/Quote"
              }
            }
          }
        }
      },
      "ReportDataPackageRequest": {
        "type": "object",
        "title": "Build a data package",
        "description": "Build the frozen data package of an approved report data quote. Charged on the records delivered, never above the quote.",
        "additionalProperties": false,
        "required": [
          "quoteId",
          "idempotencyKey"
        ],
        "properties": {
          "quoteId": {
            "type": "string",
            "title": "Quote",
            "description": "An approved report data quote of your organisation.",
            "examples": [
              "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
            ],
            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
          },
          "idempotencyKey": {
            "type": "string",
            "title": "Idempotency key",
            "description": "Chosen once by the caller for this action and repeated unchanged on every retry. The same key and body return the first answer; the same key with a different body is refused (idempotency_conflict).",
            "examples": [
              "example-retry-0001"
            ],
            "pattern": "^[A-Za-z0-9._:-]{8,128}$"
          }
        }
      },
      "ReportDataPackageAnswer": {
        "type": "object",
        "title": "Report data package answer",
        "description": "One package.",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Report data package",
            "description": "A frozen snapshot of the data one report needs (schema report-data.v1). Pages never shift: they are read from this snapshot. Free to read for 7 days.",
            "additionalProperties": false,
            "required": [
              "id",
              "schemaVersion",
              "state",
              "failure",
              "request",
              "quoteId",
              "receiptId",
              "credits",
              "datasets",
              "createdAt",
              "readyAt",
              "expiresAt"
            ],
            "properties": {
              "id": {
                "type": "string",
                "title": "Id",
                "description": "The package id.",
                "examples": [
                  "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                ],
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              "schemaVersion": {
                "type": "string",
                "const": "report-data.v1",
                "title": "Schema",
                "description": "report-data.v1."
              },
              "state": {
                "type": "string",
                "enum": [
                  "building",
                  "ready",
                  "failed",
                  "expired"
                ],
                "title": "State",
                "description": "building, ready, failed (nothing charged) or expired.",
                "examples": [
                  "building"
                ]
              },
              "failure": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Failure",
                "description": "Why the build failed; null otherwise.",
                "examples": [
                  "statement timeout reading observations"
                ]
              },
              "request": {
                "$ref": "#/components/schemas/ReportDataRequest"
              },
              "quoteId": {
                "type": "string",
                "title": "Quote",
                "description": "The quote it was built on.",
                "examples": [
                  "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                ],
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              "receiptId": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Receipt",
                "description": "What was charged; null until ready, and null when nothing was charged (nothing delivered, or free lists only).",
                "examples": [
                  "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                ],
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              "credits": {
                "type": "integer",
                "minimum": 0,
                "title": "Credits",
                "description": "Charged, at most the quote.",
                "examples": [
                  1
                ]
              },
              "datasets": {
                "type": "array",
                "items": {
                  "type": "object",
                  "title": "Dataset",
                  "description": "One dataset of the package.",
                  "additionalProperties": false,
                  "required": [
                    "dataset",
                    "records",
                    "pages",
                    "fields",
                    "coverage",
                    "freshness",
                    "sourceContext",
                    "limitations",
                    "sha256"
                  ],
                  "properties": {
                    "dataset": {
                      "type": "string",
                      "enum": [
                        "listings",
                        "observations",
                        "rating_changes",
                        "banner_placements",
                        "brand_mentions",
                        "promo_emails",
                        "storefront_promos",
                        "ad_creatives",
                        "brands",
                        "retailers"
                      ],
                      "title": "Dataset",
                      "description": "Which dataset.",
                      "examples": [
                        "listings"
                      ]
                    },
                    "records": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Records",
                      "description": "Records in the package for this dataset.",
                      "examples": [
                        8701
                      ]
                    },
                    "pages": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Pages",
                      "description": "Pages at the default page size.",
                      "examples": [
                        9
                      ]
                    },
                    "fields": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "title": "Field",
                        "description": "One field of the records.",
                        "additionalProperties": false,
                        "required": [
                          "name",
                          "type",
                          "unit",
                          "description"
                        ],
                        "properties": {
                          "name": {
                            "type": "string",
                            "title": "Name",
                            "description": "The field.",
                            "examples": [
                              "priceMinor"
                            ]
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "string",
                              "integer",
                              "number",
                              "boolean",
                              "date",
                              "date-time",
                              "object",
                              "array"
                            ],
                            "title": "Type",
                            "description": "Its JSON type.",
                            "examples": [
                              "string"
                            ]
                          },
                          "unit": {
                            "type": [
                              "null",
                              "string"
                            ],
                            "title": "Unit",
                            "description": "Its unit, e.g. INR paise; null when it has none.",
                            "examples": [
                              "INR paise"
                            ]
                          },
                          "description": {
                            "type": "string",
                            "title": "Description",
                            "description": "What it is.",
                            "examples": [
                              "The selling price, in paise, as the app showed it."
                            ]
                          }
                        }
                      },
                      "title": "Fields",
                      "description": "The fields every record carries."
                    },
                    "coverage": {
                      "type": "object",
                      "title": "Coverage",
                      "description": "What the dataset covers in the period, from Core's own collection only.",
                      "additionalProperties": false,
                      "required": [
                        "retailers",
                        "pincodes",
                        "days",
                        "note"
                      ],
                      "properties": {
                        "retailers": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "title": "Retailers",
                          "description": "Retailers with at least one record."
                        },
                        "pincodes": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Pin codes",
                          "description": "Distinct pin codes with records (0 where not pin-scoped).",
                          "examples": [
                            28
                          ]
                        },
                        "days": {
                          "type": "integer",
                          "minimum": 0,
                          "title": "Days",
                          "description": "Distinct IST days with records.",
                          "examples": [
                            52
                          ]
                        },
                        "note": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Note",
                          "description": "Plain-English coverage note; null when there is none.",
                          "examples": [
                            "Flipkart is read at 6 pins only."
                          ]
                        }
                      }
                    },
                    "freshness": {
                      "type": "object",
                      "title": "Freshness",
                      "description": "How recent the dataset is.",
                      "additionalProperties": false,
                      "required": [
                        "oldestRecordAt",
                        "newestRecordAt",
                        "asOf"
                      ],
                      "properties": {
                        "oldestRecordAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Oldest record",
                          "description": "The oldest record in the period; null when none.",
                          "examples": [
                            "2026-08-26T03:10:00Z"
                          ],
                          "format": "date-time"
                        },
                        "newestRecordAt": {
                          "type": [
                            "null",
                            "string"
                          ],
                          "title": "Newest record",
                          "description": "The newest record in the period; null when none.",
                          "examples": [
                            "2026-10-16T17:55:00Z"
                          ],
                          "format": "date-time"
                        },
                        "asOf": {
                          "type": "string",
                          "title": "As of",
                          "description": "When Core last loaded data for this dataset.",
                          "examples": [
                            "2026-10-18T06:00:00Z"
                          ],
                          "format": "date-time"
                        }
                      }
                    },
                    "sourceContext": {
                      "type": "object",
                      "title": "Source context",
                      "description": "Where the records come from.",
                      "additionalProperties": false,
                      "required": [
                        "sources",
                        "evidence"
                      ],
                      "properties": {
                        "sources": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "title": "Source",
                            "description": "A recipe or collection lane.",
                            "examples": [
                              "blinkit/search"
                            ]
                          },
                          "title": "Sources",
                          "description": "Collection sources."
                        },
                        "evidence": {
                          "type": "string",
                          "title": "Evidence",
                          "description": "How each record can be traced (D-1313).",
                          "examples": [
                            "Every record carries its source URL, fetch time and the SHA-256 of the response."
                          ]
                        }
                      }
                    },
                    "limitations": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "title": "Limitation",
                        "description": "A stated limit of this data.",
                        "examples": [
                          "Availability is never computed for Flipkart."
                        ]
                      },
                      "title": "Limitations",
                      "description": "What this data cannot tell; the report must not claim it."
                    },
                    "sha256": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "SHA-256",
                      "description": "Of the records in package order, each as canonical JSON (object keys sorted, no spaces), one per line (newline-joined); null until ready.",
                      "examples": [
                        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                      ],
                      "pattern": "^[0-9a-f]{64}$"
                    }
                  }
                },
                "title": "Datasets",
                "description": "In request order."
              },
              "createdAt": {
                "type": "string",
                "title": "Created at",
                "description": "When the build started.",
                "examples": [
                  "2026-10-18T10:00:00Z"
                ],
                "format": "date-time"
              },
              "readyAt": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Ready at",
                "description": "When it became readable; null until ready.",
                "examples": [
                  "2026-10-18T10:00:40Z"
                ],
                "format": "date-time"
              },
              "expiresAt": {
                "type": "string",
                "title": "Expires at",
                "description": "Readable until (7 days after ready).",
                "examples": [
                  "2026-10-25T10:00:40Z"
                ],
                "format": "date-time"
              }
            }
          }
        }
      },
      "ReportDataRecordsPage": {
        "type": "object",
        "title": "Package records page",
        "description": "Records in a stable order, with completeness on every page so a report cannot silently omit records.",
        "additionalProperties": false,
        "required": [
          "data",
          "page",
          "completeness"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "title": "Record",
              "description": "One record: the fields listed in the manifest, values as collected. A value not collected is null and named in missing; nothing is guessed or derived.",
              "required": [
                "id",
                "missing"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "title": "Id",
                  "description": "The record's own id, always as text (an observation's number id is given as its digits). A dataset whose records carry no id of their own (the day tables, brand profiles) gets a stable content id: r_ and the first 24 hex characters of the SHA-256 of the record."
                },
                "missing": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  },
                  "title": "Missing",
                  "description": "Fields that were not collected for this record (their value is null)."
                }
              },
              "additionalProperties": true
            },
            "title": "Records",
            "description": "In the package order."
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Where this page sits.",
            "additionalProperties": false,
            "required": [
              "dataset",
              "limit",
              "first",
              "last",
              "nextCursor"
            ],
            "properties": {
              "dataset": {
                "type": "string",
                "enum": [
                  "listings",
                  "observations",
                  "rating_changes",
                  "banner_placements",
                  "brand_mentions",
                  "promo_emails",
                  "storefront_promos",
                  "ad_creatives",
                  "brands",
                  "retailers"
                ],
                "title": "Dataset",
                "description": "Which dataset.",
                "examples": [
                  "listings"
                ]
              },
              "limit": {
                "type": "integer",
                "minimum": 0,
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  1000
                ]
              },
              "first": {
                "type": "integer",
                "minimum": 0,
                "title": "First",
                "description": "Position of the first record on this page (1-based).",
                "examples": [
                  1
                ]
              },
              "last": {
                "type": "integer",
                "minimum": 0,
                "title": "Last",
                "description": "Position of the last record on this page (0 when empty).",
                "examples": [
                  1000
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Pass as cursor for the next page; null at the end.",
                "examples": [
                  "eyJwIjoyfQ"
                ],
                "pattern": "^[A-Za-z0-9_-]{1,400}$"
              }
            }
          },
          "completeness": {
            "type": "object",
            "title": "Completeness",
            "description": "A report is complete only when every dataset was read to complete: true and the counts match the manifest.",
            "additionalProperties": false,
            "required": [
              "records",
              "delivered",
              "remaining",
              "complete",
              "packageSha256"
            ],
            "properties": {
              "records": {
                "type": "integer",
                "minimum": 0,
                "title": "Records",
                "description": "The dataset's records in the package.",
                "examples": [
                  8701
                ]
              },
              "delivered": {
                "type": "integer",
                "minimum": 0,
                "title": "Delivered",
                "description": "Records up to and including this page.",
                "examples": [
                  1000
                ]
              },
              "remaining": {
                "type": "integer",
                "minimum": 0,
                "title": "Remaining",
                "description": "Records after this page.",
                "examples": [
                  7701
                ]
              },
              "complete": {
                "type": "boolean",
                "title": "Complete",
                "description": "True on the last page only."
              },
              "packageSha256": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Package SHA-256",
                "description": "The dataset's SHA-256 from the manifest.",
                "examples": [
                  "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                ],
                "pattern": "^[0-9a-f]{64}$"
              }
            }
          }
        }
      },
      "ReportUploadRequest": {
        "type": "object",
        "title": "Save a report",
        "description": "Start saving a frontend-made report to the account. The owner is the session's server-verified active organisation; the body names none.",
        "additionalProperties": false,
        "required": [
          "idempotencyKey",
          "title",
          "kind",
          "subject",
          "window",
          "files"
        ],
        "properties": {
          "idempotencyKey": {
            "type": "string",
            "title": "Idempotency key",
            "description": "Chosen once by the caller for this action and repeated unchanged on every retry. The same key and body return the first answer; the same key with a different body is refused (idempotency_conflict).",
            "examples": [
              "example-retry-0001"
            ],
            "pattern": "^[A-Za-z0-9._:-]{8,128}$"
          },
          "title": {
            "type": "string",
            "title": "Title",
            "description": "The report title.",
            "examples": [
              "The Love Co. — Shelf Watch report"
            ],
            "minLength": 1,
            "maxLength": 300
          },
          "kind": {
            "type": "string",
            "title": "Kind",
            "description": "The report type, chosen by the frontend.",
            "examples": [
              "brand_shelf"
            ],
            "pattern": "^[a-z][a-z0-9_]{1,40}$"
          },
          "subject": {
            "type": "object",
            "title": "Subject",
            "description": "What the report is about.",
            "additionalProperties": false,
            "required": [
              "kind",
              "name",
              "slug"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "brand",
                  "category",
                  "retailer",
                  "dataset"
                ],
                "title": "Kind",
                "description": "brand, category, retailer or dataset.",
                "examples": [
                  "brand"
                ]
              },
              "name": {
                "type": "string",
                "title": "Name",
                "description": "As the report names it.",
                "examples": [
                  "The Love Co."
                ],
                "minLength": 1,
                "maxLength": 200
              },
              "slug": {
                "type": "string",
                "title": "Slug",
                "description": "Lowercase words joined by hyphens.",
                "examples": [
                  "the-love-co"
                ],
                "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
                "maxLength": 80
              }
            }
          },
          "window": {
            "type": "object",
            "title": "Window",
            "description": "The data window, IST dates, inclusive.",
            "additionalProperties": false,
            "required": [
              "from",
              "to"
            ],
            "properties": {
              "from": {
                "type": "string",
                "title": "From",
                "description": "First day.",
                "examples": [
                  "2026-08-26"
                ],
                "format": "date"
              },
              "to": {
                "type": "string",
                "title": "To",
                "description": "Last day.",
                "examples": [
                  "2026-10-16"
                ],
                "format": "date"
              }
            }
          },
          "dataPackageIds": {
            "type": "array",
            "items": {
              "type": "string",
              "title": "Package",
              "description": "A data package the report was built from.",
              "examples": [
                "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
              ],
              "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
            },
            "title": "Data packages",
            "description": "Optional; recorded with the edition.",
            "maxItems": 10,
            "uniqueItems": true
          },
          "files": {
            "type": "array",
            "items": {
              "type": "object",
              "title": "File",
              "description": "One file of the report, declared before upload.",
              "additionalProperties": false,
              "required": [
                "name",
                "format",
                "role",
                "contentType",
                "bytes",
                "sha256"
              ],
              "properties": {
                "name": {
                  "type": "string",
                  "title": "Name",
                  "description": "Relative to the report (e.g. report.html, data/prices.csv).",
                  "examples": [
                    "report.html"
                  ],
                  "pattern": "^[A-Za-z0-9_][A-Za-z0-9._-]*(/[A-Za-z0-9_][A-Za-z0-9._-]*)*$",
                  "maxLength": 200
                },
                "format": {
                  "type": "string",
                  "enum": [
                    "html",
                    "json",
                    "pdf",
                    "csv",
                    "jsonl",
                    "markdown",
                    "text"
                  ],
                  "title": "Format",
                  "description": "html, json (the report JSON), pdf, csv, jsonl, markdown or text.",
                  "examples": [
                    "html"
                  ]
                },
                "role": {
                  "type": "string",
                  "enum": [
                    "report",
                    "data"
                  ],
                  "title": "Role",
                  "description": "report: a readable report (html, pdf, report JSON); data: a supporting file.",
                  "examples": [
                    "report"
                  ]
                },
                "contentType": {
                  "type": "string",
                  "title": "Content type",
                  "description": "Served with this type.",
                  "examples": [
                    "text/html; charset=utf-8"
                  ]
                },
                "bytes": {
                  "type": "integer",
                  "minimum": 0,
                  "title": "Bytes",
                  "description": "Exact size. Any per-file limit is applied per caller (none for staff and the owner, D-1775).",
                  "examples": [
                    48362
                  ]
                },
                "sha256": {
                  "type": "string",
                  "title": "SHA-256",
                  "description": "Of the exact bytes; the store refuses a body that differs.",
                  "examples": [
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                  ],
                  "pattern": "^[0-9a-f]{64}$"
                }
              }
            },
            "title": "Files",
            "description": "Every file; at least one with role report. Any file-count limit is applied per caller (none for staff and the owner, D-1775).",
            "minItems": 1
          }
        }
      },
      "ReportUploadAnswer": {
        "type": "object",
        "title": "Report upload answer",
        "description": "One upload.",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Report upload",
            "description": "Saving one report: the signed PUT for each file while awaiting files, then processing, then saved (with the edition) or failed.",
            "additionalProperties": false,
            "required": [
              "id",
              "state",
              "failure",
              "failureDetail",
              "editionId",
              "files",
              "storage",
              "sessionExpiresAt",
              "createdAt",
              "finishedAt"
            ],
            "properties": {
              "id": {
                "type": "string",
                "title": "Id",
                "description": "The upload id.",
                "examples": [
                  "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                ],
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              "state": {
                "type": "string",
                "enum": [
                  "awaiting_files",
                  "processing",
                  "saved",
                  "failed",
                  "expired"
                ],
                "title": "State",
                "description": "awaiting_files, processing, saved, failed or expired.",
                "examples": [
                  "awaiting_files"
                ]
              },
              "failure": {
                "type": [
                  "null",
                  "string"
                ],
                "enum": [
                  "file_missing",
                  "sha256_mismatch",
                  "size_mismatch",
                  "limit_exceeded",
                  "storage_not_confirmed",
                  "expired",
                  null
                ],
                "title": "Failure",
                "description": "Why it failed; null otherwise.",
                "examples": [
                  "file_missing"
                ]
              },
              "failureDetail": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Failure detail",
                "description": "Which file and what was found.",
                "examples": [
                  "data/prices.csv: 1203 bytes, declared 1204"
                ]
              },
              "editionId": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Edition",
                "description": "The saved report (GET /v1/reports/{id}); null until saved.",
                "examples": [
                  "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                ],
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              "files": {
                "type": "array",
                "items": {
                  "type": "object",
                  "title": "File",
                  "description": "One declared file and where to PUT it.",
                  "additionalProperties": false,
                  "required": [
                    "name",
                    "format",
                    "role",
                    "bytes",
                    "sha256",
                    "received",
                    "upload"
                  ],
                  "properties": {
                    "name": {
                      "type": "string",
                      "title": "Name",
                      "description": "As declared.",
                      "examples": [
                        "report.html"
                      ],
                      "pattern": "^[A-Za-z0-9_][A-Za-z0-9._-]*(/[A-Za-z0-9_][A-Za-z0-9._-]*)*$"
                    },
                    "format": {
                      "type": "string",
                      "enum": [
                        "html",
                        "json",
                        "pdf",
                        "csv",
                        "jsonl",
                        "markdown",
                        "text"
                      ],
                      "title": "Format",
                      "description": "As declared.",
                      "examples": [
                        "html"
                      ]
                    },
                    "role": {
                      "type": "string",
                      "enum": [
                        "report",
                        "data"
                      ],
                      "title": "Role",
                      "description": "As declared.",
                      "examples": [
                        "report"
                      ]
                    },
                    "bytes": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Bytes",
                      "description": "As declared.",
                      "examples": [
                        48362
                      ]
                    },
                    "sha256": {
                      "type": "string",
                      "title": "SHA-256",
                      "description": "As declared.",
                      "examples": [
                        "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                      ],
                      "pattern": "^[0-9a-f]{64}$"
                    },
                    "received": {
                      "type": "boolean",
                      "title": "Received",
                      "description": "The object is in the store with the declared size (the signed PUT refuses other bytes, and finalising checks each SHA-256 again). Always true once saved."
                    },
                    "upload": {
                      "type": [
                        "null",
                        "object"
                      ],
                      "title": "Upload",
                      "description": "The signed PUT; null once received or when the session is over.",
                      "additionalProperties": false,
                      "required": [
                        "method",
                        "url",
                        "headers",
                        "expiresAt"
                      ],
                      "properties": {
                        "method": {
                          "type": "string",
                          "const": "PUT",
                          "title": "Method",
                          "description": "PUT."
                        },
                        "url": {
                          "type": "string",
                          "title": "URL",
                          "description": "Signed, 15 minutes; never share it.",
                          "examples": [
                            "https://store.example/customer-reports/..."
                          ]
                        },
                        "headers": {
                          "type": "object",
                          "title": "Headers",
                          "description": "Send exactly these headers (content type and SHA-256 checksum).",
                          "additionalProperties": {
                            "type": "string"
                          },
                          "examples": [
                            {
                              "content-type": "text/html; charset=utf-8",
                              "x-amz-checksum-sha256": "base64..."
                            }
                          ]
                        },
                        "expiresAt": {
                          "type": "string",
                          "title": "Expires at",
                          "description": "When this PUT stops working.",
                          "examples": [
                            "2026-10-18T10:15:00Z"
                          ],
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "title": "Files",
                "description": "In the declared order."
              },
              "storage": {
                "type": "object",
                "title": "Storage",
                "description": "The storage terms of this report, confirmed separately from data-read charges.",
                "additionalProperties": false,
                "required": [
                  "bytes",
                  "retentionMonths",
                  "limits",
                  "credits",
                  "confirmation",
                  "storageQuoteId"
                ],
                "properties": {
                  "bytes": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Bytes",
                    "description": "All files together.",
                    "examples": [
                      4500000
                    ]
                  },
                  "retentionMonths": {
                    "type": "integer",
                    "const": 12,
                    "title": "Retention",
                    "description": "Kept 12 months, then deleted (D-1764)."
                  },
                  "limits": {
                    "type": [
                      "null",
                      "object"
                    ],
                    "title": "Limits",
                    "description": "The limits that apply to this caller; null when none apply (staff and the owner, D-1775). The customer default is 100 files, 50 MB per file, 200 MB per report.",
                    "additionalProperties": false,
                    "required": [
                      "maxFiles",
                      "maxFileBytes",
                      "maxReportBytes"
                    ],
                    "properties": {
                      "maxFiles": {
                        "type": "integer",
                        "minimum": 0,
                        "title": "Files",
                        "description": "At most this many files.",
                        "examples": [
                          100
                        ]
                      },
                      "maxFileBytes": {
                        "type": "integer",
                        "minimum": 0,
                        "title": "File bytes",
                        "description": "At most this per file.",
                        "examples": [
                          52428800
                        ]
                      },
                      "maxReportBytes": {
                        "type": "integer",
                        "minimum": 0,
                        "title": "Report bytes",
                        "description": "At most this per report.",
                        "examples": [
                          209715200
                        ]
                      }
                    }
                  },
                  "credits": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Credits",
                    "description": "Storage charge for this report (0: storage is free while staff only, D-1775).",
                    "examples": [
                      0
                    ]
                  },
                  "confirmation": {
                    "type": "string",
                    "enum": [
                      "not_required",
                      "quote_required"
                    ],
                    "title": "Confirmation",
                    "description": "not_required: nothing to confirm. quote_required: approve storageQuoteId before finalising.",
                    "examples": [
                      "not_required"
                    ]
                  },
                  "storageQuoteId": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "title": "Storage quote",
                    "description": "The storage quote to approve; null when none is needed.",
                    "examples": [
                      "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                    ],
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  }
                }
              },
              "sessionExpiresAt": {
                "type": "string",
                "title": "Session expires at",
                "description": "Finalise before this.",
                "examples": [
                  "2026-10-18T11:00:00Z"
                ],
                "format": "date-time"
              },
              "createdAt": {
                "type": "string",
                "title": "Created at",
                "description": "When the upload started.",
                "examples": [
                  "2026-10-18T10:00:00Z"
                ],
                "format": "date-time"
              },
              "finishedAt": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Finished at",
                "description": "When it was saved or failed.",
                "examples": [
                  "2026-10-18T10:02:00Z"
                ],
                "format": "date-time"
              }
            }
          }
        }
      },
      "ReportUploadFinaliseRequest": {
        "type": "object",
        "title": "Finalise a report",
        "description": "Check every file and save the report to the account. Safe to repeat: finalising twice returns the same edition.",
        "additionalProperties": false,
        "required": [
          "idempotencyKey"
        ],
        "properties": {
          "idempotencyKey": {
            "type": "string",
            "title": "Idempotency key",
            "description": "Chosen once by the caller for this action and repeated unchanged on every retry. The same key and body return the first answer; the same key with a different body is refused (idempotency_conflict).",
            "examples": [
              "example-retry-0001"
            ],
            "pattern": "^[A-Za-z0-9._:-]{8,128}$"
          }
        }
      },
      "ReportScheduleCreate": {
        "type": "object",
        "title": "Create a schedule",
        "description": "A draft schedule; it runs nothing until its cost is confirmed with activate.",
        "additionalProperties": false,
        "required": [
          "idempotencyKey",
          "name",
          "data",
          "window",
          "frequency",
          "timezone",
          "renderer",
          "title",
          "subject",
          "delivery",
          "spendingLimit"
        ],
        "properties": {
          "idempotencyKey": {
            "type": "string",
            "title": "Idempotency key",
            "description": "Chosen once by the caller for this action and repeated unchanged on every retry. The same key and body return the first answer; the same key with a different body is refused (idempotency_conflict).",
            "examples": [
              "example-retry-0001"
            ],
            "pattern": "^[A-Za-z0-9._:-]{8,128}$"
          },
          "name": {
            "type": "string",
            "title": "Name",
            "description": "A name for the schedule.",
            "examples": [
              "The Love Co. weekly shelf"
            ],
            "minLength": 1,
            "maxLength": 200
          },
          "data": {
            "type": "object",
            "title": "Data",
            "description": "What each delivery reads: the report data request without its period (the window rule gives it).",
            "additionalProperties": false,
            "required": [
              "datasets"
            ],
            "properties": {
              "datasets": {
                "type": "array",
                "items": {
                  "type": "object",
                  "title": "Dataset request",
                  "description": "One dataset, narrowed.",
                  "additionalProperties": false,
                  "required": [
                    "dataset"
                  ],
                  "properties": {
                    "dataset": {
                      "type": "string",
                      "enum": [
                        "listings",
                        "observations",
                        "rating_changes",
                        "banner_placements",
                        "brand_mentions",
                        "promo_emails",
                        "storefront_promos",
                        "ad_creatives",
                        "brands",
                        "retailers"
                      ],
                      "title": "Dataset",
                      "description": "Which dataset.",
                      "examples": [
                        "listings"
                      ]
                    },
                    "fields": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "pattern": "^[a-zA-Z][a-zA-Z0-9_]{0,60}$"
                      },
                      "title": "Fields",
                      "description": "Only these fields of each record (the record id and its source fields are always included). Default: all.",
                      "maxItems": 100,
                      "uniqueItems": true,
                      "examples": [
                        [
                          "retailer",
                          "priceMinor",
                          "mrpMinor",
                          "observedAt"
                        ]
                      ]
                    },
                    "filters": {
                      "type": "object",
                      "title": "Report data filters",
                      "description": "Narrow a dataset. Values are exact (brands as retailers write them). Each dataset supports only some filters.",
                      "additionalProperties": false,
                      "required": [],
                      "properties": {
                        "retailers": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200,
                            "pattern": "^[a-z0-9_]{1,40}$"
                          },
                          "title": "Retailers",
                          "description": "Retailer ids.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "blinkit",
                              "zepto"
                            ]
                          ]
                        },
                        "brands": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "title": "Brands",
                          "description": "Brands, exactly as written.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "The Love Co."
                            ]
                          ]
                        },
                        "pincodes": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200,
                            "pattern": "^[1-9][0-9]{5}$"
                          },
                          "title": "Pin codes",
                          "description": "Six-digit pin codes.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "560001"
                            ]
                          ]
                        },
                        "productIds": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200,
                            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                          },
                          "title": "Products",
                          "description": "Core product ids.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "8d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a"
                            ]
                          ]
                        },
                        "retailerSkus": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "title": "Retailer SKUs",
                          "description": "Retailers' own product ids.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "15739354"
                            ]
                          ]
                        },
                        "searchTerms": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "title": "Search terms",
                          "description": "Search terms, as typed in the app.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "hand wash"
                            ]
                          ]
                        },
                        "advertisers": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "title": "Advertisers",
                          "description": "Advertiser names, as the ad library shows them.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "The Love Co"
                            ]
                          ]
                        },
                        "domains": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "title": "Domains",
                          "description": "Brands' own store domains.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "theloveco.in"
                            ]
                          ]
                        }
                      }
                    }
                  }
                },
                "title": "Datasets",
                "description": "One entry per dataset; each dataset at most once.",
                "minItems": 1,
                "maxItems": 10
              }
            }
          },
          "window": {
            "title": "Reporting window",
            "description": "Which days each delivery covers, in the schedule time zone: the last N complete days before the run, or the previous calendar week or month.",
            "oneOf": [
              {
                "type": "object",
                "title": "Rolling days",
                "description": "The last N complete days.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "days"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "const": "rolling_days",
                    "title": "Kind",
                    "description": "rolling_days."
                  },
                  "days": {
                    "type": "integer",
                    "minimum": 1,
                    "title": "Days",
                    "description": "1 to 366.",
                    "examples": [
                      7
                    ],
                    "maximum": 366
                  }
                }
              },
              {
                "type": "object",
                "title": "Previous calendar period",
                "description": "The previous complete week (Monday to Sunday) or month.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "period"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "const": "previous_period",
                    "title": "Kind",
                    "description": "previous_period."
                  },
                  "period": {
                    "type": "string",
                    "enum": [
                      "week",
                      "month"
                    ],
                    "title": "Period",
                    "description": "week or month.",
                    "examples": [
                      "week"
                    ]
                  }
                }
              }
            ],
            "examples": [
              {
                "kind": "rolling_days",
                "days": 7
              }
            ]
          },
          "frequency": {
            "title": "Frequency",
            "description": "When deliveries run, in the schedule time zone.",
            "oneOf": [
              {
                "type": "object",
                "title": "Daily",
                "description": "Every day.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "time"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "const": "daily",
                    "title": "Kind",
                    "description": "daily."
                  },
                  "time": {
                    "type": "string",
                    "title": "Time",
                    "description": "Local time, HH:MM, 24-hour.",
                    "examples": [
                      "07:00"
                    ],
                    "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                  }
                }
              },
              {
                "type": "object",
                "title": "Weekly",
                "description": "Once a week.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "weekday",
                  "time"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "const": "weekly",
                    "title": "Kind",
                    "description": "weekly."
                  },
                  "weekday": {
                    "type": "string",
                    "enum": [
                      "monday",
                      "tuesday",
                      "wednesday",
                      "thursday",
                      "friday",
                      "saturday",
                      "sunday"
                    ],
                    "title": "Weekday",
                    "description": "The day.",
                    "examples": [
                      "monday"
                    ]
                  },
                  "time": {
                    "type": "string",
                    "title": "Time",
                    "description": "Local time, HH:MM, 24-hour.",
                    "examples": [
                      "07:00"
                    ],
                    "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                  }
                }
              },
              {
                "type": "object",
                "title": "Monthly",
                "description": "Once a month.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "dayOfMonth",
                  "time"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "const": "monthly",
                    "title": "Kind",
                    "description": "monthly."
                  },
                  "dayOfMonth": {
                    "type": "integer",
                    "minimum": 1,
                    "title": "Day",
                    "description": "1 to 28, so every month has it.",
                    "examples": [
                      1
                    ],
                    "maximum": 28
                  },
                  "time": {
                    "type": "string",
                    "title": "Time",
                    "description": "Local time, HH:MM, 24-hour.",
                    "examples": [
                      "07:00"
                    ],
                    "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                  }
                }
              }
            ],
            "examples": [
              {
                "kind": "weekly",
                "weekday": "monday",
                "time": "07:00"
              }
            ]
          },
          "timezone": {
            "type": "string",
            "enum": [
              "Asia/Kolkata"
            ],
            "title": "Time zone",
            "description": "Asia/Kolkata for now."
          },
          "renderer": {
            "type": "object",
            "title": "Renderer",
            "description": "The frontend's renderer the worker runs (D-1777): an allow-listed package, an exact version and a template.",
            "additionalProperties": false,
            "required": [
              "package",
              "version",
              "template"
            ],
            "properties": {
              "package": {
                "type": "string",
                "title": "Package",
                "description": "The npm package the frontend published.",
                "examples": [
                  "@rewalto/report-renderer"
                ],
                "pattern": "^(@[a-z0-9-]+/)?[a-z0-9][a-z0-9._-]*$"
              },
              "version": {
                "type": "string",
                "title": "Version",
                "description": "An exact version on Core's allow-list (no ranges).",
                "examples": [
                  "1.0.0"
                ],
                "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[0-9A-Za-z.-]+)?$"
              },
              "template": {
                "type": "string",
                "title": "Template",
                "description": "A template the package declares.",
                "examples": [
                  "brand-shelf"
                ],
                "pattern": "^[a-z0-9][a-z0-9-]{0,60}$"
              }
            }
          },
          "title": {
            "type": "string",
            "title": "Report title",
            "description": "Each edition's title; {from} and {to} are replaced by the window dates.",
            "examples": [
              "The Love Co. — week {from} to {to}"
            ],
            "minLength": 1,
            "maxLength": 300
          },
          "subject": {
            "type": "object",
            "title": "Subject",
            "description": "What the report is about.",
            "additionalProperties": false,
            "required": [
              "kind",
              "name",
              "slug"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "brand",
                  "category",
                  "retailer",
                  "dataset"
                ],
                "title": "Kind",
                "description": "brand, category, retailer or dataset.",
                "examples": [
                  "brand"
                ]
              },
              "name": {
                "type": "string",
                "title": "Name",
                "description": "As the report names it.",
                "examples": [
                  "The Love Co."
                ],
                "minLength": 1,
                "maxLength": 200
              },
              "slug": {
                "type": "string",
                "title": "Slug",
                "description": "Lowercase words joined by hyphens.",
                "examples": [
                  "the-love-co"
                ],
                "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
                "maxLength": 80
              }
            }
          },
          "delivery": {
            "type": "object",
            "title": "Delivery",
            "description": "Every edition is saved to the organisation's report history; optionally, named members are told when it is ready (a link to the report, never the file).",
            "additionalProperties": false,
            "required": [
              "saveToHistory"
            ],
            "properties": {
              "saveToHistory": {
                "type": "boolean",
                "const": true,
                "title": "Save to history",
                "description": "Always true."
              },
              "notifyUserIds": {
                "type": "array",
                "items": {
                  "type": "string",
                  "title": "Member",
                  "description": "A member of the organisation (Clerk user id).",
                  "examples": [
                    "user_EXAMPLE0000000001"
                  ]
                },
                "title": "Notify",
                "description": "Members told when an edition is saved or a run fails.",
                "maxItems": 20,
                "uniqueItems": true
              }
            }
          },
          "spendingLimit": {
            "type": "object",
            "title": "Spending limit",
            "description": "A run that would exceed either limit is skipped (spending_limit) and the schedule pauses.",
            "additionalProperties": false,
            "required": [
              "perDeliveryCredits",
              "perMonthCredits"
            ],
            "properties": {
              "perDeliveryCredits": {
                "type": "integer",
                "minimum": 1,
                "title": "Per delivery",
                "description": "At most this many credits per delivery.",
                "examples": [
                  1000
                ]
              },
              "perMonthCredits": {
                "type": "integer",
                "minimum": 1,
                "title": "Per month",
                "description": "At most this many credits per calendar month (IST).",
                "examples": [
                  5000
                ]
              }
            }
          }
        }
      },
      "ReportScheduleUpdate": {
        "type": "object",
        "title": "Change a schedule",
        "description": "Any of the fields; a change that moves the cost returns an active schedule to needs_confirmation (it runs nothing until confirmed again).",
        "additionalProperties": false,
        "required": [],
        "properties": {
          "name": {
            "type": "string",
            "title": "Name",
            "description": "A name for the schedule.",
            "examples": [
              "The Love Co. weekly shelf"
            ],
            "minLength": 1,
            "maxLength": 200
          },
          "data": {
            "type": "object",
            "title": "Data",
            "description": "What each delivery reads: the report data request without its period (the window rule gives it).",
            "additionalProperties": false,
            "required": [
              "datasets"
            ],
            "properties": {
              "datasets": {
                "type": "array",
                "items": {
                  "type": "object",
                  "title": "Dataset request",
                  "description": "One dataset, narrowed.",
                  "additionalProperties": false,
                  "required": [
                    "dataset"
                  ],
                  "properties": {
                    "dataset": {
                      "type": "string",
                      "enum": [
                        "listings",
                        "observations",
                        "rating_changes",
                        "banner_placements",
                        "brand_mentions",
                        "promo_emails",
                        "storefront_promos",
                        "ad_creatives",
                        "brands",
                        "retailers"
                      ],
                      "title": "Dataset",
                      "description": "Which dataset.",
                      "examples": [
                        "listings"
                      ]
                    },
                    "fields": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "pattern": "^[a-zA-Z][a-zA-Z0-9_]{0,60}$"
                      },
                      "title": "Fields",
                      "description": "Only these fields of each record (the record id and its source fields are always included). Default: all.",
                      "maxItems": 100,
                      "uniqueItems": true,
                      "examples": [
                        [
                          "retailer",
                          "priceMinor",
                          "mrpMinor",
                          "observedAt"
                        ]
                      ]
                    },
                    "filters": {
                      "type": "object",
                      "title": "Report data filters",
                      "description": "Narrow a dataset. Values are exact (brands as retailers write them). Each dataset supports only some filters.",
                      "additionalProperties": false,
                      "required": [],
                      "properties": {
                        "retailers": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200,
                            "pattern": "^[a-z0-9_]{1,40}$"
                          },
                          "title": "Retailers",
                          "description": "Retailer ids.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "blinkit",
                              "zepto"
                            ]
                          ]
                        },
                        "brands": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "title": "Brands",
                          "description": "Brands, exactly as written.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "The Love Co."
                            ]
                          ]
                        },
                        "pincodes": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200,
                            "pattern": "^[1-9][0-9]{5}$"
                          },
                          "title": "Pin codes",
                          "description": "Six-digit pin codes.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "560001"
                            ]
                          ]
                        },
                        "productIds": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200,
                            "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                          },
                          "title": "Products",
                          "description": "Core product ids.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "8d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a"
                            ]
                          ]
                        },
                        "retailerSkus": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "title": "Retailer SKUs",
                          "description": "Retailers' own product ids.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "15739354"
                            ]
                          ]
                        },
                        "searchTerms": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "title": "Search terms",
                          "description": "Search terms, as typed in the app.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "hand wash"
                            ]
                          ]
                        },
                        "advertisers": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "title": "Advertisers",
                          "description": "Advertiser names, as the ad library shows them.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "The Love Co"
                            ]
                          ]
                        },
                        "domains": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 200
                          },
                          "title": "Domains",
                          "description": "Brands' own store domains.",
                          "minItems": 1,
                          "maxItems": 200,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "theloveco.in"
                            ]
                          ]
                        }
                      }
                    }
                  }
                },
                "title": "Datasets",
                "description": "One entry per dataset; each dataset at most once.",
                "minItems": 1,
                "maxItems": 10
              }
            }
          },
          "window": {
            "title": "Reporting window",
            "description": "Which days each delivery covers, in the schedule time zone: the last N complete days before the run, or the previous calendar week or month.",
            "oneOf": [
              {
                "type": "object",
                "title": "Rolling days",
                "description": "The last N complete days.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "days"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "const": "rolling_days",
                    "title": "Kind",
                    "description": "rolling_days."
                  },
                  "days": {
                    "type": "integer",
                    "minimum": 1,
                    "title": "Days",
                    "description": "1 to 366.",
                    "examples": [
                      7
                    ],
                    "maximum": 366
                  }
                }
              },
              {
                "type": "object",
                "title": "Previous calendar period",
                "description": "The previous complete week (Monday to Sunday) or month.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "period"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "const": "previous_period",
                    "title": "Kind",
                    "description": "previous_period."
                  },
                  "period": {
                    "type": "string",
                    "enum": [
                      "week",
                      "month"
                    ],
                    "title": "Period",
                    "description": "week or month.",
                    "examples": [
                      "week"
                    ]
                  }
                }
              }
            ],
            "examples": [
              {
                "kind": "rolling_days",
                "days": 7
              }
            ]
          },
          "frequency": {
            "title": "Frequency",
            "description": "When deliveries run, in the schedule time zone.",
            "oneOf": [
              {
                "type": "object",
                "title": "Daily",
                "description": "Every day.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "time"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "const": "daily",
                    "title": "Kind",
                    "description": "daily."
                  },
                  "time": {
                    "type": "string",
                    "title": "Time",
                    "description": "Local time, HH:MM, 24-hour.",
                    "examples": [
                      "07:00"
                    ],
                    "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                  }
                }
              },
              {
                "type": "object",
                "title": "Weekly",
                "description": "Once a week.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "weekday",
                  "time"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "const": "weekly",
                    "title": "Kind",
                    "description": "weekly."
                  },
                  "weekday": {
                    "type": "string",
                    "enum": [
                      "monday",
                      "tuesday",
                      "wednesday",
                      "thursday",
                      "friday",
                      "saturday",
                      "sunday"
                    ],
                    "title": "Weekday",
                    "description": "The day.",
                    "examples": [
                      "monday"
                    ]
                  },
                  "time": {
                    "type": "string",
                    "title": "Time",
                    "description": "Local time, HH:MM, 24-hour.",
                    "examples": [
                      "07:00"
                    ],
                    "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                  }
                }
              },
              {
                "type": "object",
                "title": "Monthly",
                "description": "Once a month.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "dayOfMonth",
                  "time"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "const": "monthly",
                    "title": "Kind",
                    "description": "monthly."
                  },
                  "dayOfMonth": {
                    "type": "integer",
                    "minimum": 1,
                    "title": "Day",
                    "description": "1 to 28, so every month has it.",
                    "examples": [
                      1
                    ],
                    "maximum": 28
                  },
                  "time": {
                    "type": "string",
                    "title": "Time",
                    "description": "Local time, HH:MM, 24-hour.",
                    "examples": [
                      "07:00"
                    ],
                    "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                  }
                }
              }
            ],
            "examples": [
              {
                "kind": "weekly",
                "weekday": "monday",
                "time": "07:00"
              }
            ]
          },
          "timezone": {
            "type": "string",
            "enum": [
              "Asia/Kolkata"
            ],
            "title": "Time zone",
            "description": "Asia/Kolkata for now."
          },
          "renderer": {
            "type": "object",
            "title": "Renderer",
            "description": "The frontend's renderer the worker runs (D-1777): an allow-listed package, an exact version and a template.",
            "additionalProperties": false,
            "required": [
              "package",
              "version",
              "template"
            ],
            "properties": {
              "package": {
                "type": "string",
                "title": "Package",
                "description": "The npm package the frontend published.",
                "examples": [
                  "@rewalto/report-renderer"
                ],
                "pattern": "^(@[a-z0-9-]+/)?[a-z0-9][a-z0-9._-]*$"
              },
              "version": {
                "type": "string",
                "title": "Version",
                "description": "An exact version on Core's allow-list (no ranges).",
                "examples": [
                  "1.0.0"
                ],
                "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[0-9A-Za-z.-]+)?$"
              },
              "template": {
                "type": "string",
                "title": "Template",
                "description": "A template the package declares.",
                "examples": [
                  "brand-shelf"
                ],
                "pattern": "^[a-z0-9][a-z0-9-]{0,60}$"
              }
            }
          },
          "title": {
            "type": "string",
            "title": "Report title",
            "description": "Each edition's title; {from} and {to} are replaced by the window dates.",
            "examples": [
              "The Love Co. — week {from} to {to}"
            ],
            "minLength": 1,
            "maxLength": 300
          },
          "subject": {
            "type": "object",
            "title": "Subject",
            "description": "What the report is about.",
            "additionalProperties": false,
            "required": [
              "kind",
              "name",
              "slug"
            ],
            "properties": {
              "kind": {
                "type": "string",
                "enum": [
                  "brand",
                  "category",
                  "retailer",
                  "dataset"
                ],
                "title": "Kind",
                "description": "brand, category, retailer or dataset.",
                "examples": [
                  "brand"
                ]
              },
              "name": {
                "type": "string",
                "title": "Name",
                "description": "As the report names it.",
                "examples": [
                  "The Love Co."
                ],
                "minLength": 1,
                "maxLength": 200
              },
              "slug": {
                "type": "string",
                "title": "Slug",
                "description": "Lowercase words joined by hyphens.",
                "examples": [
                  "the-love-co"
                ],
                "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
                "maxLength": 80
              }
            }
          },
          "delivery": {
            "type": "object",
            "title": "Delivery",
            "description": "Every edition is saved to the organisation's report history; optionally, named members are told when it is ready (a link to the report, never the file).",
            "additionalProperties": false,
            "required": [
              "saveToHistory"
            ],
            "properties": {
              "saveToHistory": {
                "type": "boolean",
                "const": true,
                "title": "Save to history",
                "description": "Always true."
              },
              "notifyUserIds": {
                "type": "array",
                "items": {
                  "type": "string",
                  "title": "Member",
                  "description": "A member of the organisation (Clerk user id).",
                  "examples": [
                    "user_EXAMPLE0000000001"
                  ]
                },
                "title": "Notify",
                "description": "Members told when an edition is saved or a run fails.",
                "maxItems": 20,
                "uniqueItems": true
              }
            }
          },
          "spendingLimit": {
            "type": "object",
            "title": "Spending limit",
            "description": "A run that would exceed either limit is skipped (spending_limit) and the schedule pauses.",
            "additionalProperties": false,
            "required": [
              "perDeliveryCredits",
              "perMonthCredits"
            ],
            "properties": {
              "perDeliveryCredits": {
                "type": "integer",
                "minimum": 1,
                "title": "Per delivery",
                "description": "At most this many credits per delivery.",
                "examples": [
                  1000
                ]
              },
              "perMonthCredits": {
                "type": "integer",
                "minimum": 1,
                "title": "Per month",
                "description": "At most this many credits per calendar month (IST).",
                "examples": [
                  5000
                ]
              }
            }
          }
        }
      },
      "ReportScheduleActivate": {
        "type": "object",
        "title": "Activate a schedule",
        "description": "Confirm the cost shown in cost; it must equal the current estimate (otherwise cost_changed, with the new estimate).",
        "additionalProperties": false,
        "required": [
          "perDeliveryCredits",
          "perMonthCredits"
        ],
        "properties": {
          "perDeliveryCredits": {
            "type": "integer",
            "minimum": 0,
            "title": "Per delivery",
            "description": "The cost.perDeliveryCredits being confirmed.",
            "examples": [
              871
            ]
          },
          "perMonthCredits": {
            "type": "integer",
            "minimum": 0,
            "title": "Per month",
            "description": "The cost.perMonthCredits being confirmed.",
            "examples": [
              4355
            ]
          }
        }
      },
      "ReportScheduleAnswer": {
        "type": "object",
        "title": "Report schedule answer",
        "description": "One schedule.",
        "additionalProperties": false,
        "required": [
          "data"
        ],
        "properties": {
          "data": {
            "type": "object",
            "title": "Report schedule",
            "description": "A scheduled report: what it reads, when, at what confirmed cost, and what happened.",
            "additionalProperties": false,
            "required": [
              "id",
              "state",
              "pauseReason",
              "name",
              "data",
              "window",
              "frequency",
              "timezone",
              "renderer",
              "title",
              "subject",
              "delivery",
              "spendingLimit",
              "cost",
              "confirmed",
              "nextDeliveryAt",
              "lastRun",
              "failuresInRow",
              "editions",
              "createdAt",
              "updatedAt"
            ],
            "properties": {
              "id": {
                "type": "string",
                "title": "Id",
                "description": "The schedule id.",
                "examples": [
                  "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                ],
                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
              },
              "state": {
                "type": "string",
                "enum": [
                  "draft",
                  "needs_confirmation",
                  "active",
                  "paused",
                  "cancelled"
                ],
                "title": "State",
                "description": "draft, needs_confirmation, active, paused or cancelled.",
                "examples": [
                  "draft"
                ]
              },
              "pauseReason": {
                "type": [
                  "null",
                  "string"
                ],
                "enum": [
                  "by_user",
                  "insufficient_credits",
                  "spending_limit",
                  "renderer_failed",
                  null
                ],
                "title": "Pause reason",
                "description": "Why it is paused; null otherwise.",
                "examples": [
                  "by_user"
                ]
              },
              "name": {
                "type": "string",
                "title": "Name",
                "description": "A name for the schedule.",
                "examples": [
                  "The Love Co. weekly shelf"
                ],
                "minLength": 1,
                "maxLength": 200
              },
              "data": {
                "type": "object",
                "title": "Data",
                "description": "What each delivery reads: the report data request without its period (the window rule gives it).",
                "additionalProperties": false,
                "required": [
                  "datasets"
                ],
                "properties": {
                  "datasets": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "title": "Dataset request",
                      "description": "One dataset, narrowed.",
                      "additionalProperties": false,
                      "required": [
                        "dataset"
                      ],
                      "properties": {
                        "dataset": {
                          "type": "string",
                          "enum": [
                            "listings",
                            "observations",
                            "rating_changes",
                            "banner_placements",
                            "brand_mentions",
                            "promo_emails",
                            "storefront_promos",
                            "ad_creatives",
                            "brands",
                            "retailers"
                          ],
                          "title": "Dataset",
                          "description": "Which dataset.",
                          "examples": [
                            "listings"
                          ]
                        },
                        "fields": {
                          "type": "array",
                          "items": {
                            "type": "string",
                            "pattern": "^[a-zA-Z][a-zA-Z0-9_]{0,60}$"
                          },
                          "title": "Fields",
                          "description": "Only these fields of each record (the record id and its source fields are always included). Default: all.",
                          "maxItems": 100,
                          "uniqueItems": true,
                          "examples": [
                            [
                              "retailer",
                              "priceMinor",
                              "mrpMinor",
                              "observedAt"
                            ]
                          ]
                        },
                        "filters": {
                          "type": "object",
                          "title": "Report data filters",
                          "description": "Narrow a dataset. Values are exact (brands as retailers write them). Each dataset supports only some filters.",
                          "additionalProperties": false,
                          "required": [],
                          "properties": {
                            "retailers": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200,
                                "pattern": "^[a-z0-9_]{1,40}$"
                              },
                              "title": "Retailers",
                              "description": "Retailer ids.",
                              "minItems": 1,
                              "maxItems": 200,
                              "uniqueItems": true,
                              "examples": [
                                [
                                  "blinkit",
                                  "zepto"
                                ]
                              ]
                            },
                            "brands": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200
                              },
                              "title": "Brands",
                              "description": "Brands, exactly as written.",
                              "minItems": 1,
                              "maxItems": 200,
                              "uniqueItems": true,
                              "examples": [
                                [
                                  "The Love Co."
                                ]
                              ]
                            },
                            "pincodes": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200,
                                "pattern": "^[1-9][0-9]{5}$"
                              },
                              "title": "Pin codes",
                              "description": "Six-digit pin codes.",
                              "minItems": 1,
                              "maxItems": 200,
                              "uniqueItems": true,
                              "examples": [
                                [
                                  "560001"
                                ]
                              ]
                            },
                            "productIds": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200,
                                "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                              },
                              "title": "Products",
                              "description": "Core product ids.",
                              "minItems": 1,
                              "maxItems": 200,
                              "uniqueItems": true,
                              "examples": [
                                [
                                  "8d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a"
                                ]
                              ]
                            },
                            "retailerSkus": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200
                              },
                              "title": "Retailer SKUs",
                              "description": "Retailers' own product ids.",
                              "minItems": 1,
                              "maxItems": 200,
                              "uniqueItems": true,
                              "examples": [
                                [
                                  "15739354"
                                ]
                              ]
                            },
                            "searchTerms": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200
                              },
                              "title": "Search terms",
                              "description": "Search terms, as typed in the app.",
                              "minItems": 1,
                              "maxItems": 200,
                              "uniqueItems": true,
                              "examples": [
                                [
                                  "hand wash"
                                ]
                              ]
                            },
                            "advertisers": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200
                              },
                              "title": "Advertisers",
                              "description": "Advertiser names, as the ad library shows them.",
                              "minItems": 1,
                              "maxItems": 200,
                              "uniqueItems": true,
                              "examples": [
                                [
                                  "The Love Co"
                                ]
                              ]
                            },
                            "domains": {
                              "type": "array",
                              "items": {
                                "type": "string",
                                "minLength": 1,
                                "maxLength": 200
                              },
                              "title": "Domains",
                              "description": "Brands' own store domains.",
                              "minItems": 1,
                              "maxItems": 200,
                              "uniqueItems": true,
                              "examples": [
                                [
                                  "theloveco.in"
                                ]
                              ]
                            }
                          }
                        }
                      }
                    },
                    "title": "Datasets",
                    "description": "One entry per dataset; each dataset at most once.",
                    "minItems": 1,
                    "maxItems": 10
                  }
                }
              },
              "window": {
                "title": "Reporting window",
                "description": "Which days each delivery covers, in the schedule time zone: the last N complete days before the run, or the previous calendar week or month.",
                "oneOf": [
                  {
                    "type": "object",
                    "title": "Rolling days",
                    "description": "The last N complete days.",
                    "additionalProperties": false,
                    "required": [
                      "kind",
                      "days"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "rolling_days",
                        "title": "Kind",
                        "description": "rolling_days."
                      },
                      "days": {
                        "type": "integer",
                        "minimum": 1,
                        "title": "Days",
                        "description": "1 to 366.",
                        "examples": [
                          7
                        ],
                        "maximum": 366
                      }
                    }
                  },
                  {
                    "type": "object",
                    "title": "Previous calendar period",
                    "description": "The previous complete week (Monday to Sunday) or month.",
                    "additionalProperties": false,
                    "required": [
                      "kind",
                      "period"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "previous_period",
                        "title": "Kind",
                        "description": "previous_period."
                      },
                      "period": {
                        "type": "string",
                        "enum": [
                          "week",
                          "month"
                        ],
                        "title": "Period",
                        "description": "week or month.",
                        "examples": [
                          "week"
                        ]
                      }
                    }
                  }
                ],
                "examples": [
                  {
                    "kind": "rolling_days",
                    "days": 7
                  }
                ]
              },
              "frequency": {
                "title": "Frequency",
                "description": "When deliveries run, in the schedule time zone.",
                "oneOf": [
                  {
                    "type": "object",
                    "title": "Daily",
                    "description": "Every day.",
                    "additionalProperties": false,
                    "required": [
                      "kind",
                      "time"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "daily",
                        "title": "Kind",
                        "description": "daily."
                      },
                      "time": {
                        "type": "string",
                        "title": "Time",
                        "description": "Local time, HH:MM, 24-hour.",
                        "examples": [
                          "07:00"
                        ],
                        "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "title": "Weekly",
                    "description": "Once a week.",
                    "additionalProperties": false,
                    "required": [
                      "kind",
                      "weekday",
                      "time"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "weekly",
                        "title": "Kind",
                        "description": "weekly."
                      },
                      "weekday": {
                        "type": "string",
                        "enum": [
                          "monday",
                          "tuesday",
                          "wednesday",
                          "thursday",
                          "friday",
                          "saturday",
                          "sunday"
                        ],
                        "title": "Weekday",
                        "description": "The day.",
                        "examples": [
                          "monday"
                        ]
                      },
                      "time": {
                        "type": "string",
                        "title": "Time",
                        "description": "Local time, HH:MM, 24-hour.",
                        "examples": [
                          "07:00"
                        ],
                        "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                      }
                    }
                  },
                  {
                    "type": "object",
                    "title": "Monthly",
                    "description": "Once a month.",
                    "additionalProperties": false,
                    "required": [
                      "kind",
                      "dayOfMonth",
                      "time"
                    ],
                    "properties": {
                      "kind": {
                        "type": "string",
                        "const": "monthly",
                        "title": "Kind",
                        "description": "monthly."
                      },
                      "dayOfMonth": {
                        "type": "integer",
                        "minimum": 1,
                        "title": "Day",
                        "description": "1 to 28, so every month has it.",
                        "examples": [
                          1
                        ],
                        "maximum": 28
                      },
                      "time": {
                        "type": "string",
                        "title": "Time",
                        "description": "Local time, HH:MM, 24-hour.",
                        "examples": [
                          "07:00"
                        ],
                        "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                      }
                    }
                  }
                ],
                "examples": [
                  {
                    "kind": "weekly",
                    "weekday": "monday",
                    "time": "07:00"
                  }
                ]
              },
              "timezone": {
                "type": "string",
                "enum": [
                  "Asia/Kolkata"
                ],
                "title": "Time zone",
                "description": "Asia/Kolkata for now."
              },
              "renderer": {
                "type": "object",
                "title": "Renderer",
                "description": "The frontend's renderer the worker runs (D-1777): an allow-listed package, an exact version and a template.",
                "additionalProperties": false,
                "required": [
                  "package",
                  "version",
                  "template"
                ],
                "properties": {
                  "package": {
                    "type": "string",
                    "title": "Package",
                    "description": "The npm package the frontend published.",
                    "examples": [
                      "@rewalto/report-renderer"
                    ],
                    "pattern": "^(@[a-z0-9-]+/)?[a-z0-9][a-z0-9._-]*$"
                  },
                  "version": {
                    "type": "string",
                    "title": "Version",
                    "description": "An exact version on Core's allow-list (no ranges).",
                    "examples": [
                      "1.0.0"
                    ],
                    "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[0-9A-Za-z.-]+)?$"
                  },
                  "template": {
                    "type": "string",
                    "title": "Template",
                    "description": "A template the package declares.",
                    "examples": [
                      "brand-shelf"
                    ],
                    "pattern": "^[a-z0-9][a-z0-9-]{0,60}$"
                  }
                }
              },
              "title": {
                "type": "string",
                "title": "Report title",
                "description": "Each edition's title; {from} and {to} are replaced by the window dates.",
                "examples": [
                  "The Love Co. — week {from} to {to}"
                ],
                "minLength": 1,
                "maxLength": 300
              },
              "subject": {
                "type": "object",
                "title": "Subject",
                "description": "What the report is about.",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "name",
                  "slug"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "brand",
                      "category",
                      "retailer",
                      "dataset"
                    ],
                    "title": "Kind",
                    "description": "brand, category, retailer or dataset.",
                    "examples": [
                      "brand"
                    ]
                  },
                  "name": {
                    "type": "string",
                    "title": "Name",
                    "description": "As the report names it.",
                    "examples": [
                      "The Love Co."
                    ],
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "slug": {
                    "type": "string",
                    "title": "Slug",
                    "description": "Lowercase words joined by hyphens.",
                    "examples": [
                      "the-love-co"
                    ],
                    "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
                    "maxLength": 80
                  }
                }
              },
              "delivery": {
                "type": "object",
                "title": "Delivery",
                "description": "Every edition is saved to the organisation's report history; optionally, named members are told when it is ready (a link to the report, never the file).",
                "additionalProperties": false,
                "required": [
                  "saveToHistory"
                ],
                "properties": {
                  "saveToHistory": {
                    "type": "boolean",
                    "const": true,
                    "title": "Save to history",
                    "description": "Always true."
                  },
                  "notifyUserIds": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "title": "Member",
                      "description": "A member of the organisation (Clerk user id).",
                      "examples": [
                        "user_EXAMPLE0000000001"
                      ]
                    },
                    "title": "Notify",
                    "description": "Members told when an edition is saved or a run fails.",
                    "maxItems": 20,
                    "uniqueItems": true
                  }
                }
              },
              "spendingLimit": {
                "type": "object",
                "title": "Spending limit",
                "description": "A run that would exceed either limit is skipped (spending_limit) and the schedule pauses.",
                "additionalProperties": false,
                "required": [
                  "perDeliveryCredits",
                  "perMonthCredits"
                ],
                "properties": {
                  "perDeliveryCredits": {
                    "type": "integer",
                    "minimum": 1,
                    "title": "Per delivery",
                    "description": "At most this many credits per delivery.",
                    "examples": [
                      1000
                    ]
                  },
                  "perMonthCredits": {
                    "type": "integer",
                    "minimum": 1,
                    "title": "Per month",
                    "description": "At most this many credits per calendar month (IST).",
                    "examples": [
                      5000
                    ]
                  }
                }
              },
              "cost": {
                "type": "object",
                "title": "Cost",
                "description": "Estimated at the published rates from what the data request matches now (C-012; no report fee, D-1760).",
                "additionalProperties": false,
                "required": [
                  "perDeliveryCredits",
                  "deliveriesPerMonth",
                  "perMonthCredits",
                  "rateVersion",
                  "estimatedAt",
                  "fitsBalance"
                ],
                "properties": {
                  "perDeliveryCredits": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Per delivery",
                    "description": "Estimated credits per delivery.",
                    "examples": [
                      871
                    ]
                  },
                  "deliveriesPerMonth": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Deliveries per month",
                    "description": "At most this many in a month.",
                    "examples": [
                      5
                    ]
                  },
                  "perMonthCredits": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Per month",
                    "description": "Estimated credits per month.",
                    "examples": [
                      4355
                    ]
                  },
                  "rateVersion": {
                    "type": "string",
                    "title": "Rate version",
                    "description": "The rate card used.",
                    "examples": [
                      "4"
                    ]
                  },
                  "estimatedAt": {
                    "type": "string",
                    "title": "Estimated at",
                    "description": "When it was estimated.",
                    "examples": [
                      "2026-10-18T10:00:00Z"
                    ],
                    "format": "date-time"
                  },
                  "fitsBalance": {
                    "type": "boolean",
                    "title": "Fits balance",
                    "description": "The month fits the credits the organisation has left (always true under unlimited credits)."
                  }
                }
              },
              "confirmed": {
                "type": [
                  "null",
                  "object"
                ],
                "title": "Confirmed",
                "description": "The cost the user confirmed; null until confirmed.",
                "additionalProperties": false,
                "required": [
                  "perDeliveryCredits",
                  "perMonthCredits",
                  "confirmedBy",
                  "confirmedAt"
                ],
                "properties": {
                  "perDeliveryCredits": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Per delivery",
                    "description": "Confirmed per delivery.",
                    "examples": [
                      871
                    ]
                  },
                  "perMonthCredits": {
                    "type": "integer",
                    "minimum": 0,
                    "title": "Per month",
                    "description": "Confirmed per month.",
                    "examples": [
                      4355
                    ]
                  },
                  "confirmedBy": {
                    "type": "string",
                    "title": "By",
                    "description": "Who confirmed.",
                    "examples": [
                      "staff:user_EXAMPLE0000000001"
                    ]
                  },
                  "confirmedAt": {
                    "type": "string",
                    "title": "At",
                    "description": "When.",
                    "examples": [
                      "2026-10-18T10:05:00Z"
                    ],
                    "format": "date-time"
                  }
                }
              },
              "nextDeliveryAt": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next delivery",
                "description": "The next run; null unless active.",
                "examples": [
                  "2026-10-20T01:30:00Z"
                ],
                "format": "date-time"
              },
              "lastRun": {
                "type": [
                  "null",
                  "object"
                ],
                "title": "Last run",
                "description": "The most recent run.",
                "additionalProperties": false,
                "required": [
                  "id",
                  "state",
                  "editionId",
                  "finishedAt"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "title": "Run",
                    "description": "The run id.",
                    "examples": [
                      "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                    ],
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "state": {
                    "type": "string",
                    "enum": [
                      "queued",
                      "quoting",
                      "building_data",
                      "rendering",
                      "saving",
                      "saved",
                      "failed",
                      "skipped"
                    ],
                    "title": "State",
                    "description": "Its state.",
                    "examples": [
                      "queued"
                    ]
                  },
                  "editionId": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "title": "Edition",
                    "description": "The saved report; null unless saved.",
                    "examples": [
                      "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                    ],
                    "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                  },
                  "finishedAt": {
                    "type": [
                      "null",
                      "string"
                    ],
                    "title": "Finished at",
                    "description": "When it ended.",
                    "examples": [
                      "2026-10-13T01:31:10Z"
                    ],
                    "format": "date-time"
                  }
                }
              },
              "failuresInRow": {
                "type": "integer",
                "minimum": 0,
                "title": "Failures in a row",
                "description": "Runs that failed since the last saved one.",
                "examples": [
                  0
                ]
              },
              "editions": {
                "type": "integer",
                "minimum": 0,
                "title": "Editions",
                "description": "Editions saved so far.",
                "examples": [
                  3
                ]
              },
              "createdAt": {
                "type": "string",
                "title": "Created at",
                "description": "When it was created.",
                "examples": [
                  "2026-10-18T10:00:00Z"
                ],
                "format": "date-time"
              },
              "updatedAt": {
                "type": "string",
                "title": "Updated at",
                "description": "Last change.",
                "examples": [
                  "2026-10-18T10:05:00Z"
                ],
                "format": "date-time"
              }
            }
          }
        }
      },
      "ReportSchedulesPage": {
        "type": "object",
        "title": "Report schedules",
        "description": "The organisation's schedules, newest first.",
        "additionalProperties": false,
        "required": [
          "data",
          "page"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "title": "Report schedule",
              "description": "A scheduled report: what it reads, when, at what confirmed cost, and what happened.",
              "additionalProperties": false,
              "required": [
                "id",
                "state",
                "pauseReason",
                "name",
                "data",
                "window",
                "frequency",
                "timezone",
                "renderer",
                "title",
                "subject",
                "delivery",
                "spendingLimit",
                "cost",
                "confirmed",
                "nextDeliveryAt",
                "lastRun",
                "failuresInRow",
                "editions",
                "createdAt",
                "updatedAt"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "title": "Id",
                  "description": "The schedule id.",
                  "examples": [
                    "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                  ],
                  "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                },
                "state": {
                  "type": "string",
                  "enum": [
                    "draft",
                    "needs_confirmation",
                    "active",
                    "paused",
                    "cancelled"
                  ],
                  "title": "State",
                  "description": "draft, needs_confirmation, active, paused or cancelled.",
                  "examples": [
                    "draft"
                  ]
                },
                "pauseReason": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "enum": [
                    "by_user",
                    "insufficient_credits",
                    "spending_limit",
                    "renderer_failed",
                    null
                  ],
                  "title": "Pause reason",
                  "description": "Why it is paused; null otherwise.",
                  "examples": [
                    "by_user"
                  ]
                },
                "name": {
                  "type": "string",
                  "title": "Name",
                  "description": "A name for the schedule.",
                  "examples": [
                    "The Love Co. weekly shelf"
                  ],
                  "minLength": 1,
                  "maxLength": 200
                },
                "data": {
                  "type": "object",
                  "title": "Data",
                  "description": "What each delivery reads: the report data request without its period (the window rule gives it).",
                  "additionalProperties": false,
                  "required": [
                    "datasets"
                  ],
                  "properties": {
                    "datasets": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "title": "Dataset request",
                        "description": "One dataset, narrowed.",
                        "additionalProperties": false,
                        "required": [
                          "dataset"
                        ],
                        "properties": {
                          "dataset": {
                            "type": "string",
                            "enum": [
                              "listings",
                              "observations",
                              "rating_changes",
                              "banner_placements",
                              "brand_mentions",
                              "promo_emails",
                              "storefront_promos",
                              "ad_creatives",
                              "brands",
                              "retailers"
                            ],
                            "title": "Dataset",
                            "description": "Which dataset.",
                            "examples": [
                              "listings"
                            ]
                          },
                          "fields": {
                            "type": "array",
                            "items": {
                              "type": "string",
                              "pattern": "^[a-zA-Z][a-zA-Z0-9_]{0,60}$"
                            },
                            "title": "Fields",
                            "description": "Only these fields of each record (the record id and its source fields are always included). Default: all.",
                            "maxItems": 100,
                            "uniqueItems": true,
                            "examples": [
                              [
                                "retailer",
                                "priceMinor",
                                "mrpMinor",
                                "observedAt"
                              ]
                            ]
                          },
                          "filters": {
                            "type": "object",
                            "title": "Report data filters",
                            "description": "Narrow a dataset. Values are exact (brands as retailers write them). Each dataset supports only some filters.",
                            "additionalProperties": false,
                            "required": [],
                            "properties": {
                              "retailers": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200,
                                  "pattern": "^[a-z0-9_]{1,40}$"
                                },
                                "title": "Retailers",
                                "description": "Retailer ids.",
                                "minItems": 1,
                                "maxItems": 200,
                                "uniqueItems": true,
                                "examples": [
                                  [
                                    "blinkit",
                                    "zepto"
                                  ]
                                ]
                              },
                              "brands": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                "title": "Brands",
                                "description": "Brands, exactly as written.",
                                "minItems": 1,
                                "maxItems": 200,
                                "uniqueItems": true,
                                "examples": [
                                  [
                                    "The Love Co."
                                  ]
                                ]
                              },
                              "pincodes": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200,
                                  "pattern": "^[1-9][0-9]{5}$"
                                },
                                "title": "Pin codes",
                                "description": "Six-digit pin codes.",
                                "minItems": 1,
                                "maxItems": 200,
                                "uniqueItems": true,
                                "examples": [
                                  [
                                    "560001"
                                  ]
                                ]
                              },
                              "productIds": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200,
                                  "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                                },
                                "title": "Products",
                                "description": "Core product ids.",
                                "minItems": 1,
                                "maxItems": 200,
                                "uniqueItems": true,
                                "examples": [
                                  [
                                    "8d2e3f4a-5b6c-4d7e-8f9a-0b1c2d3e4f5a"
                                  ]
                                ]
                              },
                              "retailerSkus": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                "title": "Retailer SKUs",
                                "description": "Retailers' own product ids.",
                                "minItems": 1,
                                "maxItems": 200,
                                "uniqueItems": true,
                                "examples": [
                                  [
                                    "15739354"
                                  ]
                                ]
                              },
                              "searchTerms": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                "title": "Search terms",
                                "description": "Search terms, as typed in the app.",
                                "minItems": 1,
                                "maxItems": 200,
                                "uniqueItems": true,
                                "examples": [
                                  [
                                    "hand wash"
                                  ]
                                ]
                              },
                              "advertisers": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                "title": "Advertisers",
                                "description": "Advertiser names, as the ad library shows them.",
                                "minItems": 1,
                                "maxItems": 200,
                                "uniqueItems": true,
                                "examples": [
                                  [
                                    "The Love Co"
                                  ]
                                ]
                              },
                              "domains": {
                                "type": "array",
                                "items": {
                                  "type": "string",
                                  "minLength": 1,
                                  "maxLength": 200
                                },
                                "title": "Domains",
                                "description": "Brands' own store domains.",
                                "minItems": 1,
                                "maxItems": 200,
                                "uniqueItems": true,
                                "examples": [
                                  [
                                    "theloveco.in"
                                  ]
                                ]
                              }
                            }
                          }
                        }
                      },
                      "title": "Datasets",
                      "description": "One entry per dataset; each dataset at most once.",
                      "minItems": 1,
                      "maxItems": 10
                    }
                  }
                },
                "window": {
                  "title": "Reporting window",
                  "description": "Which days each delivery covers, in the schedule time zone: the last N complete days before the run, or the previous calendar week or month.",
                  "oneOf": [
                    {
                      "type": "object",
                      "title": "Rolling days",
                      "description": "The last N complete days.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "days"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "const": "rolling_days",
                          "title": "Kind",
                          "description": "rolling_days."
                        },
                        "days": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Days",
                          "description": "1 to 366.",
                          "examples": [
                            7
                          ],
                          "maximum": 366
                        }
                      }
                    },
                    {
                      "type": "object",
                      "title": "Previous calendar period",
                      "description": "The previous complete week (Monday to Sunday) or month.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "period"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "const": "previous_period",
                          "title": "Kind",
                          "description": "previous_period."
                        },
                        "period": {
                          "type": "string",
                          "enum": [
                            "week",
                            "month"
                          ],
                          "title": "Period",
                          "description": "week or month.",
                          "examples": [
                            "week"
                          ]
                        }
                      }
                    }
                  ],
                  "examples": [
                    {
                      "kind": "rolling_days",
                      "days": 7
                    }
                  ]
                },
                "frequency": {
                  "title": "Frequency",
                  "description": "When deliveries run, in the schedule time zone.",
                  "oneOf": [
                    {
                      "type": "object",
                      "title": "Daily",
                      "description": "Every day.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "time"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "const": "daily",
                          "title": "Kind",
                          "description": "daily."
                        },
                        "time": {
                          "type": "string",
                          "title": "Time",
                          "description": "Local time, HH:MM, 24-hour.",
                          "examples": [
                            "07:00"
                          ],
                          "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "title": "Weekly",
                      "description": "Once a week.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "weekday",
                        "time"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "const": "weekly",
                          "title": "Kind",
                          "description": "weekly."
                        },
                        "weekday": {
                          "type": "string",
                          "enum": [
                            "monday",
                            "tuesday",
                            "wednesday",
                            "thursday",
                            "friday",
                            "saturday",
                            "sunday"
                          ],
                          "title": "Weekday",
                          "description": "The day.",
                          "examples": [
                            "monday"
                          ]
                        },
                        "time": {
                          "type": "string",
                          "title": "Time",
                          "description": "Local time, HH:MM, 24-hour.",
                          "examples": [
                            "07:00"
                          ],
                          "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "title": "Monthly",
                      "description": "Once a month.",
                      "additionalProperties": false,
                      "required": [
                        "kind",
                        "dayOfMonth",
                        "time"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string",
                          "const": "monthly",
                          "title": "Kind",
                          "description": "monthly."
                        },
                        "dayOfMonth": {
                          "type": "integer",
                          "minimum": 1,
                          "title": "Day",
                          "description": "1 to 28, so every month has it.",
                          "examples": [
                            1
                          ],
                          "maximum": 28
                        },
                        "time": {
                          "type": "string",
                          "title": "Time",
                          "description": "Local time, HH:MM, 24-hour.",
                          "examples": [
                            "07:00"
                          ],
                          "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$"
                        }
                      }
                    }
                  ],
                  "examples": [
                    {
                      "kind": "weekly",
                      "weekday": "monday",
                      "time": "07:00"
                    }
                  ]
                },
                "timezone": {
                  "type": "string",
                  "enum": [
                    "Asia/Kolkata"
                  ],
                  "title": "Time zone",
                  "description": "Asia/Kolkata for now."
                },
                "renderer": {
                  "type": "object",
                  "title": "Renderer",
                  "description": "The frontend's renderer the worker runs (D-1777): an allow-listed package, an exact version and a template.",
                  "additionalProperties": false,
                  "required": [
                    "package",
                    "version",
                    "template"
                  ],
                  "properties": {
                    "package": {
                      "type": "string",
                      "title": "Package",
                      "description": "The npm package the frontend published.",
                      "examples": [
                        "@rewalto/report-renderer"
                      ],
                      "pattern": "^(@[a-z0-9-]+/)?[a-z0-9][a-z0-9._-]*$"
                    },
                    "version": {
                      "type": "string",
                      "title": "Version",
                      "description": "An exact version on Core's allow-list (no ranges).",
                      "examples": [
                        "1.0.0"
                      ],
                      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[0-9A-Za-z.-]+)?$"
                    },
                    "template": {
                      "type": "string",
                      "title": "Template",
                      "description": "A template the package declares.",
                      "examples": [
                        "brand-shelf"
                      ],
                      "pattern": "^[a-z0-9][a-z0-9-]{0,60}$"
                    }
                  }
                },
                "title": {
                  "type": "string",
                  "title": "Report title",
                  "description": "Each edition's title; {from} and {to} are replaced by the window dates.",
                  "examples": [
                    "The Love Co. — week {from} to {to}"
                  ],
                  "minLength": 1,
                  "maxLength": 300
                },
                "subject": {
                  "type": "object",
                  "title": "Subject",
                  "description": "What the report is about.",
                  "additionalProperties": false,
                  "required": [
                    "kind",
                    "name",
                    "slug"
                  ],
                  "properties": {
                    "kind": {
                      "type": "string",
                      "enum": [
                        "brand",
                        "category",
                        "retailer",
                        "dataset"
                      ],
                      "title": "Kind",
                      "description": "brand, category, retailer or dataset.",
                      "examples": [
                        "brand"
                      ]
                    },
                    "name": {
                      "type": "string",
                      "title": "Name",
                      "description": "As the report names it.",
                      "examples": [
                        "The Love Co."
                      ],
                      "minLength": 1,
                      "maxLength": 200
                    },
                    "slug": {
                      "type": "string",
                      "title": "Slug",
                      "description": "Lowercase words joined by hyphens.",
                      "examples": [
                        "the-love-co"
                      ],
                      "pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
                      "maxLength": 80
                    }
                  }
                },
                "delivery": {
                  "type": "object",
                  "title": "Delivery",
                  "description": "Every edition is saved to the organisation's report history; optionally, named members are told when it is ready (a link to the report, never the file).",
                  "additionalProperties": false,
                  "required": [
                    "saveToHistory"
                  ],
                  "properties": {
                    "saveToHistory": {
                      "type": "boolean",
                      "const": true,
                      "title": "Save to history",
                      "description": "Always true."
                    },
                    "notifyUserIds": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "title": "Member",
                        "description": "A member of the organisation (Clerk user id).",
                        "examples": [
                          "user_EXAMPLE0000000001"
                        ]
                      },
                      "title": "Notify",
                      "description": "Members told when an edition is saved or a run fails.",
                      "maxItems": 20,
                      "uniqueItems": true
                    }
                  }
                },
                "spendingLimit": {
                  "type": "object",
                  "title": "Spending limit",
                  "description": "A run that would exceed either limit is skipped (spending_limit) and the schedule pauses.",
                  "additionalProperties": false,
                  "required": [
                    "perDeliveryCredits",
                    "perMonthCredits"
                  ],
                  "properties": {
                    "perDeliveryCredits": {
                      "type": "integer",
                      "minimum": 1,
                      "title": "Per delivery",
                      "description": "At most this many credits per delivery.",
                      "examples": [
                        1000
                      ]
                    },
                    "perMonthCredits": {
                      "type": "integer",
                      "minimum": 1,
                      "title": "Per month",
                      "description": "At most this many credits per calendar month (IST).",
                      "examples": [
                        5000
                      ]
                    }
                  }
                },
                "cost": {
                  "type": "object",
                  "title": "Cost",
                  "description": "Estimated at the published rates from what the data request matches now (C-012; no report fee, D-1760).",
                  "additionalProperties": false,
                  "required": [
                    "perDeliveryCredits",
                    "deliveriesPerMonth",
                    "perMonthCredits",
                    "rateVersion",
                    "estimatedAt",
                    "fitsBalance"
                  ],
                  "properties": {
                    "perDeliveryCredits": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Per delivery",
                      "description": "Estimated credits per delivery.",
                      "examples": [
                        871
                      ]
                    },
                    "deliveriesPerMonth": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Deliveries per month",
                      "description": "At most this many in a month.",
                      "examples": [
                        5
                      ]
                    },
                    "perMonthCredits": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Per month",
                      "description": "Estimated credits per month.",
                      "examples": [
                        4355
                      ]
                    },
                    "rateVersion": {
                      "type": "string",
                      "title": "Rate version",
                      "description": "The rate card used.",
                      "examples": [
                        "4"
                      ]
                    },
                    "estimatedAt": {
                      "type": "string",
                      "title": "Estimated at",
                      "description": "When it was estimated.",
                      "examples": [
                        "2026-10-18T10:00:00Z"
                      ],
                      "format": "date-time"
                    },
                    "fitsBalance": {
                      "type": "boolean",
                      "title": "Fits balance",
                      "description": "The month fits the credits the organisation has left (always true under unlimited credits)."
                    }
                  }
                },
                "confirmed": {
                  "type": [
                    "null",
                    "object"
                  ],
                  "title": "Confirmed",
                  "description": "The cost the user confirmed; null until confirmed.",
                  "additionalProperties": false,
                  "required": [
                    "perDeliveryCredits",
                    "perMonthCredits",
                    "confirmedBy",
                    "confirmedAt"
                  ],
                  "properties": {
                    "perDeliveryCredits": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Per delivery",
                      "description": "Confirmed per delivery.",
                      "examples": [
                        871
                      ]
                    },
                    "perMonthCredits": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Per month",
                      "description": "Confirmed per month.",
                      "examples": [
                        4355
                      ]
                    },
                    "confirmedBy": {
                      "type": "string",
                      "title": "By",
                      "description": "Who confirmed.",
                      "examples": [
                        "staff:user_EXAMPLE0000000001"
                      ]
                    },
                    "confirmedAt": {
                      "type": "string",
                      "title": "At",
                      "description": "When.",
                      "examples": [
                        "2026-10-18T10:05:00Z"
                      ],
                      "format": "date-time"
                    }
                  }
                },
                "nextDeliveryAt": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "title": "Next delivery",
                  "description": "The next run; null unless active.",
                  "examples": [
                    "2026-10-20T01:30:00Z"
                  ],
                  "format": "date-time"
                },
                "lastRun": {
                  "type": [
                    "null",
                    "object"
                  ],
                  "title": "Last run",
                  "description": "The most recent run.",
                  "additionalProperties": false,
                  "required": [
                    "id",
                    "state",
                    "editionId",
                    "finishedAt"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "title": "Run",
                      "description": "The run id.",
                      "examples": [
                        "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                      ],
                      "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                    },
                    "state": {
                      "type": "string",
                      "enum": [
                        "queued",
                        "quoting",
                        "building_data",
                        "rendering",
                        "saving",
                        "saved",
                        "failed",
                        "skipped"
                      ],
                      "title": "State",
                      "description": "Its state.",
                      "examples": [
                        "queued"
                      ]
                    },
                    "editionId": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Edition",
                      "description": "The saved report; null unless saved.",
                      "examples": [
                        "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                      ],
                      "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                    },
                    "finishedAt": {
                      "type": [
                        "null",
                        "string"
                      ],
                      "title": "Finished at",
                      "description": "When it ended.",
                      "examples": [
                        "2026-10-13T01:31:10Z"
                      ],
                      "format": "date-time"
                    }
                  }
                },
                "failuresInRow": {
                  "type": "integer",
                  "minimum": 0,
                  "title": "Failures in a row",
                  "description": "Runs that failed since the last saved one.",
                  "examples": [
                    0
                  ]
                },
                "editions": {
                  "type": "integer",
                  "minimum": 0,
                  "title": "Editions",
                  "description": "Editions saved so far.",
                  "examples": [
                    3
                  ]
                },
                "createdAt": {
                  "type": "string",
                  "title": "Created at",
                  "description": "When it was created.",
                  "examples": [
                    "2026-10-18T10:00:00Z"
                  ],
                  "format": "date-time"
                },
                "updatedAt": {
                  "type": "string",
                  "title": "Updated at",
                  "description": "Last change.",
                  "examples": [
                    "2026-10-18T10:05:00Z"
                  ],
                  "format": "date-time"
                }
              }
            },
            "title": "Schedules",
            "description": "Newest first; cancelled ones last."
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "minimum": 0,
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  20
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Pass as cursor; null at the end.",
                "examples": [
                  "eyJ0Ijoi"
                ],
                "pattern": "^[A-Za-z0-9_-]{1,400}$"
              }
            }
          }
        }
      },
      "ReportRunsPage": {
        "type": "object",
        "title": "Report runs",
        "description": "A schedule's runs, newest first.",
        "additionalProperties": false,
        "required": [
          "data",
          "page"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "title": "Report run",
              "description": "One delivery: exactly one per schedule and slot, so a duplicate start is the same run.",
              "additionalProperties": false,
              "required": [
                "id",
                "scheduleId",
                "slot",
                "state",
                "skipReason",
                "failure",
                "window",
                "renderer",
                "quoteId",
                "dataPackageId",
                "credits",
                "editionId",
                "startedAt",
                "finishedAt"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "title": "Id",
                  "description": "The run id.",
                  "examples": [
                    "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                  ],
                  "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                },
                "scheduleId": {
                  "type": "string",
                  "title": "Schedule",
                  "description": "Its schedule.",
                  "examples": [
                    "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                  ],
                  "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                },
                "slot": {
                  "type": "string",
                  "title": "Slot",
                  "description": "The delivery time it is for.",
                  "examples": [
                    "2026-10-20T01:30:00Z"
                  ],
                  "format": "date-time"
                },
                "state": {
                  "type": "string",
                  "enum": [
                    "queued",
                    "quoting",
                    "building_data",
                    "rendering",
                    "saving",
                    "saved",
                    "failed",
                    "skipped"
                  ],
                  "title": "State",
                  "description": "queued, quoting, building_data, rendering, saving, saved, failed or skipped.",
                  "examples": [
                    "queued"
                  ]
                },
                "skipReason": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "enum": [
                    "insufficient_credits",
                    "spending_limit",
                    "paused",
                    "cancelled",
                    null
                  ],
                  "title": "Skip reason",
                  "description": "Why it was skipped; null otherwise.",
                  "examples": [
                    "insufficient_credits"
                  ]
                },
                "failure": {
                  "type": [
                    "null",
                    "object"
                  ],
                  "title": "Failure",
                  "description": "Where and why it failed; nothing partial is saved.",
                  "additionalProperties": false,
                  "required": [
                    "stage",
                    "message"
                  ],
                  "properties": {
                    "stage": {
                      "type": "string",
                      "enum": [
                        "quote",
                        "data",
                        "renderer",
                        "upload",
                        "register"
                      ],
                      "title": "Stage",
                      "description": "quote, data, renderer, upload or register.",
                      "examples": [
                        "quote"
                      ]
                    },
                    "message": {
                      "type": "string",
                      "title": "Message",
                      "description": "What went wrong, plain English.",
                      "examples": [
                        "renderer exceeded 120 seconds"
                      ]
                    }
                  }
                },
                "window": {
                  "type": "object",
                  "title": "Window",
                  "description": "The days this delivery covers, IST.",
                  "additionalProperties": false,
                  "required": [
                    "from",
                    "to"
                  ],
                  "properties": {
                    "from": {
                      "type": "string",
                      "title": "From",
                      "description": "First day.",
                      "examples": [
                        "2026-10-13"
                      ],
                      "format": "date"
                    },
                    "to": {
                      "type": "string",
                      "title": "To",
                      "description": "Last day.",
                      "examples": [
                        "2026-10-19"
                      ],
                      "format": "date"
                    }
                  }
                },
                "renderer": {
                  "type": "object",
                  "title": "Renderer",
                  "description": "The frontend's renderer the worker runs (D-1777): an allow-listed package, an exact version and a template.",
                  "additionalProperties": false,
                  "required": [
                    "package",
                    "version",
                    "template"
                  ],
                  "properties": {
                    "package": {
                      "type": "string",
                      "title": "Package",
                      "description": "The npm package the frontend published.",
                      "examples": [
                        "@rewalto/report-renderer"
                      ],
                      "pattern": "^(@[a-z0-9-]+/)?[a-z0-9][a-z0-9._-]*$"
                    },
                    "version": {
                      "type": "string",
                      "title": "Version",
                      "description": "An exact version on Core's allow-list (no ranges).",
                      "examples": [
                        "1.0.0"
                      ],
                      "pattern": "^[0-9]+\\.[0-9]+\\.[0-9]+(-[0-9A-Za-z.-]+)?$"
                    },
                    "template": {
                      "type": "string",
                      "title": "Template",
                      "description": "A template the package declares.",
                      "examples": [
                        "brand-shelf"
                      ],
                      "pattern": "^[a-z0-9][a-z0-9-]{0,60}$"
                    }
                  }
                },
                "quoteId": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "title": "Quote",
                  "description": "Its data quote; null before quoting.",
                  "examples": [
                    "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                  ],
                  "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                },
                "dataPackageId": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "title": "Data package",
                  "description": "Its data package; null before building.",
                  "examples": [
                    "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                  ],
                  "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                },
                "credits": {
                  "type": "object",
                  "title": "Credits",
                  "description": "What it cost.",
                  "additionalProperties": false,
                  "required": [
                    "quoted",
                    "charged"
                  ],
                  "properties": {
                    "quoted": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Quoted",
                      "description": "The quote ceiling.",
                      "examples": [
                        871
                      ]
                    },
                    "charged": {
                      "type": "integer",
                      "minimum": 0,
                      "title": "Charged",
                      "description": "Settled, at most the quote; 0 when skipped or failed before reading.",
                      "examples": [
                        871
                      ]
                    }
                  }
                },
                "editionId": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "title": "Edition",
                  "description": "The saved report (GET /v1/reports/{id}); null unless saved.",
                  "examples": [
                    "5b6c7d8e-9f0a-4b1c-8d2e-3f4a5b6c7d8e"
                  ],
                  "pattern": "^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
                },
                "startedAt": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "title": "Started at",
                  "description": "When it started.",
                  "examples": [
                    "2026-10-20T01:30:02Z"
                  ],
                  "format": "date-time"
                },
                "finishedAt": {
                  "type": [
                    "null",
                    "string"
                  ],
                  "title": "Finished at",
                  "description": "When it ended.",
                  "examples": [
                    "2026-10-20T01:31:10Z"
                  ],
                  "format": "date-time"
                }
              }
            },
            "title": "Runs",
            "description": "Newest first."
          },
          "page": {
            "type": "object",
            "title": "Page",
            "description": "Paging.",
            "additionalProperties": false,
            "required": [
              "limit",
              "nextCursor"
            ],
            "properties": {
              "limit": {
                "type": "integer",
                "minimum": 0,
                "title": "Limit",
                "description": "The page size used.",
                "examples": [
                  20
                ]
              },
              "nextCursor": {
                "type": [
                  "null",
                  "string"
                ],
                "title": "Next cursor",
                "description": "Pass as cursor; null at the end.",
                "examples": [
                  "eyJ0Ijoi"
                ],
                "pattern": "^[A-Za-z0-9_-]{1,400}$"
              }
            }
          }
        }
      }
    },
    "headers": {
      "RequestIdHeader": {
        "description": "The id of this request. Quote it when you report a problem. You may send your own `x-request-id` (8 to 128 plain characters); anything else is replaced.",
        "schema": {
          "type": "string"
        }
      },
      "RateLimitLimitHeader": {
        "description": "Requests allowed in the current one-minute window for this credential (or, without one, this IP).",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "RateLimitRemainingHeader": {
        "description": "Requests left in the current window.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "RateLimitResetHeader": {
        "description": "Seconds until the current window resets.",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "RetryAfterHeader": {
        "description": "On a 429: seconds to wait before retrying (the same as `RateLimit-Reset`).",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      }
    },
    "securitySchemes": {
      "sessionJwt": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "A Clerk session token for a signed-in user: `Authorization: Bearer <token>`. Mint it in the frontend with the Clerk JWT template named `rewalto-core`, whose audience is `rewalto-core-api`. It carries `sub`, `org_id` and `org_role`. An expired token is `session_expired`."
      },
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "rwk_ API key",
        "description": "An organisation API key: `Authorization: Bearer rwk_...`. Minted with `createKey`; the secret is shown once. A key carries scopes and an expiry of 7, 30 or 90 days.",
        "x-scopes": [
          "data:read",
          "tools:run",
          "usage:read"
        ]
      },
      "serviceKey": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "rws_ service key",
        "description": "A Rewalto service key, for Rewalto's own servers only: `Authorization: Bearer rws_...`. Minted and revoked by staff, never through the API; the secret is shown once. It carries scopes and an expiry, opens only `/v1/service` routes, and every call is audited.",
        "x-scopes": [
          "notification-preferences:read",
          "intake:write"
        ]
      }
    }
  },
  "x-error-codes": {
    "invalid_request": {
      "status": 400,
      "retry": "fix_request"
    },
    "invalid_json": {
      "status": 400,
      "retry": "fix_request"
    },
    "unauthenticated": {
      "status": 401,
      "retry": "refresh_credentials"
    },
    "session_expired": {
      "status": 401,
      "retry": "refresh_credentials"
    },
    "key_expired": {
      "status": 401,
      "retry": "refresh_credentials"
    },
    "key_revoked": {
      "status": 401,
      "retry": "refresh_credentials"
    },
    "credits_exhausted": {
      "status": 402,
      "retry": "never"
    },
    "over_quote": {
      "status": 402,
      "retry": "never"
    },
    "plan_required": {
      "status": 402,
      "retry": "never"
    },
    "price_changed": {
      "status": 409,
      "retry": "never"
    },
    "forbidden": {
      "status": 403,
      "retry": "never"
    },
    "org_missing": {
      "status": 403,
      "retry": "never"
    },
    "scope_missing": {
      "status": 403,
      "retry": "never"
    },
    "not_entitled": {
      "status": 403,
      "retry": "never"
    },
    "private_data": {
      "status": 403,
      "retry": "never"
    },
    "access_control": {
      "status": 403,
      "retry": "never"
    },
    "not_found": {
      "status": 404,
      "retry": "fix_request"
    },
    "quote_expired": {
      "status": 410,
      "retry": "fix_request"
    },
    "quote_already_approved": {
      "status": 409,
      "retry": "never"
    },
    "refund_refused": {
      "status": 409,
      "retry": "never"
    },
    "catalogue_refused": {
      "status": 409,
      "retry": "never"
    },
    "not_for_sale": {
      "status": 409,
      "retry": "never"
    },
    "export_not_ready": {
      "status": 409,
      "retry": "never"
    },
    "download_expired": {
      "status": 410,
      "retry": "fix_request"
    },
    "idempotency_conflict": {
      "status": 409,
      "retry": "never"
    },
    "stale_version": {
      "status": 409,
      "retry": "never"
    },
    "package_not_ready": {
      "status": 409,
      "retry": "never"
    },
    "upload_not_ready": {
      "status": 409,
      "retry": "never"
    },
    "cost_changed": {
      "status": 409,
      "retry": "never"
    },
    "billing_profile_missing": {
      "status": 409,
      "retry": "never"
    },
    "export_not_available": {
      "status": 409,
      "retry": "never"
    },
    "unknown_capability": {
      "status": 404,
      "retry": "fix_request"
    },
    "schema_retired": {
      "status": 410,
      "retry": "fix_request"
    },
    "payload_too_large": {
      "status": 413,
      "retry": "fix_request"
    },
    "unsupported_media_type": {
      "status": 415,
      "retry": "fix_request"
    },
    "rate_limited": {
      "status": 429,
      "retry": "after_reset"
    },
    "internal": {
      "status": 500,
      "retry": "bounded"
    },
    "evidence_unavailable": {
      "status": 503,
      "retry": "bounded"
    },
    "payment_provider_unavailable": {
      "status": 503,
      "retry": "bounded"
    },
    "checkout_unavailable": {
      "status": 503,
      "retry": "bounded"
    },
    "invoicing_unavailable": {
      "status": 409,
      "retry": "never"
    },
    "unavailable": {
      "status": 503,
      "retry": "bounded"
    }
  }
}
