openapi: 3.1.0

# =============================================================================
# eqomOS Partner API - the LIVE surface.
#
# ⚠️ THIS FILE REPLACES A SPEC THAT HAD GONE STALE AND WAS THEREFORE WORSE THAN
# NOTHING. The version published at /docs/ described the ten Wave-0
# seller/supplier endpoints - every one of which was retired on 2026-07-23 and
# now 404s - and described NONE of the nineteen endpoints that actually work.
# A partner following it would have integrated against endpoints that do not
# exist while never learning about the ones that do.
#
# The source of truth for what is callable is
# src/main/resources/partner/partner-endpoint-scopes.properties: an endpoint
# NOT in that file is denied, whatever this document says. When that file
# changes, this one must change in the same commit.
# =============================================================================

info:
  title: eqomOS Partner API
  version: "1.0"
  # Sidebar header logo. Redoc renders info.x-logo at the top of the (dark) left
  # sidebar; backgroundColor gives the wordmark a white backing so the navy
  # eqomOS mark stays legible. Self-hosted next to this file (served at /docs/),
  # not hotlinked, so the portal has no runtime dependency on eqomos.com.
  # No href on purpose: the logo is branding, not a link. Redoc renders it as a
  # plain <img> when href is absent, so clicking it keeps the reader on the docs
  # page instead of leaving for the corporate site.
  x-logo:
    url: eqomos-logo.png
    altText: eqomOS
    backgroundColor: "#FFFFFF"
  description: |
    The headless commerce API behind eqomOS storefronts. A partner builds its own
    frontend against these endpoints and performs back-office work in the eqomOS
    admin application.

    ## Two credentials, two questions

    Every call carries a **partner credential** answering *which application is
    this*. Calls that act on behalf of a shopper additionally carry a **customer
    token** answering *whose data is this*. Neither substitutes for the other.

    ```
    X-Api-Key:        <your api key>
    Authorization:    Bearer <partner access token>     # from POST /auth/token
    X-Customer-Token: <shopper's web JWT>               # customer-scoped endpoints only
    ```

    ## Tenancy is not something you send

    Your tenant comes from your partner record. If you are mapped to exactly one
    tenant you cannot name one at all. If you are mapped to several you may send
    `siteMasterId`, and a tenant outside your mapping is **refused** - never
    silently swapped for your default.

    ## Identifiers are parameters, never path segments

    `/geo/states?countryId=101`, not `/geo/states/101`. Authorisation resolves the
    scope by an exact URI match, so an id in the path makes the request unmapped
    and therefore denied.

    ## Rate limits

    Per-partner, returned on every response as `X-RateLimit-Limit`,
    `X-RateLimit-Remaining` and `X-RateLimit-Reset`. A `429` carries `Retry-After`.

    They report the **tightest** tier - whichever of per-minute/hour/day/month has least
    headroom right now, because that is the one that will actually stop you. If your
    credential has no configured limit the headers are absent rather than invented.

    ## Every response carries X-Request-Id

    Quote it in any support request. It is the only handle on a deliberately
    opaque rejection.

    ## Quick start

    1. `POST /auth/token` with your `apiKey` + `apiSecret` -> a 15-minute `accessToken`.
    2. Send `X-Api-Key` and `Authorization: Bearer <accessToken>` on every call.
    3. For a shopper's own data (profile, cart, wishlist, orders, checkout) also send
       `X-Customer-Token` - the shopper's web JWT from `POST /customer/auth/login`.

    ## Scopes

    Your credential is granted a set of scopes; an endpoint you lack the scope for is
    `403 E_SCOPE`. The scopes in play:

    | Scope | Grants |
    |---|---|
    | `catalog:read` | catalogue, search, product pages, brands, banners |
    | `geo:read` | countries / states / cities / pincode + reference vocabularies |
    | `customer:auth` | register, login, OTP, password reset (mints the customer token) |
    | `customer:profile:read` | the shopper's account, addresses, points, cards, reviews |
    | `customer:profile:write` | manage the shopper's addresses; change password |
    | `cart:read` / `cart:write` | read / modify the shopper's cart |
    | `wishlist:read` / `wishlist:write` | read / modify the shopper's wishlist |
    | `orders:customer:read` | the shopper's own orders + order confirmation |
    | `orders:customer:write` | cancel / return-replacement the shopper's own order (request; back-office settles the refund) |
    | `checkout:read` | payment / shipping options, voucher validation |
    | `checkout:write` | place the shopper's order (prepaid or COD) |

    ## Signing a shopper in is two steps on an OTP tenant

    On a tenant with OTP login (which includes The Maharaja Shop, site 4):

    1. `POST /customer/auth/check` with the credential - verifies the password **and
       sends the login OTP**, returning a resend timer.
    2. `POST /customer/auth/login` with the same credential **plus the `otp`** - returns
       the `JWT` you use as `X-Customer-Token`.

    OTP delivery depends on the tenant having SMS enabled; where it is off the code is
    generated but not sent.

    ## Webhooks

    We POST an event to a URL you register in the admin console. **They are not enabled by
    registering** - an endpoint is created SUSPENDED and an operator activates it.

    ### Verify every delivery

    ```
    X-Eqomos-Event:      order.status.changed
    X-Eqomos-Event-Id:   <uuid>
    X-Eqomos-Timestamp:  <unix seconds>
    X-Eqomos-Signature:  t=<ts>,v1=<hex HMAC-SHA256>
    ```

    The MAC covers **`<timestamp> + "." + <raw body>`**, keyed with your **webhook secret**
    (shown once, alongside the API secret, when a credential is issued). Compute it over the
    RAW body before any JSON parsing, and compare in constant time.

    **Reject a delivery whose `X-Eqomos-Timestamp` is more than 5 minutes old.** The timestamp
    is inside the signed string precisely so you can: without that check a captured delivery
    can be replayed at you forever.

    ### Three properties you must design for

    | | |
    |---|---|
    | **At-least-once** | Retries mean duplicates. **Dedupe on `X-Eqomos-Event-Id`** - it is stable across every retry of the same occurrence. |
    | **No ordering** | Two status changes a second apart can arrive out of order. Every payload carries the authoritative state plus `occurredAt`; drop anything staler than what you hold. |
    | **Thin payloads** | You get the event, the resource id and the field that changed - then `GET` the resource for detail. Nothing in the payload is data you could not already fetch. |

    ### Retries

    `2xx` is success. **`4xx` is terminal** - we take it as "you will never accept this" and stop
    (except `408` and `429`, which retry). `5xx` and timeouts retry **6 times over about 24
    hours**: 1m, 5m, 30m, 2h, 6h, 12h. After that the delivery is dead-lettered and visible to
    our operators, who can replay it. An endpoint that fails repeatedly is auto-suspended.

    Connect timeout 3s, response timeout 10s - a slow endpoint is treated as a failure.

    ### Rotating your webhook secret, without missing an event

    Issuing a new credential **revokes nothing**, so both are live at once:

    1. Issue a new credential; you receive a new webhook secret.
    2. **Accept EITHER secret** - try the new one, fall back to the old - until step 3.
    3. Ask us to revoke the old credential.

    We always sign with your newest active secret, so step 2 is what makes the cutover seamless.

servers:
  - url: https://ns-multiclientapi.dealyug.com/v1
    description: Production

tags:
  - name: Authentication
    description: Mint the access token every other call presents.
  - name: Catalog
    description: Home, search, listing, product pages, brands, banners. Scope `catalog:read`.
  - name: Geo
    description: Countries / states / cities / pincode. Global reference data. Scope `geo:read`.
  - name: Reference
    description: Lookup vocabularies (cancel reasons, group values). Scope `geo:read`.
  - name: Customer Identity
    description: Register, login, OTP and password reset. These mint the customer token.
  - name: Customer Profile
    description: The signed-in shopper's account, addresses, points, cards, reviews.
  - name: Cart & Wishlist
    description: Read and modify the signed-in shopper's cart and wishlist.
  - name: Orders
    description: The signed-in shopper's own orders, tracking and photos.
  - name: Checkout
    description: Payment / shipping options and voucher validation (reads only; no order placement).

x-tagGroups:
  - name: Getting started
    tags: [Authentication]
  - name: Browse (no shopper needed)
    tags: [Catalog, Geo, Reference]
  - name: Shopper account
    tags: [Customer Identity, Customer Profile, Cart & Wishlist, Orders, Checkout]

# -----------------------------------------------------------------------------
security:
  - PartnerKey: []
    PartnerToken: []

components:
  securitySchemes:
    PartnerKey:
      type: apiKey
      in: header
      name: X-Api-Key
      description: Your API key. Public in the sense a username is - it identifies, it does not authenticate.
    PartnerToken:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 15-minute access token from `POST /auth/token`. Signed with a key unique to your credential.
    CustomerToken:
      type: apiKey
      in: header
      name: X-Customer-Token
      description: |
        The shopper's web JWT, for customer-scoped endpoints only.

        Sent as a **header, never a cookie**: a cross-origin API that authenticated
        from a cookie would inherit a CSRF problem on every state-changing route.

        It is checked against your tenant, against the session revocation list, and
        against the stored customer record. An expired one is expired - there is no
        refresh flow here; re-authenticate the shopper.

  responses:
    Unauthorized:
      description: |
        Authentication failed. **Deliberately uniform** across unknown key, wrong
        signature, expired token and mismatched claims - each distinction would be an
        oracle. The real reason is recorded server-side against your `X-Request-Id`.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
          example: { status: FAIL, message: "Request could not be authorized.", response: { code: E_AUTH } }
    CustomerUnauthorized:
      description: |
        Your credential is fine; the **shopper's** token is missing, expired or
        revoked. A distinct code on purpose - retrying your own credential will not
        help, you need to re-authenticate the shopper.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
          example: { status: FAIL, message: "A valid customer token is required for this endpoint. Send it in the X-Customer-Token header.", response: { code: E_CUSTOMER_AUTH } }
    Forbidden:
      description: |
        Your credential does not hold the scope this endpoint requires, your source
        IP is not in your allowlist, or you named a tenant you are not mapped to.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
          examples:
            scope:  { value: { status: FAIL, message: "This credential is not authorized for this endpoint.", response: { code: E_SCOPE } } }
            tenant: { value: { status: FAIL, message: "This credential is not authorized for the requested tenant.", response: { code: E_TENANT } } }
    NotFound:
      description: |
        No such resource **for you**. A record belonging to another tenant answers
        exactly like one that does not exist - telling them apart would let a caller
        enumerate another tenant's catalogue.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
          example: { status: FAIL, message: "Not found.", response: { code: E_NOT_FOUND } }
    TooMany:
      description: Rate limit exceeded. See `Retry-After`.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Error" }
          example: { status: FAIL, message: "Rate limit exceeded. Please retry later.", response: { code: E_QUOTA } }
    RateLimited:
      description: |
        Too many failed authentication attempts **for this shopper**.

        This is NOT the same limiter as the `E_QUOTA` 429 above, and the difference
        matters when you handle it:

        - **`E_QUOTA`** counts every call your credential makes, across all your
          shoppers. Back off globally.
        - **this one** counts failed sign-in attempts for ONE account, on YOUR
          partner id: 5 in a 60-second window. Other shoppers are unaffected and a
          successful sign-in clears it immediately. Retrying the same account with
          the same password will not help; show the user an error.

        It is keyed on the account rather than your source address on purpose -
        every one of your shoppers reaches us from the same server IP, so an
        address-based counter would let five unrelated failures lock out your
        entire customer base.
      content:
        application/json:
          schema: { $ref: "#/components/schemas/Envelope" }
          example: { status: FAIL, message: "Too many login attempts. Please try again later.", response: null }

  schemas:
    Envelope:
      type: object
      description: Every endpoint answers in this envelope. Check `status`, not the HTTP code alone.
      properties:
        status:  { type: string, enum: [SUCCESS, FAIL] }
        message: { type: string, nullable: true }
        response: { description: Endpoint-specific payload; null on failure }
    Error:
      allOf:
        - $ref: "#/components/schemas/Envelope"
        - type: object
          properties:
            response:
              type: object
              properties:
                code:      { type: string, enum: [E_AUTH, E_CUSTOMER_AUTH, E_SCOPE, E_TENANT, E_QUOTA, E_NOT_FOUND] }
                requestId: { type: string }

  parameters:
    SiteMasterId:
      name: siteMasterId
      in: query
      required: false
      schema: { type: integer, format: int64 }
      description: |
        Only meaningful for a partner mapped to SEVERAL tenants. Omit it and your
        default tenant is used. A tenant outside your mapping is refused.
    SkuId:
      name: skuId
      in: query
      required: true
      schema: { type: integer, format: int64 }
      description: |
        A SKU on **your** tenant. One belonging to another tenant answers `404`,
        identically to one that does not exist.

paths:
  /auth/token:
    post:
      tags:
      - Authentication
      summary: Exchange your API key + secret for a 15-minute access token
      description: 'The only endpoint that takes no token — it mints the one every other call presents. Throttled per IP and
        key. There is no refresh token by design: a short TTL plus a cheap re-mint beats a refresh lifecycle.'
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
            example:
              apiKey: pk_live_...
              apiSecret: sk_live_...
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Token issued.
                response:
                  accessToken: eyJhbGciOiJIUzI1NiJ9...
                  tokenType: Bearer
                  expiresIn: 900
                  scopes:
                  - catalog:read
                  - geo:read
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/categories:
    post:
      tags:
      - Catalog
      summary: Category tree for your tenant (header / footer navigation)
      description: '**Scope `catalog:read`.** The full published category hierarchy for your tenant. Tenant-scoped by the
        platform — no id is sent.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - &id001
        $ref: '#/components/parameters/SiteMasterId'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  rootParentCategoryByOrder:
                    '518':
                    - 519
                    '95':
                    - 319
                    '458':
                    - 355
                    '492':
                    - 493
                    '133':
                    - 184
                    '121':
                    - 516
                    '291':
                    - 292
                    '523': []
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  rootCategoryByOrder:
                  - 518
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/home:
    post:
      tags:
      - Catalog
      summary: Home-page composition
      description: '**Scope `catalog:read`.** Everything the storefront home page renders: featured rails, banners and blocks
        for your tenant.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  bannerList1:
                  - id: 35
                    type: HOME_ADVERTISE_1
                    name: Air India Merchandise
                    skuId: 0
                    langId: 7066
                    langCode: en
                    langName: English
                    sku: null
                  homeRootIds:
                  - ''
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  rootCategoryByOrder:
                  - 518
                  brandList:
                  - id: 47
                    name: Marks And Spencer
                    image: Image Not Available.jpg
                    description: Marks And Spencer
                    isactive: 1
                    sequenceNo: 1
                    active: 'YES'
                    cd: null
                  langList:
                  - code: en
                    value: English
                    cd: null
                  bannerList3:
                  - id: 23
                    type: HOME_ADVERTISE_3
                    name: HeroBanner-1
                    skuId: 0
                    langId: 7066
                    langCode: en
                    langName: English
                    sku: null
                  bannerList2:
                  - id: 26
                    type: HOME_ADVERTISE_2
                    name: Headphones- Travel
                    skuId: 0
                    langId: 7066
                    langCode: en
                    langName: English
                    sku: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/banners:
    post:
      tags:
      - Catalog
      summary: Promotional banners
      description: '**Scope `catalog:read`.** Banners for a placement. Pass `type` (e.g. `HOME`).'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: type
        in: query
        required: false
        schema:
          type: string
        description: Banner placement, e.g. HOME.
        example: HOME
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Success
                response:
                - id: 36
                  type: HOME
                  name: ADIDAS INDIA
                  skuId: 0
                  langId: 7066
                  langCode: en
                  langName: English
                  sku: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/new-trends:
    post:
      tags:
      - Catalog
      summary: “New trends” rail
      description: '**Scope `catalog:read`.** The curated new-arrivals rail for your tenant.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: The record not found
                response: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/top-offers:
    post:
      tags:
      - Catalog
      summary: “Top offers” rail
      description: '**Scope `catalog:read`.** The curated offers rail for your tenant.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: The record not found
                response: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/brands:
    post:
      tags:
      - Catalog
      summary: Brands on your tenant
      description: '**Scope `catalog:read`.** Every brand published on your tenant.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  webCartYouSave: 0.0
                  webCartTotalPayable: 0.0
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  brandList:
                  - id: 6
                    name: Wildcraft
                    image: 6_29052026151447.jpg
                    description: Wildcraft
                    isactive: 1
                    sequenceNo: 1
                    active: 'YES'
                    cd: null
                  langList:
                  - code: en
                    value: English
                    cd: null
                  totalAccuralPoints: 0
                  webCartTotalItems: 0
                  webCartShippingCost: 0.0
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/brands-by-category:
    post:
      tags:
      - Catalog
      summary: Brands within a category
      description: '**Scope `catalog:read`.** Brands that have products in a category. Pass `catId`.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: catId
        in: query
        required: true
        schema:
          type: integer
        description: Category id on your tenant.
        example: 84
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                - id: 6
                  name: Wildcraft
                  image: 6_29052026151447.jpg
                  description: Wildcraft
                  isactive: 1
                  sequenceNo: 1
                  active: 'YES'
                  cd: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/search:
    post:
      tags:
      - Catalog
      summary: Search products
      description: '**Scope `catalog:read`.** Keyword / category search. `filter`, `page` and sort are parameters on this
        endpoint — there is no separate filter or sort route.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: cat
        in: query
        required: false
        schema:
          type: integer
        description: Restrict to a category id.
        example: 84
      - name: query
        in: query
        required: false
        schema:
          type: string
        description: Search text.
        example: watch
      - name: page
        in: query
        required: false
        schema:
          type: integer
        description: 1-based page number.
        example: 1
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  prductList:
                    draw: 0
                    recordsTotal: 613
                    recordsFiltered: 613
                    data:
                    - skuId: 1061
                      skuCode: NUC-3
                      skuName: Noize Ultimate Combo - 3.1kg
                      offerPrice: 8047.0
                      offerMrp: 9897.0
                      images:
                      - Noize-Ultimate-Combo---3-1kg-1-1780755640402.jpg
                      wsBean: []
                      currentInventory: 29999
                    recordPerPage: 24
                    currentPageNo: 1
                    filtterMap: null
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  homePageSliderDefData:
                  - id: 16
                    slidertype: 800
                    slidertypename: SLIDER
                    siteMasterId: null
                    siteMasterName: null
                    slidername: null
                    slidercode: SL2
                    sliderdisplayname: Technology Curated For Modern Travel
                  langList:
                  - code: en
                    value: English
                    cd: null
                  pageName: catelog
                  categoryBannerMap: null
                  prductFiltter:
                    proudctSizeFiltter:
                    - key: 0
                      value: null
                      count: 155
                    skuVarinatColorFiltter:
                    - key: 3048
                      value: Anchor Blue
                      code: 1598_color1781592325829.jpg
                      count: 1
                    proudctBrandFiltter:
                    - key: 1
                      value: Apple
                      count: 232
                    minMaxPrice:
                    - key: null
                      value: '246221.0'
                      cd: null
                    supplyType:
                    - key: 7078
                      value: Stock
                      cd: null
                    proudctTagFiltter:
                    - key: 1
                      value: Maharaja Picks
                      count: 1
                    proudctColorFiltter:
                    - key: 0
                      value: null
                      count: 155
                    proudctCategoryFiltter:
                    - key: 39
                      value: AirPods Pro 3
                      count: 1
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/listing:
    post:
      tags:
      - Catalog
      summary: Category / filtered listing with paging + sort
      description: '**Scope `catalog:read`.** The listing grid. **Filtering, sorting and “load more” are all parameters here**
        (`filter`, `page`, `totalRecord`), not separate endpoints.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: filter
        in: query
        required: false
        schema:
          type: string
        description: Filter expression, e.g. `cat=84`.
        example: cat=84
      - name: page
        in: query
        required: false
        schema:
          type: integer
        description: 1-based page number.
        example: 1
      - name: totalRecord
        in: query
        required: false
        schema:
          type: integer
        description: Page size.
        example: 12
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  langList:
                  - code: en
                    value: English
                    cd: null
                  categoryBannerMap: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/autocomplete:
    post:
      tags:
      - Catalog
      summary: Search autocomplete suggestions
      description: '**Scope `catalog:read`.** Type-ahead suggestions for a partial query.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: query
        in: query
        required: true
        schema:
          type: string
        description: Partial search text.
        example: wat
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  ProductData:
                  - key: 1222
                    value: Men Polo Collar T-Shirts Test Black S
                    cd: null
                  CategoryData:
                  - parentName: Air India Merchandise
                    rootId: 0
                    displayName: T-shirts
                    rootName: null
                    name: Tshirts
                    id: 520
                    key: 520
                    parentId: 518
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/product-detail:
    post:
      tags:
      - Catalog
      summary: Full detail for one SKU (product page)
      description: '**Scope `catalog:read`.** The SKU must be on your tenant; a foreign or unknown id answers `404` identically.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - &id002
        $ref: '#/components/parameters/SkuId'
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  id: 912
                  mainSkuId: 0
                  mainProductId: null
                  productCode: AWMIX450
                  productName: Aiwa MI-X450 Pro Enigma high Efficiency Audio Speaker with Retro Styling - Rose Gold
                  isapproved: 1
                  sellerId: 11
                  sellerName: ZRPL
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/product-async:
    post:
      tags:
      - Catalog
      summary: Deferred product-page data
      description: '**Scope `catalog:read`.** Flash offers and size/colour options, split out so the page can render first.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id002
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  isFlashSale: false
                  sizeTypes:
                  - key: 7062
                    value: UK
                    cd: null
                  langList:
                  - code: en
                    value: English
                    cd: null
                  stock: true
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/product-gallery:
    post:
      tags:
      - Catalog
      summary: Product image gallery
      description: '**Scope `catalog:read`.** Gallery images for a SKU on your tenant.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id002
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  skuName: Aiwa MI-X450 Pro Enigma high Efficiency Audio Speaker with Retro Styling - Rose Gold
                  skuGalleryList: []
                  skuId: 912
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/product-learn-more:
    post:
      tags:
      - Catalog
      summary: “Learn more” rich content
      description: '**Scope `catalog:read`.** Long-form marketing content blocks for a SKU.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id002
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  skuName: Aiwa MI-X450 Pro Enigma high Efficiency Audio Speaker with Retro Styling - Rose Gold
                  stagSkuSpecificationBeans: []
                  skuDetailsBean:
                    id: 898
                    skuId: 912
                    skuName: Aiwa MI-X450 Pro Enigma high Efficiency Audio Speaker with Retro Styling - Rose Gold
                    description: <p>120W portable speaker with deep bass and immersive sound powered by a 22500mAh batter…
                    warranty: 120W portable speaker with deep bass dual wireless microphones multiple connectivity opt…
                    sizeChart: null
                    videoLink: ''
                    title: ''
                  skuLearnMoreList: []
                  skuId: 912
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/product-static-content:
    post:
      tags:
      - Catalog
      summary: Static product content
      description: '**Scope `catalog:read`.** Static spec / description content for a SKU.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id002
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record added successfully.
                response:
                  skuId: 101
                  staticContent: <h3>Product care</h3><p>Wipe with a soft, dry cloth. Avoid moisture.</p>
                  contentType: LEARN_MORE
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooMany'
  /geo/countries:
    get: &id003
      tags:
      - Geo
      summary: Countries
      description: '**Scope `geo:read`.** Global reference data — identical for every tenant.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                - id: 101
                  code: IN
                  name: India
                  isactive: true
                  flagimage: null
                  mobilecode: '91'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
    post: *id003
  /geo/countries-detail:
    get: &id004
      tags:
      - Geo
      summary: Countries with dialling / ISO detail
      description: '**Scope `geo:read`.** Countries with ISO codes and dialling prefixes.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  countriesList:
                  - key: 101
                    value: India
                    cd: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
    post: *id004
  /geo/states:
    get: &id005
      tags:
      - Geo
      summary: States of a country
      description: '**Scope `geo:read`.** Pass `countryId` as a parameter, never a path segment.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: countryId
        in: query
        required: true
        schema:
          type: integer
        description: Country id.
        example: 101
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Success
                response:
                - id: 1
                  code: AN
                  name: Andaman And Nicobar Islands
                  countryId: 101
                  country: India
                  isactive: true
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
    post: *id005
  /geo/cities:
    get: &id006
      tags:
      - Geo
      summary: Cities of a state
      description: '**Scope `geo:read`.** Pass `stateId`.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: stateId
        in: query
        required: true
        schema:
          type: integer
        description: State id.
        example: 1
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Success
                response:
                - id: 1056
                  stateId: 1
                  state: Andaman And Nicobar Islands
                  code: CBD
                  name: Nicobar
                  isactive: true
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
    post: *id006
  /geo/pincode:
    get: &id007
      tags:
      - Geo
      summary: Resolve a pincode to country / state / city
      description: '**Scope `geo:read`.** Look up an address from a postcode. Pass `pincode`.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: pincode
        in: query
        required: true
        schema:
          type: string
        description: Postal code.
        example: '400709'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Success
                response:
                  pincode: '400709'
                  city: Navi Mumbai
                  stateName: Maharashtra
                  stateId: '21'
                  pincodeId: '15092'
                  cityId: '1042'
                  countryName: India
                  countryId: '101'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
    post: *id007
  /geo/city-area:
    get: &id008
      tags:
      - Geo
      summary: Areas / localities of a city
      description: '**Scope `geo:read`.** Pass `cityId`.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: cityId
        in: query
        required: true
        schema:
          type: integer
        description: City id.
        example: 1
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Success
                response:
                - id: 1
                  cityId: 1
                  city: Abohar
                  regionId: 21
                  region: WEST
                  pincode: '152116'
                  isactive: true
                  countryId: 101
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
    post: *id008
  /reference/group-values:
    post:
      tags:
      - Reference
      summary: Values of a lookup group
      description: '**Scope `geo:read`.** Neutral reference vocabularies (kept under `geo:read`, not the commercial catalogue
        scope). Pass `groupname`.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: groupname
        in: query
        required: true
        schema:
          type: string
        description: Lookup group name.
        example: CANCEL_ORDER
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  type:
                  - key: 109
                    value: Customer Wants Order Cancellation
                    cd: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /reference/group-subtypes:
    post:
      tags:
      - Reference
      summary: Sub-types of a lead / group type
      description: '**Scope `geo:read`.** Pass `leadTypeId`.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: leadTypeId
        in: query
        required: true
        schema:
          type: integer
        description: Lead / group type id.
        example: 109
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  subtype:
                  - key: 144
                    value: Customer Has Dropped His Plan
                    cd: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /reference/cancel-reasons:
    post:
      tags:
      - Reference
      summary: Order cancellation reasons
      description: '**Scope `geo:read`.** The cancellation-reason vocabulary for order flows.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  reasons:
                  - key: 144
                    value: Customer Has Dropped His Plan
                    cd: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/auth/check:
    post:
      tags:
      - Customer Identity
      summary: Step 1 of OTP login — verify the password and send the login OTP
      description: '**Scope `customer:auth`.** On an OTP tenant this is **step 1** of signing in: it verifies the password
        and, if correct, generates a one-time code, stores it against the shopper and sends it by SMS, returning a resend
        timer. It starts no session — follow with `/customer/auth/login` (step 2). ⚠️ Identify the shopper by `loginUserName`
        here (not `emailid`/`mobileno`). ⚠️ It answers identically for wrong password and unknown account, so it cannot enumerate
        accounts. ⚠️ Where SMS delivery is disabled the code is stored but not sent, and login cannot complete.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                webUserBean:
                  type: string
                  description: A JSON string carrying the shopper fields.
            example:
              webUserBean: '{"loginUserName":"9876500000","password":"S3cret!"}'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              examples:
                accepted:
                  summary: Credentials accepted, OTP sent
                  value:
                    status: SUCCESS
                    message: OTP has been sent on your registered mobile number.
                    response:
                      resendAfterSeconds: 30
                rejected:
                  summary: Credentials rejected
                  value:
                    status: FAIL
                    message: Invalid email or password
                    response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /customer/auth/login:
    post:
      tags:
      - Customer Identity
      summary: Step 2 of OTP login — submit the OTP, receive the customer token
      description: '**Scope `customer:auth`.** Signing in is a two-step flow on an OTP tenant (which includes site 4). Call
        `/customer/auth/check` first (it sends the OTP), then call this with the same credential plus the `otp`. On a non-OTP
        tenant, call this directly with just the password. Identify the shopper by `emailid` or `mobileno`. On success the
        response carries the `JWT` you send as `X-Customer-Token` on every customer-bound route.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                webUserBean:
                  type: string
                  description: A JSON string carrying the shopper fields.
            example:
              webUserBean: '{"mobileno":"9876500000","password":"S3cret!","otp":"483920"}'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              examples:
                success:
                  summary: Signed in — token issued
                  value:
                    status: SUCCESS
                    message: Success
                    response:
                      JWT: eyJhbGciOiJIUzUxMiJ9.<web-jwt>
                      JWT_WEB_REFRESH_TOKEN: eyJhbGciOiJIUzUxMiJ9.<refresh>
                      JWT_WEB_REFRESH_EXPIRY: 10800
                      webUserBean:
                        id: 89
                        name: Partner Test
                otp_missing:
                  summary: OTP not supplied (call /check first)
                  value:
                    status: FAIL
                    message: Please enter OTP.
                    response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /customer/auth/register:
    post:
      tags:
      - Customer Identity
      summary: Register a new shopper on your tenant
      description: '**Scope `customer:auth`.** Creates a shopper and starts OTP verification. The tenant is stamped server-side.
        Throttled (registration is otherwise an enumeration oracle). Site 4 additionally requires a membership id downstream.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
            example:
              name: Partner Test
              emailid: shopper@example.com
              mobileno: '9876500000'
              password: S3cret!
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              examples:
                success:
                  summary: Created — OTP sent
                  value:
                    status: SUCCESS
                    message: Dear User, OTP is forwarded to your Registered Mobile number. OTP will expire in 5 minutes
                    response:
                      webUserBean:
                        id: 89
                        name: Partner Test
                        emailid: shopper@example.com
                        mobileno: '9876500000'
                        isOtpVerificationRequired: true
                      otpResendIntervalSeconds: 30
                      otpResendRemainingSeconds: 30
                invalid:
                  summary: Validation / precondition failure
                  value:
                    status: FAIL
                    message: Invalid data found, Please enter valid data
                    response:
                      password: Your password must be at least 8 characters long and include uppercase, lowercase, number,
                        and special character. Avoid sequences (e.g., 1234, abcd), repeated characters (e.g., 1111), and previously
                        compromised passwords.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /customer/auth/otp/send:
    post:
      tags:
      - Customer Identity
      summary: Send a signup OTP
      description: '**Scope `customer:auth`.** Throttled — it sends messages. SMS delivery is tenant-dependent.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                webUserBean:
                  type: string
                  description: A JSON string carrying the shopper fields.
            example:
              webUserBean: '{"mobileno":"9876500000","emailid":"shopper@example.com"}'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Something went wrong
                response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /customer/auth/otp/verify:
    post:
      tags:
      - Customer Identity
      summary: Verify a signup OTP
      description: '**Scope `customer:auth`.** Throttled — an unthrottled six-digit check is brute-forceable.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                webUserBean:
                  type: string
                  description: A JSON string carrying the shopper fields.
            example:
              webUserBean: '{"mobileno":"9876500000","otp":"483920"}'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: OTP is invalid, Please enter valid OTP
                response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /customer/auth/password/forgot:
    post:
      tags:
      - Customer Identity
      summary: Start a password reset
      description: '**Scope `customer:auth`.** Sends a reset code. Answers the same for a known and an unknown address (enumeration-safe)
        and does not change the existing password.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
            example:
              loginUserName: '9876500000'
              mobileno: '9876500000'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Reset password link send on your provided email.
                response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /customer/auth/password/reset:
    post:
      tags:
      - Customer Identity
      summary: Complete a password reset
      description: '**Scope `customer:auth`.** Finds the shopper by the reset OTP and sets the new password. Replay is refused.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
            example:
              mobileno: '9876500000'
              otp: '483920'
              password: N3wpass!
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: User Account does not exist. Please enter a valid username. OR maybe you are using an in…
                response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '429':
          $ref: '#/components/responses/RateLimited'
  /customer/auth/logout:
    get: &id009
      tags:
      - Customer Identity
      summary: Log the shopper out (revoke the customer token)
      description: '**Scope `customer:auth`.** Send the shopper''s `X-Customer-Token`; the session behind it is revoked immediately.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: logout successfully.
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
    post: *id009
  /customer/profile:
    post:
      tags:
      - Customer Profile
      summary: The authenticated shopper's own account
      description: '**Scope `customer:profile:read`.** Requires `X-Customer-Token`. No user id is accepted — the shopper is
        derived from the token, so this can only return the caller''s own account.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  langList:
                  - code: en
                    value: English
                    cd: null
                  categoryBannerMap: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/addresses:
    post:
      tags:
      - Customer Profile
      summary: The shopper's saved addresses
      description: '**Scope `customer:profile:read`.** Requires `X-Customer-Token`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  userAddressListData:
                  - id: 92
                    pincodeId: 1
                    pincode: '152116'
                    userId: 49
                    userName: Shopper
                    name: COD Test Addr
                    mobileno: '9876500000'
                    phoneno: null
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  userAddressListDataStr: '[{"id":92,"pincodeId":1,"pincode":"152116","userId":49,"userName":"Shopper","name":"COD
                    Te…'
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  langList:
                  - code: en
                    value: English
                    cd: null
                  countryList:
                  - key: 101
                    value: India
                    cd: null
                  categoryBannerMap: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/points:
    post:
      tags:
      - Customer Profile
      summary: Loyalty points balance / history
      description: '**Scope `customer:profile:read`.** Requires `X-Customer-Token`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  categoryBannerMap: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/cards:
    post:
      tags:
      - Customer Profile
      summary: The shopper's saved cards
      description: '**Scope `customer:profile:read`.** Requires `X-Customer-Token`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  payrocJstokenUrl: null
                  langList:
                  - code: en
                    value: English
                    cd: null
                  countryList:
                  - key: 101
                    value: India
                    cd: null
                  categoryBannerMap: null
                  storeCardList: []
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/reviews:
    post:
      tags:
      - Customer Profile
      summary: Reviews the shopper has written
      description: '**Scope `customer:profile:read`.** Requires `X-Customer-Token`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  langList:
                  - code: en
                    value: English
                    cd: null
                  categoryBannerMap: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/cart:
    post:
      tags:
      - Cart & Wishlist
      summary: The shopper's cart
      description: '**Scope `cart:read`.** Requires `X-Customer-Token`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  webCartYouSave: 0.0
                  webCartTotalPayable: 0.0
                  webCartTotalPayableWithGV: null
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  noofsku: '50'
                  langList:
                  - code: en
                    value: English
                    cd: null
                  totalAccuralPoints: 0
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/header:
    post:
      tags:
      - Cart & Wishlist
      summary: Header summary (cart + wishlist counts)
      description: '**Scope `cart:read`.** Requires `X-Customer-Token`. The small counts a storefront header shows.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  webCartShippingCost: 0.0
                  webCartYouSave: 0.0
                  webCartTotalPayable: 0.0
                  wishlistTotalItems: 9
                  webCartSkuQtyMap: {}
                  webCartTotalAmount: 0.0
                  webCartSkuImageMap: {}
                  totalAccuralPoints: 0
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/cart/add:
    post:
      tags:
      - Cart & Wishlist
      summary: Add a SKU to the cart
      description: '**Scope `cart:write`.** Requires `X-Customer-Token`. Name a **variant** SKU in `skuList`, not a parent
        grouping SKU. `parentSkuId` must be the SKU being bought - a variant is added by its own id, the same id in `parentSkuId`
        and in `skuList` - and a line whose `skuList` names a different SKU is refused with `CART_LINE_SKU_MISMATCH` (`200`
        with a `FAIL` envelope, not an error status).'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
            example:
              parentSkuId: 914
              skuList:
              - skuId: 914
                qty: 1
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              examples:
                added:
                  summary: Added to the cart
                  value:
                    status: SUCCESS
                    message: Record updated successfully.
                    response:
                      id: null
                      parentSkuId: 914
                      parentSkuName: null
                      skuId: null
                      skuName: null
                      userId: 49
                      userName: null
                      useremailid: shopper@example.com
                sku_mismatch:
                  summary: Refused - skuList names a SKU other than parentSkuId
                  value:
                    status: FAIL
                    message: This item could not be added to the cart. Please select the product option again and retry.
                    response:
                      code: CART_LINE_SKU_MISMATCH
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /customer/cart/remove:
    post:
      tags:
      - Cart & Wishlist
      summary: Remove a line from the cart
      description: '**Scope `cart:write`.** Requires `X-Customer-Token`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
            example:
              parentSkuId: 914
              skuList:
              - skuId: 914
                qty: 1
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record Deleted successfully.
                response:
                  id: null
                  parentSkuId: 914
                  parentSkuName: null
                  skuId: null
                  skuName: null
                  userId: 49
                  userName: null
                  useremailid: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /customer/cart/check-inventory:
    post:
      tags:
      - Cart & Wishlist
      summary: Is a SKU in stock in the quantity asked for?
      description: '**Scope `cart:write`.** Requires `X-Customer-Token`. The pre-flight a cart / checkout screen runs.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
            example:
              parentSkuId: 914
              quantity: 1
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Success
                response:
                  id: null
                  parentSkuId: 914
                  parentSkuName: null
                  skuId: null
                  skuName: null
                  userId: null
                  userName: null
                  useremailid: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /customer/wishlist:
    post:
      tags:
      - Cart & Wishlist
      summary: The shopper's wishlist
      description: '**Scope `wishlist:read`.** Requires `X-Customer-Token`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  userWishListData:
                    draw: 0
                    recordsTotal: 9
                    recordsFiltered: 9
                    data:
                    - id: null
                      parentSkuId: 1064
                      parentSkuName: Noize Creatine Monohydrate - 100g
                      offerprice: 789.0
                      skucode: NCM-100G
                      wuserId: null
                      wuserName: null
                      wuserMobileNo: null
                    recordPerPage: 24
                    currentPageNo: 1
                    filtterMap: null
                  langList:
                  - code: en
                    value: English
                    cd: null
                  categoryBannerMap: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/wishlist/add:
    post:
      tags:
      - Cart & Wishlist
      summary: Add a SKU to the wishlist
      description: '**Scope `wishlist:write`.** Requires `X-Customer-Token`. Send `parentSkuId` as a form parameter.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                parentSkuId:
                  type: integer
            example:
              parentSkuId: 914
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record added successfully.
                response:
                  id: null
                  parentSkuId: 914
                  parentSkuName: null
                  offerprice: 0.0
                  skucode: null
                  wuserId: 49
                  wuserName: null
                  wuserMobileNo: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /customer/wishlist/remove:
    post:
      tags:
      - Cart & Wishlist
      summary: Remove an entry from the wishlist
      description: '**Scope `wishlist:write`.** Requires `X-Customer-Token`. Send `parentSkuId` as a form parameter.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                parentSkuId:
                  type: integer
            example:
              parentSkuId: 914
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record Deleted successfully.
                response:
                  id: null
                  parentSkuId: 914
                  parentSkuName: null
                  offerprice: 0.0
                  skucode: null
                  wuserId: 49
                  wuserName: null
                  wuserMobileNo: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /customer/wishlist/update:
    post:
      tags:
      - Cart & Wishlist
      summary: Update a wishlist entry
      description: '**Scope `wishlist:write`.** Requires `X-Customer-Token`. Targets an existing wishlist entry by `parentSkuId`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
            example:
              parentSkuId: 914
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Error Fetching Record
                response:
                  id: null
                  parentSkuId: 914
                  parentSkuName: null
                  offerprice: 0.0
                  skucode: null
                  wuserId: 49
                  wuserName: null
                  wuserMobileNo: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /customer/orders:
    post:
      tags:
      - Orders
      summary: The shopper's own orders
      description: '**Scope `orders:customer:read`.** Requires `X-Customer-Token`. Lists only the caller''s orders.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  langList:
                  - code: en
                    value: English
                    cd: null
                  categoryBannerMap: null
                  webUserOrderListData:
                    draw: 0
                    recordsTotal: 10
                    recordsFiltered: 10
                    data:
                    - id: 488
                      grouporderid: AGS493
                      paymentorderid: AS338
                      paymentName: POSTPAID
                      offername: Apple TV 4K Wi-Fi with 64GB storage
                      repOrderId: null
                      sellerName: TeamsComputer
                      skuParentId: 1554
                    recordPerPage: 10
                    currentPageNo: 1
                    filtterMap: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/order-detail:
    post:
      tags:
      - Orders
      summary: One order in full
      description: '**Scope `orders:customer:read`.** Requires `X-Customer-Token`. Guarded: the `orderId` must belong to the
        caller, else `404`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - name: orderId
        in: query
        required: true
        schema:
          type: integer
        description: An order id belonging to the shopper.
        example: 181
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  langList:
                  - code: en
                    value: English
                    cd: null
                  showBillingSeparately: '0'
                  countryList:
                  - key: 101
                    value: India
                    cd: null
                  categoryBannerMap: null
                  webUserOrderListData: []
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/order-tracking:
    post:
      tags:
      - Orders
      summary: Tracking / status for an order
      description: '**Scope `orders:customer:read`.** Requires `X-Customer-Token`. Guarded on ownership of `orderId`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - name: orderId
        in: query
        required: true
        schema:
          type: integer
        description: An order id belonging to the shopper.
        example: 181
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  brands:
                  - id: 6
                    name: Wildcraft
                    image: 6_29052026151447.jpg
                    description: Wildcraft
                    isactive: 1
                    sequenceNo: 1
                    active: 'YES'
                    cd: null
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  orderId: 181
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  orders:
                  - - fromStatusId: 101
                      fromStatusName: New Order
                      toStatusId: 101
                      toStatusName: New Order
                      trackingName: New Order
                      trackingDate: 18 Jun 2026 08:18:55 PM
                      cd: 1781813935000
                  langList:
                  - code: en
                    value: English
                    cd: null
                  categoryBannerMap: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/order-photos:
    post:
      tags:
      - Orders
      summary: Delivery / product photos for an order
      description: '**Scope `orders:customer:read`.** Requires `X-Customer-Token`. Guarded on ownership of `orderId`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - name: orderId
        in: query
        required: true
        schema:
          type: integer
        description: An order id belonging to the shopper.
        example: 181
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  productPhotos: {}
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooMany'
  /checkout/payment-options:
    post:
      tags:
      - Checkout
      summary: Available payment methods
      description: '**Scope `checkout:read`.** Requires `X-Customer-Token`. Lists methods; moves no money.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Kindly Select Address
                response:
                - code: en
                  value: English
                  cd: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /checkout/shipping-options:
    post:
      tags:
      - Checkout
      summary: Available shipping methods
      description: '**Scope `checkout:read`.** Requires `X-Customer-Token`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  webCartYouSave: 0.0
                  webCartTotalPayable: 0.0
                  shippingMap:
                    '7263': 0
                    '7251': '30'
                    '7262': '0'
                    '7250': 0
                  isNonGvFlag: true
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  webCartTotalPayableWithGV: null
                  langList:
                  - code: en
                    value: English
                    cd: null
                  totalAccuralPoints: 0
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /checkout/payment-shipping-details:
    post:
      tags:
      - Checkout
      summary: Combined payment + shipping detail
      description: '**Scope `checkout:read`.** Requires `X-Customer-Token`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  webCartYouSave: 0.0
                  webCartTotalPayable: 0.0
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  langList:
                  - code: en
                    value: English
                    cd: null
                  totalAccuralPoints: 0
                  webCartTotalItems: 0
                  webCartShippingCost: 0.0
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /checkout/config:
    post:
      tags:
      - Checkout
      summary: Checkout configuration for the tenant
      description: '**Scope `checkout:read`.** Requires `X-Customer-Token`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  guest.autocreate.customer.enabled: '1'
                  guest.identity.match.mode: MOBILE
                  otp.length: '6'
                  otp.max.sends.per.hour: '5'
                  checkout.membership.required: '1'
                  otp.ttl.minutes: '5'
                  otp.max.attempts: '5'
                  guest.otp.required.existing.user: '1'
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /checkout/validate-voucher:
    post:
      tags:
      - Checkout
      summary: Validate a gift voucher (does not redeem)
      description: '**Scope `checkout:read`.** Requires `X-Customer-Token`. Reads the voucher and answers whether it is usable;
        redemption happens at payment.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
            example:
              gvName: YOURVOUCHER
              offerIds:
              - 1
              source: WEB
              siteMasterId: 4
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Something Went wrong, kindly refresh page then try again.
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
  /checkout/confirmation:
    get: &id010
      tags:
      - Checkout
      summary: Order confirmation (“thank you”) page
      description: '**Scope `orders:customer:read`.** Requires `X-Customer-Token`. Guarded: the `groupOrderId` must belong
        to the caller.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - name: groupOrderId
        in: query
        required: true
        schema:
          type: string
        description: A group order id belonging to the shopper.
        example: AGU181
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    salutation: ''
                    name: Shopper
                    lastName: Singh
                    mobileno: '9876500000'
                  categoryHierarchy:
                    '518':
                      '519': []
                      '520': []
                      '521': []
                    '95':
                      '319': []
                      '465': []
                      '466':
                      - '480'
                      '489': []
                      '490':
                      - '327'
                      '84':
                      - '326'
                    '458':
                      '355': []
                      '357': []
                      '517': []
                    '492':
                      '493':
                      - '495'
                      '499':
                      - '509'
                    '133':
                      '184': []
                      '515': []
                      '246': []
                    '121':
                      '516': []
                      '341': []
                      '385': []
                    '291':
                      '292': []
                    '523': {}
                  categoriesMap:
                    '472':
                      id: 472
                      name: Charging Accessories
                      displayName: Charging Accessories
                      description: Charging Accessories
                      catlevel: 1
                      seqno: 1
                      parentId: 468
                      parentName: Audio And Tech
                    '474':
                      id: 474
                      name: SmartPhones
                      displayName: SmartPhones
                      description: ''
                      catlevel: 1
                      seqno: 3
                      parentId: 468
                      parentName: Audio And Tech
                    '476':
                      id: 476
                      name: Health Care
                      displayName: Health Care
                      description: ''
                      catlevel: 1
                      seqno: 51
                      parentId: 475
                      parentName: Personal Care and Grooming
                    '355':
                      id: 355
                      name: Travel Accessories
                      displayName: Travel Accessories
                      description: ''
                      catlevel: 1
                      seqno: 55
                      parentId: 458
                      parentName: Travel
                    '477':
                      id: 477
                      name: Massager
                      displayName: Massager
                      description: ''
                      catlevel: 2
                      seqno: 197
                      parentId: 294
                      parentName: Health Devices
                    '510':
                      id: 510
                      name: Air Conditioner
                      displayName: Air Conditioner
                      description: ''
                      catlevel: 2
                      seqno: 207
                      parentId: 499
                      parentName: Home Appliances
                    '357':
                      id: 357
                      name: Luggage Trolleys
                      displayName: Luggage Trolleys
                      description: ''
                      catlevel: 1
                      seqno: 56
                      parentId: 458
                      parentName: Travel
                    '511':
                      id: 511
                      name: Washing Machine
                      displayName: Washing Machine
                      description: ''
                      catlevel: 2
                      seqno: 208
                      parentId: 499
                      parentName: Home Appliances
                  errMsg: Error in getting Order information, please try again
                  langList:
                  - code: en
                    value: English
                    cd: null
                  categoryBannerMap: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooMany'
    post: *id010
  /catalog/filter-listing:
    post:
      tags:
      - Catalog
      summary: Filtered / sorted product listing
      description: '**Scope `catalog:read`.** No customer token. Filtered, sorted, paged product listing (the jqx-grid filter
        view). Tenant-scoped and fail-closed; all filters are bound.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: false
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                q:
                  type: string
                  description: Free-text query.
                cat:
                  type: string
                  description: Category id.
                filter:
                  type: string
                  description: Filter expression, e.g. cat=84.
                page:
                  type: string
            example:
              q: watch
              page: '1'
      responses:
        '200':
          description: OK (datatable envelope)
          content:
            application/json:
              schema:
                type: object
              example:
                recordsTotal: 12
                recordsFiltered: 12
                data: []
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/product-components-by-ids:
    post:
      tags:
      - Catalog
      summary: Product card/component data for a set of SKU ids
      description: '**Scope `catalog:read`.** No customer token. Returns card/component data for the comma-separated `productId`
        SKU ids (for a partner-rendered "recently viewed" strip). Tenant-scoped: ids on another tenant are dropped.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                productId:
                  type: string
                  description: Comma-separated SKU ids.
              required:
              - productId
            example:
              productId: 101,102,103
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  recentViewGuestLogin: []
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/product-reviews:
    post:
      tags:
      - Catalog
      summary: Product reviews (anonymised)
      description: '**Scope `catalog:read`.** No customer token. Ratings and reviews for the SKU in `offerId`. Tenant-scoped
        (reviews for a SKU not on your tenant come back empty). Reviewer identity is NOT returned - reviews are anonymised
        to rating, title, text, likes and date.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                offerId:
                  type: string
                  description: A SKU id published on your tenant.
                page:
                  type: string
              required:
              - offerId
            example:
              offerId: '101'
              page: '1'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  reviewList:
                  - id: 88
                    rating: 5
                    title: Excellent quality
                    review: Looks premium and arrived on time.
                    likes: 3
                    dislikes: 0
                    cd: '2026-06-12 10:04:00'
                    wuserName: null
                    wuserId: null
                    wuserMobileNo: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/related-products:
    post:
      tags:
      - Catalog
      summary: Related products (you may also like)
      description: '**Scope `catalog:read`.** No customer token. Related products for the SKU in the `id` param (which is
        a SKU id). Guarded: the SKU must be published on your tenant, else `404`.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                id:
                  type: string
                  description: A SKU id published on your tenant.
              required:
              - id
            example:
              id: '101'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                - skuId: 205
                  skuCode: TM-WATCH-205
                  skuName: Classic Leather Strap Watch
                  offerPrice: 2499.0
                  offerMrp: 3999.0
                  images:
                  - /static/www/images/skuImages/205/205_1.jpg
                  isInventoryAvailable: true
                  currentInventory: 34
                  shortDescription: Analog watch with a genuine leather strap.
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The SKU is not published on your tenant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
  /catalog/sku-recipes:
    post:
      tags:
      - Catalog
      summary: Recipes attached to a SKU
      description: '**Scope `catalog:read`.** No customer token. Returns the recipe(s) for `skuId`. Guarded: the SKU must
        be published on your tenant, else `404`.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                skuId:
                  type: string
                  description: A SKU id published on your tenant.
              required:
              - skuId
            example:
              skuId: '101'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                - id: 12
                  skuId: 101
                  productTitle: Masala Chai
                  description: A spiced Indian milk tea.
                  imageName: /static/www/images/recipeimages/masala-chai.jpg
                  ingredients: Tea leaves, milk, ginger, cardamom, sugar
                  steps: Boil water with the spices, add tea and milk, simmer, then strain.
                  cookingtime: 10 mins
                  serve: '2'
                  mealTime: Morning
                  isactive: 1
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The SKU is not published on your tenant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
  /checkout/review:
    post:
      tags:
      - Checkout
      summary: Checkout review screen (cart, addresses, totals)
      description: '**Scope `checkout:read`.** Requires `X-Customer-Token`. Returns the shopper''s cart, saved addresses and
        language list for the checkout review step. Reads only; scoped to the authenticated shopper. If an OPTIONAL `groupOrderId`
        is supplied it must belong to the shopper (returns `404` otherwise).'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - name: groupOrderId
        in: query
        required: false
        schema:
          type: string
        description: Optional. A group order id belonging to the shopper, to include payment-gateway detail.
        example: AGU181
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  webUserBean:
                    id: 49
                    emailid: shopper@example.com
                    name: Shopper
                    mobileno: '9876500000'
                  cartOfferData: []
                  webUserAddressBeans: []
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The supplied groupOrderId does not belong to the shopper.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
  /checkout/validate-reward:
    post:
      tags:
      - Checkout
      summary: Validate reward-point redemption against the cart
      description: '**Scope `checkout:read`.** Requires `X-Customer-Token`. Checks whether the reward points offered can be
        redeemed against the shopper''s current cart total. Reads only; scoped to the authenticated shopper.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                rewardPoint:
                  type: string
                  description: The number of reward points to redeem.
                shipMethodTypeId:
                  type: string
                  description: Optional shipping method, to include shipping in the payable total.
              required:
              - rewardPoint
            example:
              rewardPoint: '500'
              shipMethodTypeId: '1'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  valid: true
                  redeemablePoints: 500
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /checkout/place-order:
    post:
      tags:
      - Checkout
      summary: Place the shopper's order (prepaid or COD)
      description: '**Scope `checkout:write`.** Requires `X-Customer-Token`. The first money write on this API. Recomputes
        totals server-side, reserves inventory and creates the order for the authenticated shopper; for a prepaid order it
        returns the payment-gateway details to redirect to, for **COD** it confirms the order directly (payment collected
        on delivery). Credit (B2B account) and card-on-delivery are rejected with `400`. Address ids (`addId`, `billingAddId`,
        `pickupAddressId`) must belong to the shopper or the call returns `404`. `siteMasterId` is ignored; the order is always
        placed on the tenant bound to your credential.


        **Idempotency (required).** Send a unique `Idempotency-Key` header per order. A retry with the same key returns the
        first attempt''s outcome (with `Idempotency-Replayed: true`) and places nothing — so a network timeout never double-places.
        A request still processing under that key returns `409`; a new order needs a new key. Keys are honoured for 24 hours.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - name: Idempotency-Key
        in: header
        required: true
        schema:
          type: string
          maxLength: 255
          pattern: '[A-Za-z0-9._:-]{1,255}'
        description: A unique key per order (e.g. a UUID). Reuse it verbatim to retry safely.
        example: order-2026-07-24-7f3a9c
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                addId:
                  type: string
                  description: Delivery address id belonging to the shopper.
                billingAddId:
                  type: string
                  description: Optional. Present only when billing differs from delivery.
                payGatewayId:
                  type: string
                  description: Prepaid gateway id. COD/credit/card-on-delivery combos are refused.
                payOptionId:
                  type: string
                gv:
                  type: string
                  description: Optional gift-voucher code.
                rwrdPoint:
                  type: string
                  description: Optional reward points to redeem.
                shipMethodTypeId:
                  type: string
                orderDeliveryTypeId:
                  type: string
                source:
                  type: string
                  example: WEB
              required:
              - addId
              - payGatewayId
              - payOptionId
            example:
              addId: '123'
              payGatewayId: '22'
              payOptionId: '35'
              shipMethodTypeId: '1'
              source: WEB
      responses:
        '200':
          description: Order placed; response carries the order and gateway details to redirect to.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  orderPaymentNumber: AGU182
                  userId: 49
                  gatewayMap:
                    status: SUCCESS
                    gatewayStatus: SUCCESS
        '400':
          description: Bad request — a missing/malformed Idempotency-Key header, or a disallowed payment method (credit /
            card-on-delivery; COD and prepaid are supported).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: This payment method is not supported on this API. Use prepaid or cash on delivery (COD).
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: An address id supplied does not belong to the shopper.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '409':
          description: A request with this Idempotency-Key is still being processed. Do not retry; query the order status.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: A request with this Idempotency-Key is still being processed. Do not retry; query the order status.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
        '503':
          description: Order placement is temporarily unavailable (the idempotency store is unreachable; it fails closed rather
            than risk a double charge).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Order placement is temporarily unavailable. Please retry with the same Idempotency-Key.
                response: null
  /customer/address/save:
    post:
      tags:
      - Customer Profile
      summary: Create or update one of the shopper's addresses
      description: '**Scope `customer:profile:write`.** Requires `X-Customer-Token`. Creates an address when `id` is omitted;
        updates it when `id` is present (the address must belong to the shopper). The owner is always the authenticated shopper
        — any `userId` in the body is ignored.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
            example:
              name: Shopper Singh
              mobileno: '9876500000'
              address: 12 MG Road
              pincode: '400709'
              addressType: HOME
      responses:
        '200':
          description: Address saved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Success
                response:
                  id: 321
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/address/default:
    post:
      tags:
      - Customer Profile
      summary: Set one of the shopper's addresses as default
      description: '**Scope `customer:profile:write`.** Requires `X-Customer-Token`. Only the shopper''s own addresses are
        affected.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                webUserAddressBean:
                  type: string
                  description: JSON string with the address id, e.g. {"id":321}
              required:
              - webUserAddressBean
            example:
              webUserAddressBean: '{"id":321}'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Success
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/address/delete:
    post:
      tags:
      - Customer Profile
      summary: Delete one of the shopper's addresses
      description: '**Scope `customer:profile:write`.** Requires `X-Customer-Token`. The address must belong to the shopper;
        a foreign or unknown id is rejected.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                webUserAddressBean:
                  type: string
                  description: JSON string with the address id, e.g. {"id":321}
              required:
              - webUserAddressBean
            example:
              webUserAddressBean: '{"id":321}'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record deleted successfully
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/password/change:
    post:
      tags:
      - Customer Profile
      summary: Change the shopper's password
      description: '**Scope `customer:profile:write`.** Requires `X-Customer-Token`. The CURRENT password is required and
        verified before the change (send it as `currentPassword`); the new password travels in `webUserBean` as `password`
        + `confirmPassword`. Applies to the authenticated shopper only.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                currentPassword:
                  type: string
                  description: The shopper's current password (verified server-side).
                webUserBean:
                  type: string
                  description: JSON string with the new password, e.g. {"password":"...","confirmPassword":"..."}
              required:
              - currentPassword
              - webUserBean
            example:
              currentPassword: OldPass!23
              webUserBean: '{"password":"NewPass!45","confirmPassword":"NewPass!45"}'
      responses:
        '200':
          description: Password changed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record updated successfully
                response: null
        '400':
          description: The current password was not supplied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: The current password is required. Send it as currentPassword.
                response: null
        '401':
          description: Missing customer token, or the current password is incorrect.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: The current password is incorrect.
                response: null
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/notifications:
    post:
      tags:
      - Customer Profile
      summary: The shopper's notifications
      description: '**Scope `customer:profile:read`.** Requires `X-Customer-Token`. Returns the bound shopper''s notifications.
        Any `userId` sent is ignored - the authenticated shopper is used.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  notificationList:
                  - id: 501
                    notificationType: ORDER
                    message: Your order AGU181 has been dispatched.
                    isRead: 0
                    cd: '2026-06-20 14:05:00'
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/notifications/count:
    post:
      tags:
      - Customer Profile
      summary: Unread notification count
      description: '**Scope `customer:profile:read`.** Requires `X-Customer-Token`. Unread count for the bound shopper (caller
        `userId` ignored).'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  count: 3
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/notifications/read:
    post:
      tags:
      - Customer Profile
      summary: Mark a notification read
      description: '**Scope `customer:profile:read`.** Requires `X-Customer-Token`. Marks one of the bound shopper''s own
        notifications as read. `notificationId` must be a notification addressed to that shopper on your tenant - anything
        else answers `404`, whether it belongs to another shopper or does not exist.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                notificationId:
                  type: string
                  description: The id of one of this shopper's notifications, as returned by `/customer/notifications`.
              required:
              - notificationId
            example:
              notificationId: '501'
      responses:
        '200':
          description: Marked read. Repeating the call is harmless.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The notification is not this shopper's, or does not exist - the two are deliberately indistinguishable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/notifications/subscribe-stock:
    post:
      tags:
      - Customer Profile
      summary: Subscribe to a back-in-stock notification
      description: '**Scope `engagement:write`.** Requires `X-Customer-Token`. Subscribes the shopper to a back-in-stock alert
        for `parentSkuId` (must be on your tenant, else `404`).'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                parentSkuId:
                  type: string
                  description: A SKU id on your tenant.
              required:
              - parentSkuId
            example:
              parentSkuId: '101'
      responses:
        '200':
          description: Subscribed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record added successfully.
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The SKU is not on your tenant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/review/rate:
    post:
      tags:
      - Customer Profile
      summary: Write a product rating / review
      description: '**Scope `engagement:write`.** Requires `X-Customer-Token`. Posts a rating and review for `skuId` (must
        be on your tenant, else `404`). Title and review text are validated - HTML/script content is rejected with `400`.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                webUserOfferRatingReviewBean:
                  type: string
                  description: 'JSON: { skuId, rating (1-5), title, review }'
              required:
              - webUserOfferRatingReviewBean
            example:
              webUserOfferRatingReviewBean: '{"skuId":101,"rating":5,"title":"Excellent","review":"Great quality, fast delivery."}'
      responses:
        '200':
          description: Review saved.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record added successfully.
                response: null
        '400':
          description: Missing details, or title/review contains HTML/script.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'Invalid review text: HTML or script content is not allowed.'
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The SKU is not on your tenant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/cart/save-for-later:
    post:
      tags:
      - Cart & Wishlist
      summary: Move a cart line to save-for-later
      description: '**Scope `cart:write`.** Requires `X-Customer-Token`. Moves a cart line to the shopper''s save-for-later
        list.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                webUserCartBean:
                  type: string
                  description: JSON cart line, e.g. {"id":88,"parentSkuId":101}
              required:
              - webUserCartBean
            example:
              webUserCartBean: '{"id":88,"parentSkuId":101}'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record updated successfully
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/order/cancel:
    post:
      tags:
      - Orders
      summary: Cancel one of the shopper's orders (request; back-office settles the refund)
      description: '**Scope `orders:customer:write`.** Requires `X-Customer-Token`. Cancels the shopper''s order named by
        `paymentorderid` (must belong to the shopper, else `404`). This is a REQUEST: it records the cancellation and moves
        the order to a pending refund status; the money refund is settled by the tenant''s back-office (gateway refund for
        gateway-paid; gift-voucher / wallet for GV/COD). No money moves at this call.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                paymentorderid:
                  type: string
                  description: A payment order id belonging to the shopper.
                remarks:
                  type: string
                  description: Optional cancellation reason.
              required:
              - paymentorderid
            example:
              paymentorderid: AU126
              remarks: Ordered by mistake
      responses:
        '200':
          description: Cancellation recorded; order moved to pending refund.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record updated successfully
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The order does not belong to the shopper (or cannot be cancelled).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/order/invoice:
    post:
      tags:
      - Orders
      summary: Download invoice(s) for the shopper's order(s)
      description: '**Scope `orders:customer:read`.** Requires `X-Customer-Token`. Returns invoice data for the orders in
        `orderIdsInvoice` (payment order ids) or `groupOrderIdsInvoice` (group order ids). EVERY id must belong to the shopper
        - one foreign id fails the whole request (`404`).'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                orderIdsInvoice:
                  type: string
                  description: Comma-separated payment order ids.
                groupOrderIdsInvoice:
                  type: string
                  description: Comma-separated group order ids.
            example:
              orderIdsInvoice: AU126
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  fileName: invoice_AU126_1721822400000.pdf
                  outArray: JVBERi0xLjQKJ...base64-encoded-PDF-bytes...
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: An order does not belong to the shopper.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/order/reorder:
    post:
      tags:
      - Orders
      summary: Re-order (rebuild the cart from) a past order
      description: '**Scope `orders:customer:write`.** Requires `X-Customer-Token`. Rebuilds the cart from the shopper''s
        past order named by `reOrderId` (a payment order id; must belong to the shopper, else `404`).'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                reOrderId:
                  type: string
                  description: A payment order id belonging to the shopper.
              required:
              - reOrderId
            example:
              reOrderId: AU126
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record found successfully
                response:
                  addedToCart: 2
                  skippedUnavailable: 0
                  cartItems:
                  - skuId: 101
                    quantity: 1
                  - skuId: 205
                    quantity: 1
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The order does not belong to the shopper.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
  /customer/order/return-replacement:
    post:
      tags:
      - Orders
      summary: Raise a return / replacement request (back-office settles the refund)
      description: '**Scope `orders:customer:write`.** Requires `X-Customer-Token`. Raises a return or replacement request
        for the shopper''s delivered order. The header order AND every line (`complaintMasterBeans[].grouporderid`) must belong
        to the shopper, else `404`. REQUEST only: it creates the return order + a lead and starts the pending refund; the
        refund is settled by the tenant''s back-office. No money moves at this call.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                returnOrderBean:
                  type: string
                  description: 'JSON string: { paymentorderid, grouporderid, remark, complaintMasterBeans:[{ grouporderid,
                    ... }] }'
              required:
              - returnOrderBean
            example:
              returnOrderBean: '{"paymentorderid":"AU126","grouporderid":"AGU181","remark":"Damaged","complaintMasterBeans":[{"grouporderid":"AGU181-1"}]}'
      responses:
        '200':
          description: Return/replacement request created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Record updated successfully
                response: null
        '400':
          description: Missing/invalid return details.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Please provide the return/replacement details.
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The order (or a return line) does not belong to the shopper.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
  /engagement/enquiry:
    post:
      tags:
      - Engagement
      summary: Submit a contact / product enquiry (visitor not signed in)
      description: '**Scope `engagement:public:write`.** **No `X-Customer-Token`** - this is the contact form you show a signed-out
        visitor. Creates a lead on your tenant and emails a confirmation to the address supplied. The tenant is stamped server-side
        from your partner record; there is no site field to send. `skuId` is optional, but when present it must be a SKU on
        your tenant (else `404`). Free-text fields are validated: HTML or script content is rejected with `400`. Throttled
        per partner per tenant - every submission counts, not just failed ones.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                leadTypeId:
                  type: string
                  description: Lead type (group id). Required.
                dispositionId:
                  type: string
                  description: Disposition (group id). Required.
                name:
                  type: string
                  description: Visitor's name.
                email:
                  type: string
                  description: Visitor's email; the confirmation is sent here.
                mobileNo:
                  type: string
                  description: Visitor's mobile number.
                details:
                  type: string
                  description: The enquiry text. Defaults to 'Web User Enquiry' if omitted.
                remarks:
                  type: string
                  description: Optional free-text remark, stored as a lead comment.
                skuId:
                  type: string
                  description: Optional SKU the enquiry is about. Must be on your tenant.
                pincode:
                  type: string
                  description: Optional pincode.
                address:
                  type: string
                  description: Optional address.
              required:
              - leadTypeId
              - dispositionId
            example:
              leadTypeId: '175'
              dispositionId: '215'
              name: Asha Menon
              email: shopper@example.com
              mobileNo: '9876500000'
              details: Please call me about delivery timelines.
      responses:
        '200':
          description: Enquiry received; a lead was created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Dear User! we have received your request our team will get back to you soon
                response: null
        '400':
          description: Free text contained HTML or script content.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'Invalid input: HTML or script content is not allowed.'
                response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The SKU named is not on your tenant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          description: Too many submissions from this partner on this tenant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Too many submissions. Please wait a minute and try again.
                response: null
  /engagement/campaign-lead:
    post:
      tags:
      - Engagement
      summary: Submit a campaign / offer lead for a product (visitor not signed in)
      description: '**Scope `engagement:public:write`.** **No `X-Customer-Token`.** The lead form behind a campaign or offer
        landing page. `skuId` and `pincode` are REQUIRED: the product name is copied from the SKU, and the state and city
        are resolved from the pincode. The SKU must be on your tenant, else `404`. **Insert-only** - an `id` in the body is
        ignored and a new lead is always created. Free text is validated (`400` on HTML/script), and the route is throttled
        per partner per tenant.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - skuId
              - pincode
              - details
            example:
              skuId: 912
              name: Asha Menon
              email: shopper@example.com
              mobileNo: '9876500000'
              pincode: '400709'
              details: Interested in this offer
      responses:
        '200':
          description: Lead received.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: Dear User! we have received your request our team will get back to you soon
                response: null
        '400':
          description: Free text contained HTML or script content, or the lead details are missing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'Invalid input: HTML or script content is not allowed.'
                response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: The SKU is not on your tenant, or no SKU was named.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Not found.
                response: null
        '429':
          description: Too many submissions from this partner on this tenant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Too many submissions. Please wait a minute and try again.
                response: null
  /engagement/subscribe:
    post:
      tags:
      - Engagement
      summary: Newsletter signup (visitor not signed in)
      description: '**Scope `engagement:public:write`.** **No `X-Customer-Token`.** Adds an email address to your tenant''s
        newsletter list. The tenant is stamped server-side, and the duplicate check is scoped to it - the same address may
        be subscribed independently on another tenant. An address already on YOUR list answers `200` with a `FAIL` envelope,
        not an error status. Throttled per partner per tenant.'
      security:
      - PartnerKey: []
        PartnerToken: []
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              properties:
                subscribeBean:
                  type: string
                  description: 'JSON string: { email }'
              required:
              - subscribeBean
            example:
              subscribeBean: '{"email":"shopper@example.com"}'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              examples:
                subscribed:
                  summary: Added to the list
                  value:
                    status: SUCCESS
                    message: Congratulations. If we have have anything of extreme value to send you we will. If not we won’t
                      bug you. Our promise
                    response: null
                already:
                  summary: Already on this tenant's list
                  value:
                    status: FAIL
                    message: Dear User! Provided email is already subscribed with us
                    response: null
        '400':
          description: The body contained HTML or script content.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'Invalid input: HTML or script content is not allowed.'
                response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          description: Too many submissions from this partner on this tenant.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Too many submissions. Please wait a minute and try again.
                response: null
  /servicedesk/catalogue:
    post:
      tags:
      - ServiceDesk
      summary: Bookable service types, modes, concerns and items
      description: '**Scope `servicedesk:catalog:read`.** Everything a booking funnel needs to render its first step. Tenant-scoped
        by your partner binding - no id is sent.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  serviceTypes:
                    '1': Advisory Consultation
                    '2': Home Services
                  modes:
                  - id: 4
                    name: At Home
                  concerns:
                  - id: 3
                    name: Leaking tap
                  serviceItems:
                  - id: 7
                    name: Plumbing Callout & Diagnosis
                    serviceTypeId: 2
                    durationMinutes: 60
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /servicedesk/providers:
    post:
      tags:
      - ServiceDesk
      summary: Published, verified providers
      description: '**Scope `servicedesk:provider:read`.** Only providers that are PUBLISHED and VERIFIED on your tenant.
        An unverified provider cannot be booked and is not listed.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  providers:
                  - id: 5
                    code: SVCP-PLM-001
                    displayName: Epsilon Plumbing Works
                    serviceTypeId: 2
                    ratingAvg: 0.0
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /servicedesk/availability:
    post:
      tags:
      - ServiceDesk
      summary: Open slots for one provider over a date window
      description: '**Scope `servicedesk:availability:read`.** ⚠️ The window is CLAMPED to 62 days, not merely validated -
        an unbounded range is cheap to ask for and expensive to serve. Slots carry no counters, no version and no status (SF-032):
        a slot appearing here is not a promise it will still be free when you hold it.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: providerId
        in: query
        required: true
        schema:
          type: integer
        description: Provider id from /providers.
        example: 5
      - name: fromDate
        in: query
        required: true
        schema:
          type: string
        description: Inclusive, yyyy-MM-dd.
        example: '2026-09-03'
      - name: toDate
        in: query
        required: true
        schema:
          type: string
        description: Inclusive, yyyy-MM-dd. Clamped to fromDate + 62 days.
        example: '2026-09-10'
      - name: serviceModeId
        in: query
        required: false
        schema:
          type: integer
        description: Narrow to one delivery mode.
        example: 4
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  windowFrom: '2026-09-03'
                  windowTo: '2026-09-10'
                  slots:
                  - id: 167385
                    slotDate: '2026-09-03'
                    startTime: 08:00
                    endTime: 09:00
                    providerId: 5
                    serviceModeId: 4
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /servicedesk/quote:
    post:
      tags:
      - ServiceDesk
      summary: The price for one slot
      description: '**Scope `servicedesk:availability:read`.** ⚠️ SERVER-DERIVED, AND NOT AN INPUT TO ANYTHING. Price varies
        by slot - a modifier can move it by day, hour or lead time - so there is no single ''price of a service''. The confirm
        re-prices from the held slot regardless of what was quoted, so a stale quote costs a re-read, never a wrong charge.
        An unresolved quote says so and carries no number.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: slotId
        in: query
        required: true
        schema:
          type: integer
        description: Slot id from /availability.
        example: 167385
      - name: serviceTypeId
        in: query
        required: true
        schema:
          type: integer
        description: Service type id.
        example: 2
      - name: serviceItemId
        in: query
        required: true
        schema:
          type: integer
        description: Service item id the provider offers.
        example: 7
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  quote:
                    resolved: true
                    totalDisplay: ₹ 649.00
                    lines:
                    - label: Service
                      amountDisplay: ₹ 550.00
                    - label: CGST
                      amountDisplay: ₹ 49.50
                    - label: SGST
                      amountDisplay: ₹ 49.50
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /servicedesk/hold:
    post:
      tags:
      - ServiceDesk
      summary: Reserve a slot for your customer
      description: '**Scope `servicedesk:booking:write`.** ⚠️ REQUIRES `X-Customer-Token` for an EXISTING customer. This platform
        does not create a person''s record on a partner''s assertion, so a walk-up customer must be onboarded through the
        customer-auth scopes first. ⚠️ `Idempotency-Key` is REQUIRED on this endpoint, and it is the only ServiceDesk write
        that requires one: confirm, cancel and reschedule are each bound to a hold token or a booking id the database will
        not spend twice, whereas a hold takes a FRESH unit of capacity on every call. A retry after a timeout you never saw
        resolve returns the original hold rather than taking a second one. Reuse the key verbatim to retry; a DIFFERENT request
        needs a NEW key. ⚠️ The same key with a different body is `422`, never a replay of the first answer - being told you
        booked an appointment you did not ask for is discovered when somebody does not arrive. Keys are honoured for 24 hours.
        The hold is short-lived and is released automatically if you do not confirm.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - name: Idempotency-Key
        in: header
        required: true
        schema:
          type: string
          maxLength: 255
          pattern: '[A-Za-z0-9._:-]{1,255}'
        description: A unique key per request (e.g. a UUID). Reuse it verbatim to retry safely; a DIFFERENT request needs
          a different key.
        example: svc-2026-08-30-7f3a9c
      - name: slotId
        in: query
        required: true
        schema:
          type: integer
        description: Slot id from /availability.
        example: 167385
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  outcome: HELD
                  holdToken: 3f7c1e90-2b44-4a19-9c1d-8e5b7a0d1234
                  expiresAt: '2026-08-29T12:41:07'
                  ttlSeconds: 420
        '400':
          description: Bad request - the Idempotency-Key header is missing or malformed. Nothing was attempted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'This endpoint requires an Idempotency-Key header: 1-240 characters from A-Z a-z 0-9 . _ - and :'
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          description: A request with this Idempotency-Key is still in progress. Do NOT retry blind - read the booking back
            before sending it again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'Another request with this Idempotency-Key is still in progress. Do not retry it blind: read the
                  booking back before sending it again.'
                response: null
        '422':
          description: That Idempotency-Key has already been used for a DIFFERENT request. The first result is NOT replayed,
            deliberately - it describes another appointment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: That Idempotency-Key has already been used for a DIFFERENT request. Send a new key for a new request,
                  or resend the original one unchanged.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
        '503':
          description: 'Idempotency could not be guaranteed (the store is unreachable). It fails CLOSED: the request was NOT
            performed. Retry with the same key.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Idempotency could not be guaranteed for this request. It was NOT performed. Retry it.
                response: null
  /servicedesk/hold/release:
    post:
      tags:
      - ServiceDesk
      summary: Give a held slot back
      description: '**Scope `servicedesk:booking:write`.** Releases a hold your customer owns. A token belonging to someone
        else affects nothing and is refused identically to one that expired - the two answers are the same sentence.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - name: holdToken
        in: query
        required: true
        schema:
          type: string
        description: The token /hold returned.
        example: 3f7c1e90-2b44-4a19-9c1d-8e5b7a0d1234
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  outcome: RELEASED
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /servicedesk/booking/confirm:
    post:
      tags:
      - ServiceDesk
      summary: Turn a held slot into a booking
      description: '**Scope `servicedesk:booking:write`.** ⚠️ NO AMOUNT, DISCOUNT, TAX OR TOTAL IS A REQUEST FIELD. Not validated
        - ABSENT. The whole breakdown is re-derived from the ids on the consumed hold. ⚠️ NO PAYMENT IS CAPTURED. A confirmed
        booking sits UNPAID; that is the behaviour on every channel, not a partner limitation. ⚠️ A `couponCode` that no longer
        applies is REFUSED with `response.outcome = COUPON_REFUSED` (status FAIL, message `That code cannot be applied.`),
        nothing is booked and the hold is NOT consumed. The refusal carries `response.fullPrice`, the server re-price of the same
        booking WITHOUT the coupon (display only), and `response.expectedTotal`, the same total as a plain decimal string. A
        coupon whose own configuration is faulty is answered the same way. ⚠️ The message is that ONE sentence for EVERY
        coupon refusal, whatever the reason (unknown, expired, used up, per-customer limit, minimum order, scope); no reason
        is returned, so do not branch on the message. To book at that price, re-submit the same confirm
        WITHOUT `couponCode`, WITH `expectedTotal` set to that value, under a NEW `Idempotency-Key`, while the hold is still
        live. ⚠️ `expectedTotal` is a COMPARISON value, never the price: the server prices the booking again and, if its total
        differs from `expectedTotal` to the paise (or `expectedTotal` is not a plain decimal with at most two places), REFUSES
        with `response.outcome = PRICE_CHANGED` (status FAIL), books nothing, leaves the hold unconsumed and returns the new
        `fullPrice` and `expectedTotal` - show the new price and re-submit with the new `expectedTotal` if the customer
        accepts. A confirm without `expectedTotal` behaves as before. ⚠️ `Idempotency-Key` is OPTIONAL
        here, and that is deliberate rather than an omission. The guarantee is the HOLD TOKEN: it is consumed by one conditional
        statement, so a retry - even with NO header at all - replays the same booking rather than creating a second one. Sending
        a key additionally replays the FIRST response instead of re-running the call. ⚠️ The same key with a DIFFERENT body
        is `422`, never a replay. Keys are honoured for 24 hours.'
      security:
      - PartnerKey: []
        PartnerToken: []
        CustomerToken: []
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        schema:
          type: string
          maxLength: 255
          pattern: '[A-Za-z0-9._:-]{1,255}'
        description: Optional. A unique key per request; reuse it verbatim to retry safely. A DIFFERENT request needs a different
          key.
        example: svc-2026-08-30-7f3a9c
      - name: holdToken
        in: query
        required: true
        schema:
          type: string
        description: The token /hold returned.
        example: 3f7c1e90-2b44-4a19-9c1d-8e5b7a0d1234
      - name: serviceTypeId
        in: query
        required: true
        schema:
          type: integer
        description: Service type id.
        example: 2
      - name: serviceItemId
        in: query
        required: true
        schema:
          type: integer
        description: Service item the provider offers.
        example: 7
      - name: concernId
        in: query
        required: false
        schema:
          type: integer
        description: Optional concern id.
        example: 3
      - name: couponCode
        in: query
        required: false
        schema:
          type: string
        description: Optional coupon. If it no longer applies the confirm answers COUPON_REFUSED with `fullPrice` and books
          nothing; omit this parameter on the resubmit to book at full price. The refusal message is the same for every
          reason; the reason is never returned.
        example: WELCOME10
      - name: expectedTotal
        in: query
        required: false
        schema:
          type: string
          pattern: ^\d{1,13}(\.\d{1,2})?$
        description: Optional. The total the customer was SHOWN, copied from `response.expectedTotal` of a COUPON_REFUSED or
          PRICE_CHANGED answer. A comparison value only - it is never used as the price. If the server's re-price differs,
          the confirm answers PRICE_CHANGED with the new `fullPrice` and books nothing. Omit it on a first confirm.
        example: '1298.00'
      - name: customerNotes
        in: query
        required: false
        schema:
          type: string
        description: Free text, bounded.
        example: Leak under the sink
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  outcome: CONFIRMED
                  booking:
                    bookingNumber: BKG-4-NMH99YPZKPAE7XWYHN
                    scheduledDate: '2026-09-03'
                    scheduledStart: 08:00
                    scheduledEnd: 09:00
                    providerId: 5
                    serviceModeId: 4
                    currencyCode: INR
                    baseAmount: 550.0
                    discountAmount: 0.0
                    taxAmount: 99.0
                    totalAmount: 649.0
                    paymentStatus: UNPAID
        '400':
          description: Bad request - the Idempotency-Key header, if sent, is malformed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'That Idempotency-Key is not valid: 1-240 characters from A-Z a-z 0-9 . _ - and :, and it may not
                  begin with a reserved prefix.'
                response: null
        '401':
          $ref: '#/components/responses/CustomerUnauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          description: A request with this Idempotency-Key is still in progress. Do NOT retry blind - read the booking back
            before sending it again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'Another request with this Idempotency-Key is still in progress. Do not retry it blind: read the
                  booking back before sending it again.'
                response: null
        '422':
          description: That Idempotency-Key has already been used for a DIFFERENT request. The first result is NOT replayed,
            deliberately - it describes another appointment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: That Idempotency-Key has already been used for a DIFFERENT request. Send a new key for a new request,
                  or resend the original one unchanged.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
        '503':
          description: 'Idempotency could not be guaranteed (the store is unreachable). It fails CLOSED: the request was NOT
            performed. Retry with the same key.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Idempotency could not be guaranteed for this request. It was NOT performed. Retry it.
                response: null
  /servicedesk/booking/detail:
    post:
      tags:
      - ServiceDesk
      summary: One booking you created
      description: '**Scope `servicedesk:booking:read`.** ⚠️ Only bookings YOUR integration created. A booking that does not
        exist, belongs to another partner, or sits on another tenant all answer the same refusal - a more helpful reply would
        confirm that a guessed booking number is real. ⚠️ No customer name, phone or email is returned: you supplied the customer
        token, and this API is not a directory.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: bookingNumber
        in: query
        required: true
        schema:
          type: string
        description: Booking number from /booking/confirm.
        example: BKG-4-NMH99YPZKPAE7XWYHN
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  booking:
                    bookingNumber: BKG-4-NMH99YPZKPAE7XWYHN
                    scheduledDate: '2026-09-03'
                    scheduledStart: 08:00
                    scheduledEnd: 09:00
                    providerId: 5
                    providerName: Epsilon Plumbing Works
                    serviceTypeId: 2
                    serviceItemId: 7
                    serviceModeId: 4
                    statusName: CONFIRMED
                    statusGroup: OPEN
                    currencyCode: INR
                    totalAmount: 649.0
                    refundedAmount: 0.0
                    paymentStatus: UNPAID
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /servicedesk/booking/list:
    post:
      tags:
      - ServiceDesk
      summary: The bookings you created
      description: '**Scope `servicedesk:booking:read`.** Newest first. Narrowed to your integration in SQL, not by a filter
        you send.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: fromDate
        in: query
        required: false
        schema:
          type: string
        description: Inclusive lower bound on the scheduled date.
        example: '2026-09-01'
      - name: toDate
        in: query
        required: false
        schema:
          type: string
        description: Inclusive upper bound.
        example: '2026-09-30'
      - name: pageSize
        in: query
        required: false
        schema:
          type: integer
        description: Bounded at 100.
        example: 25
      - name: offset
        in: query
        required: false
        schema:
          type: integer
        description: Zero-based.
        example: 0
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  totalRecords: 1
                  bookings:
                  - bookingNumber: BKG-4-NMH99YPZKPAE7XWYHN
                    scheduledDate: '2026-09-03'
                    providerName: Epsilon Plumbing Works
                    statusName: CONFIRMED
                    currencyCode: INR
                    totalAmount: 649.0
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /servicedesk/booking/cancel:
    post:
      tags:
      - ServiceDesk
      summary: Cancel a booking you created
      description: '**Scope `servicedesk:booking:cancel`.** ⚠️ A SEPARATE SCOPE FROM `booking:write`, deliberately: cancelling
        is what carries the refund consequence, so an integration that may create bookings is not automatically one that may
        cancel them. Subject to the tenant''s policy cutoff - you cannot waive it. ⚠️ `Idempotency-Key` is OPTIONAL here,
        and that is deliberate rather than an omission: this call is bound to a hold token or a booking id that the database
        itself will not spend twice, so a retry WITHOUT the header is already safe. Sending one additionally replays the FIRST
        response instead of re-running the call. ⚠️ The same key with a DIFFERENT body is `422`, never a replay. Keys are
        honoured for 24 hours.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        schema:
          type: string
          maxLength: 255
          pattern: '[A-Za-z0-9._:-]{1,255}'
        description: Optional. A unique key per request; reuse it verbatim to retry safely. A DIFFERENT request needs a different
          key.
        example: svc-2026-08-30-7f3a9c
      - name: bookingId
        in: query
        required: true
        schema:
          type: integer
        description: Booking id.
        example: 4021
      - name: reason
        in: query
        required: false
        schema:
          type: string
        description: Free text, bounded.
        example: Customer rescheduled by phone
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  outcome: CANCELLED
                  booking:
                    bookingNumber: BKG-4-NMH99YPZKPAE7XWYHN
                    totalAmount: 649.0
        '400':
          description: Bad request - the Idempotency-Key header, if sent, is malformed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'That Idempotency-Key is not valid: 1-240 characters from A-Z a-z 0-9 . _ - and :, and it may not
                  begin with a reserved prefix.'
                response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          description: A request with this Idempotency-Key is still in progress. Do NOT retry blind - read the booking back
            before sending it again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'Another request with this Idempotency-Key is still in progress. Do not retry it blind: read the
                  booking back before sending it again.'
                response: null
        '422':
          description: That Idempotency-Key has already been used for a DIFFERENT request. The first result is NOT replayed,
            deliberately - it describes another appointment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: That Idempotency-Key has already been used for a DIFFERENT request. Send a new key for a new request,
                  or resend the original one unchanged.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
        '503':
          description: 'Idempotency could not be guaranteed (the store is unreachable). It fails CLOSED: the request was NOT
            performed. Retry with the same key.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Idempotency could not be guaranteed for this request. It was NOT performed. Retry it.
                response: null
  /servicedesk/booking/reschedule:
    post:
      tags:
      - ServiceDesk
      summary: Move a booking you created to another slot
      description: '**Scope `servicedesk:booking:cancel`.** Moves the appointment to `targetSlotId`. The target is acquired
        through the same atomic statement a fresh hold uses, so a slot taken in between is refused rather than double-booked.
        ⚠️ `Idempotency-Key` is OPTIONAL here, and that is deliberate rather than an omission: this call is bound to a hold
        token or a booking id that the database itself will not spend twice, so a retry WITHOUT the header is already safe.
        Sending one additionally replays the FIRST response instead of re-running the call. ⚠️ The same key with a DIFFERENT
        body is `422`, never a replay. Keys are honoured for 24 hours.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - name: Idempotency-Key
        in: header
        required: false
        schema:
          type: string
          maxLength: 255
          pattern: '[A-Za-z0-9._:-]{1,255}'
        description: Optional. A unique key per request; reuse it verbatim to retry safely. A DIFFERENT request needs a different
          key.
        example: svc-2026-08-30-7f3a9c
      - name: bookingId
        in: query
        required: true
        schema:
          type: integer
        description: Booking id.
        example: 4021
      - name: targetSlotId
        in: query
        required: true
        schema:
          type: integer
        description: Slot id from /availability.
        example: 167390
      - name: reason
        in: query
        required: false
        schema:
          type: string
        description: Free text, bounded.
        example: Customer asked for a later time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  outcome: RESCHEDULED
                  booking:
                    bookingNumber: BKG-4-NMH99YPZKPAE7XWYHN
                    scheduledDate: '2026-09-05'
                    scheduledStart: 08:00
                    totalAmount: 649.0
        '400':
          description: Bad request - the Idempotency-Key header, if sent, is malformed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'That Idempotency-Key is not valid: 1-240 characters from A-Z a-z 0-9 . _ - and :, and it may not
                  begin with a reserved prefix.'
                response: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          description: A request with this Idempotency-Key is still in progress. Do NOT retry blind - read the booking back
            before sending it again.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: 'Another request with this Idempotency-Key is still in progress. Do not retry it blind: read the
                  booking back before sending it again.'
                response: null
        '422':
          description: That Idempotency-Key has already been used for a DIFFERENT request. The first result is NOT replayed,
            deliberately - it describes another appointment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: That Idempotency-Key has already been used for a DIFFERENT request. Send a new key for a new request,
                  or resend the original one unchanged.
                response: null
        '429':
          $ref: '#/components/responses/TooMany'
        '503':
          description: 'Idempotency could not be guaranteed (the store is unreachable). It fails CLOSED: the request was NOT
            performed. Retry with the same key.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: FAIL
                message: Idempotency could not be guaranteed for this request. It was NOT performed. Retry it.
                response: null
  /digital/library:
    post:
      tags:
      - Digital
      summary: The customer's digital purchases
      description: '**Scope `digital:library:read`.** Every entitlement this customer owns, with the server''s own verdict
        on each: whether it can be downloaded now, and if not, why. ⚠️ Requires `X-Customer-Token` - the scope is CUSTOMER-BOUND,
        so the customer is resolved before the handler runs and there is no customer id to send. Dates are epoch milliseconds.
        A LICENCE entitlement carries its `licenceKey`; a DOWNLOAD one does not.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  count: 2
                  items:
                  - grantCode: iN34nkRGztUMvYszwRxfTG
                    productName: Advanced Excel - Masterclass
                    skuCode: DGT-XL-01
                    type: LICENCE
                    status: ACTIVE
                    orderNumber: AS467
                    purchasedOn: 1788599772000
                    validFrom: 1788619669000
                    validUntil: null
                    neverExpires: true
                    firstAccessedOn: null
                    downloadsUsed: 0
                    maxDownloads: null
                    downloadsRemaining: null
                    unlimitedDownloads: true
                    devicesUsed: 0
                    maxDevices: 1
                    unlimitedDevices: false
                    downloadable: true
                    reason: ''
                    reasonMessage: ''
                    refundable: true
                    refundNote: You have not opened this yet, so it can still be refunded.
                    licenceKey: XXXXX-XXXXX-XXXXX-XXXXX-XXXXX
                  - grantCode: 6wvrEhucNltgXXss3BGjTs
                    productName: Field Safety Handbook
                    skuCode: DGT-FS-02
                    type: DOWNLOAD
                    status: ACTIVE
                    orderNumber: AS442
                    purchasedOn: 1788512400000
                    validFrom: 1788512400000
                    validUntil: 1820048400000
                    neverExpires: false
                    firstAccessedOn: 1788516000000
                    downloadsUsed: 5
                    maxDownloads: 5
                    downloadsRemaining: 0
                    unlimitedDownloads: false
                    devicesUsed: 1
                    maxDevices: 2
                    unlimitedDevices: false
                    downloadable: false
                    reason: LIMIT
                    reasonMessage: You have used all 5 downloads for this item.
                    refundable: false
                    refundNote: You opened this on 3 September 2026, so it can no longer be refunded.
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'
  /digital/delivery/url:
    post:
      tags:
      - Digital
      summary: Mint a fresh, single-use delivery token
      description: '**Scope `digital:delivery:write`.** Returns a signed, expiring token for one asset of one grant. ⚠️ THIS
        IS A `:write` SCOPE BECAUSE MINTING MANUFACTURES A SINGLE-USE CREDENTIAL that will consume the customer''s download
        ceiling when it is spent - the mint EVALUATES the ceiling, the redeem spends it. A partner granted only `digital:library:read`
        therefore cannot produce download credentials. ⚠️ Spend the token from YOUR OWN SERVER against `/ECOM/api/digital/delivery/{token}`;
        it is single-use, short-lived and bound to this customer. No absolute URL is returned, because ours would be meaningless
        in your page.'
      security:
      - PartnerKey: []
        PartnerToken: []
      parameters:
      - *id001
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Envelope'
              example:
                status: SUCCESS
                message: null
                response:
                  token: v1.NH4xfjF-NDl-MTc4ODYwMTg3Nw.XXXXXXXXXXXXXXXXXXXXXX
                  assetId: 1
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/TooMany'

webhooks:
  order.status.changed:
    post:
      tags:
      - Webhooks
      summary: An order moved to a new status.
      description: 'Sent when: An order moved to a new status.


        Verify `X-Eqomos-Signature` and reject a timestamp older than 5 minutes; dedupe on `eventId`; do not assume ordering.
        Reply `2xx` as soon as you have durably accepted it - **a `4xx` is terminal and we stop retrying**, and anything slower
        than 10s is treated as a failure. See the Webhooks section above for the full contract.'
      parameters:
      - name: X-Eqomos-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - order.status.changed
      - name: X-Eqomos-Event-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: The dedupe key.
      - name: X-Eqomos-Timestamp
        in: header
        required: true
        schema:
          type: integer
        description: Unix seconds. Reject if more than 5 minutes old.
      - name: X-Eqomos-Signature
        in: header
        required: true
        schema:
          type: string
        description: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>" keyed with your webhook secret>.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                  description: Stable across every retry of this occurrence. DEDUPE ON THIS.
                event:
                  type: string
                  enum:
                  - order.status.changed
                occurredAt:
                  type: string
                  format: date-time
                  description: ISO-8601 UTC, when the change happened - not when it was sent.
                id:
                  type: string
                  description: The id of the resource the event is about.
                status:
                  description: The new status id.
              required:
              - eventId
              - event
              - occurredAt
              - id
            example:
              eventId: 297fa9be-b7ea-4919-93b4-a8de04164cd6
              event: order.status.changed
              occurredAt: '2026-07-29T11:20:11Z'
              id: AGS496
              status: 116
      responses:
        '200':
          description: Accepted. Any 2xx ends delivery.
        '400':
          description: TERMINAL - we stop retrying. Only reply 4xx if you will never accept it.
        '500':
          description: Retried on the documented backoff.
  order.cancelled:
    post:
      tags:
      - Webhooks
      summary: An order reached the cancelled status.
      description: 'Sent when: An order reached the cancelled status.


        Verify `X-Eqomos-Signature` and reject a timestamp older than 5 minutes; dedupe on `eventId`; do not assume ordering.
        Reply `2xx` as soon as you have durably accepted it - **a `4xx` is terminal and we stop retrying**, and anything slower
        than 10s is treated as a failure. See the Webhooks section above for the full contract.'
      parameters:
      - name: X-Eqomos-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - order.cancelled
      - name: X-Eqomos-Event-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: The dedupe key.
      - name: X-Eqomos-Timestamp
        in: header
        required: true
        schema:
          type: integer
        description: Unix seconds. Reject if more than 5 minutes old.
      - name: X-Eqomos-Signature
        in: header
        required: true
        schema:
          type: string
        description: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>" keyed with your webhook secret>.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                  description: Stable across every retry of this occurrence. DEDUPE ON THIS.
                event:
                  type: string
                  enum:
                  - order.cancelled
                occurredAt:
                  type: string
                  format: date-time
                  description: ISO-8601 UTC, when the change happened - not when it was sent.
                id:
                  type: string
                  description: The id of the resource the event is about.
                status:
                  description: The cancelled status id.
              required:
              - eventId
              - event
              - occurredAt
              - id
            example:
              eventId: 297fa9be-b7ea-4919-93b4-a8de04164cd6
              event: order.cancelled
              occurredAt: '2026-07-29T11:20:11Z'
              id: AGS496
              status: 103
      responses:
        '200':
          description: Accepted. Any 2xx ends delivery.
        '400':
          description: TERMINAL - we stop retrying. Only reply 4xx if you will never accept it.
        '500':
          description: Retried on the documented backoff.
  order.refund.settled:
    post:
      tags:
      - Webhooks
      summary: A refund was SETTLED by the back office - not merely requested.
      description: 'Sent when: A refund was SETTLED by the back office - not merely requested.


        Verify `X-Eqomos-Signature` and reject a timestamp older than 5 minutes; dedupe on `eventId`; do not assume ordering.
        Reply `2xx` as soon as you have durably accepted it - **a `4xx` is terminal and we stop retrying**, and anything slower
        than 10s is treated as a failure. See the Webhooks section above for the full contract.'
      parameters:
      - name: X-Eqomos-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - order.refund.settled
      - name: X-Eqomos-Event-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: The dedupe key.
      - name: X-Eqomos-Timestamp
        in: header
        required: true
        schema:
          type: integer
        description: Unix seconds. Reject if more than 5 minutes old.
      - name: X-Eqomos-Signature
        in: header
        required: true
        schema:
          type: string
        description: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>" keyed with your webhook secret>.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                  description: Stable across every retry of this occurrence. DEDUPE ON THIS.
                event:
                  type: string
                  enum:
                  - order.refund.settled
                occurredAt:
                  type: string
                  format: date-time
                  description: ISO-8601 UTC, when the change happened - not when it was sent.
                id:
                  type: string
                  description: The id of the resource the event is about.
                status:
                  description: The refunded status id.
              required:
              - eventId
              - event
              - occurredAt
              - id
            example:
              eventId: 297fa9be-b7ea-4919-93b4-a8de04164cd6
              event: order.refund.settled
              occurredAt: '2026-07-29T11:20:11Z'
              id: AGS496
              status: 112
      responses:
        '200':
          description: Accepted. Any 2xx ends delivery.
        '400':
          description: TERMINAL - we stop retrying. Only reply 4xx if you will never accept it.
        '500':
          description: Retried on the documented backoff.
  catalog.sku.published:
    post:
      tags:
      - Webhooks
      summary: A SKU became visible on your tenant.
      description: 'Sent when: A SKU became visible on your tenant.


        Verify `X-Eqomos-Signature` and reject a timestamp older than 5 minutes; dedupe on `eventId`; do not assume ordering.
        Reply `2xx` as soon as you have durably accepted it - **a `4xx` is terminal and we stop retrying**, and anything slower
        than 10s is treated as a failure. See the Webhooks section above for the full contract.'
      parameters:
      - name: X-Eqomos-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - catalog.sku.published
      - name: X-Eqomos-Event-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: The dedupe key.
      - name: X-Eqomos-Timestamp
        in: header
        required: true
        schema:
          type: integer
        description: Unix seconds. Reject if more than 5 minutes old.
      - name: X-Eqomos-Signature
        in: header
        required: true
        schema:
          type: string
        description: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>" keyed with your webhook secret>.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                  description: Stable across every retry of this occurrence. DEDUPE ON THIS.
                event:
                  type: string
                  enum:
                  - catalog.sku.published
                occurredAt:
                  type: string
                  format: date-time
                  description: ISO-8601 UTC, when the change happened - not when it was sent.
                id:
                  type: string
                  description: The id of the resource the event is about.
                skuCode:
                  description: The SKU code.
              required:
              - eventId
              - event
              - occurredAt
              - id
            example:
              eventId: 297fa9be-b7ea-4919-93b4-a8de04164cd6
              event: catalog.sku.published
              occurredAt: '2026-07-29T11:20:11Z'
              id: AGS496
              skuCode: AWMIX450
      responses:
        '200':
          description: Accepted. Any 2xx ends delivery.
        '400':
          description: TERMINAL - we stop retrying. Only reply 4xx if you will never accept it.
        '500':
          description: Retried on the documented backoff.
  catalog.sku.unpublished:
    post:
      tags:
      - Webhooks
      summary: A SKU stopped being visible on your tenant.
      description: 'Sent when: A SKU stopped being visible on your tenant.


        Verify `X-Eqomos-Signature` and reject a timestamp older than 5 minutes; dedupe on `eventId`; do not assume ordering.
        Reply `2xx` as soon as you have durably accepted it - **a `4xx` is terminal and we stop retrying**, and anything slower
        than 10s is treated as a failure. See the Webhooks section above for the full contract.'
      parameters:
      - name: X-Eqomos-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - catalog.sku.unpublished
      - name: X-Eqomos-Event-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: The dedupe key.
      - name: X-Eqomos-Timestamp
        in: header
        required: true
        schema:
          type: integer
        description: Unix seconds. Reject if more than 5 minutes old.
      - name: X-Eqomos-Signature
        in: header
        required: true
        schema:
          type: string
        description: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>" keyed with your webhook secret>.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                  description: Stable across every retry of this occurrence. DEDUPE ON THIS.
                event:
                  type: string
                  enum:
                  - catalog.sku.unpublished
                occurredAt:
                  type: string
                  format: date-time
                  description: ISO-8601 UTC, when the change happened - not when it was sent.
                id:
                  type: string
                  description: The id of the resource the event is about.
                skuCode:
                  description: The SKU code.
              required:
              - eventId
              - event
              - occurredAt
              - id
            example:
              eventId: 297fa9be-b7ea-4919-93b4-a8de04164cd6
              event: catalog.sku.unpublished
              occurredAt: '2026-07-29T11:20:11Z'
              id: AGS496
              skuCode: AWMIX450
      responses:
        '200':
          description: Accepted. Any 2xx ends delivery.
        '400':
          description: TERMINAL - we stop retrying. Only reply 4xx if you will never accept it.
        '500':
          description: Retried on the documented backoff.
  catalog.price.changed:
    post:
      tags:
      - Webhooks
      summary: A published SKU's live price changed.
      description: 'Sent when: A published SKU''s live price changed.


        Verify `X-Eqomos-Signature` and reject a timestamp older than 5 minutes; dedupe on `eventId`; do not assume ordering.
        Reply `2xx` as soon as you have durably accepted it - **a `4xx` is terminal and we stop retrying**, and anything slower
        than 10s is treated as a failure. See the Webhooks section above for the full contract.'
      parameters:
      - name: X-Eqomos-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - catalog.price.changed
      - name: X-Eqomos-Event-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: The dedupe key.
      - name: X-Eqomos-Timestamp
        in: header
        required: true
        schema:
          type: integer
        description: Unix seconds. Reject if more than 5 minutes old.
      - name: X-Eqomos-Signature
        in: header
        required: true
        schema:
          type: string
        description: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>" keyed with your webhook secret>.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                  description: Stable across every retry of this occurrence. DEDUPE ON THIS.
                event:
                  type: string
                  enum:
                  - catalog.price.changed
                occurredAt:
                  type: string
                  format: date-time
                  description: ISO-8601 UTC, when the change happened - not when it was sent.
                id:
                  type: string
                  description: The id of the resource the event is about.
                price:
                  description: The new effective price (offer price when set, else MRP).
              required:
              - eventId
              - event
              - occurredAt
              - id
            example:
              eventId: 297fa9be-b7ea-4919-93b4-a8de04164cd6
              event: catalog.price.changed
              occurredAt: '2026-07-29T11:20:11Z'
              id: AGS496
              price: 2499.0
      responses:
        '200':
          description: Accepted. Any 2xx ends delivery.
        '400':
          description: TERMINAL - we stop retrying. Only reply 4xx if you will never accept it.
        '500':
          description: Retried on the documented backoff.
  servicedesk.booking.confirmed:
    post:
      tags:
      - Webhooks
      summary: A booking you created was confirmed against its held slot.
      description: 'Sent when: A booking you created was confirmed against its held slot.


        Verify `X-Eqomos-Signature` and reject a timestamp older than 5 minutes; dedupe on `eventId`; do not assume ordering.
        Reply `2xx` as soon as you have durably accepted it - **a `4xx` is terminal and we stop retrying**, and anything slower
        than 10s is treated as a failure. See the Webhooks section above for the full contract.'
      parameters:
      - name: X-Eqomos-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - servicedesk.booking.confirmed
      - name: X-Eqomos-Event-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: The dedupe key.
      - name: X-Eqomos-Timestamp
        in: header
        required: true
        schema:
          type: integer
        description: Unix seconds. Reject if more than 5 minutes old.
      - name: X-Eqomos-Signature
        in: header
        required: true
        schema:
          type: string
        description: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>" keyed with your webhook secret>.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                  description: Stable across every retry of this occurrence. DEDUPE ON THIS.
                event:
                  type: string
                  enum:
                  - servicedesk.booking.confirmed
                occurredAt:
                  type: string
                  format: date-time
                  description: ISO-8601 UTC, when the change happened - not when it was sent.
                id:
                  type: string
                  description: The id of the resource the event is about.
                status:
                  description: The booking's new status id. Call /servicedesk/booking/detail for its name.
              required:
              - eventId
              - event
              - occurredAt
              - id
            example:
              eventId: 297fa9be-b7ea-4919-93b4-a8de04164cd6
              event: servicedesk.booking.confirmed
              occurredAt: '2026-07-29T11:20:11Z'
              id: AGS496
              status: 4102
      responses:
        '200':
          description: Accepted. Any 2xx ends delivery.
        '400':
          description: TERMINAL - we stop retrying. Only reply 4xx if you will never accept it.
        '500':
          description: Retried on the documented backoff.
  servicedesk.booking.cancelled:
    post:
      tags:
      - Webhooks
      summary: A booking you created was cancelled - the booking's own lifecycle, not a refund.
      description: 'Sent when: A booking you created was cancelled - the booking''s own lifecycle, not a refund.


        Verify `X-Eqomos-Signature` and reject a timestamp older than 5 minutes; dedupe on `eventId`; do not assume ordering.
        Reply `2xx` as soon as you have durably accepted it - **a `4xx` is terminal and we stop retrying**, and anything slower
        than 10s is treated as a failure. See the Webhooks section above for the full contract.'
      parameters:
      - name: X-Eqomos-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - servicedesk.booking.cancelled
      - name: X-Eqomos-Event-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: The dedupe key.
      - name: X-Eqomos-Timestamp
        in: header
        required: true
        schema:
          type: integer
        description: Unix seconds. Reject if more than 5 minutes old.
      - name: X-Eqomos-Signature
        in: header
        required: true
        schema:
          type: string
        description: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>" keyed with your webhook secret>.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                  description: Stable across every retry of this occurrence. DEDUPE ON THIS.
                event:
                  type: string
                  enum:
                  - servicedesk.booking.cancelled
                occurredAt:
                  type: string
                  format: date-time
                  description: ISO-8601 UTC, when the change happened - not when it was sent.
                id:
                  type: string
                  description: The id of the resource the event is about.
                status:
                  description: The booking's new status id.
              required:
              - eventId
              - event
              - occurredAt
              - id
            example:
              eventId: 297fa9be-b7ea-4919-93b4-a8de04164cd6
              event: servicedesk.booking.cancelled
              occurredAt: '2026-07-29T11:20:11Z'
              id: AGS496
              status: 4106
      responses:
        '200':
          description: Accepted. Any 2xx ends delivery.
        '400':
          description: TERMINAL - we stop retrying. Only reply 4xx if you will never accept it.
        '500':
          description: Retried on the documented backoff.
  servicedesk.booking.rescheduled:
    post:
      tags:
      - Webhooks
      summary: A booking you created moved to a different slot.
      description: 'Sent when: A booking you created moved to a different slot.


        Verify `X-Eqomos-Signature` and reject a timestamp older than 5 minutes; dedupe on `eventId`; do not assume ordering.
        Reply `2xx` as soon as you have durably accepted it - **a `4xx` is terminal and we stop retrying**, and anything slower
        than 10s is treated as a failure. See the Webhooks section above for the full contract.'
      parameters:
      - name: X-Eqomos-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - servicedesk.booking.rescheduled
      - name: X-Eqomos-Event-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: The dedupe key.
      - name: X-Eqomos-Timestamp
        in: header
        required: true
        schema:
          type: integer
        description: Unix seconds. Reject if more than 5 minutes old.
      - name: X-Eqomos-Signature
        in: header
        required: true
        schema:
          type: string
        description: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>" keyed with your webhook secret>.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                  description: Stable across every retry of this occurrence. DEDUPE ON THIS.
                event:
                  type: string
                  enum:
                  - servicedesk.booking.rescheduled
                occurredAt:
                  type: string
                  format: date-time
                  description: ISO-8601 UTC, when the change happened - not when it was sent.
                id:
                  type: string
                  description: The id of the resource the event is about.
                status:
                  description: The booking's status id - a reschedule ends back at CONFIRMED.
              required:
              - eventId
              - event
              - occurredAt
              - id
            example:
              eventId: 297fa9be-b7ea-4919-93b4-a8de04164cd6
              event: servicedesk.booking.rescheduled
              occurredAt: '2026-07-29T11:20:11Z'
              id: AGS496
              status: 4102
      responses:
        '200':
          description: Accepted. Any 2xx ends delivery.
        '400':
          description: TERMINAL - we stop retrying. Only reply 4xx if you will never accept it.
        '500':
          description: Retried on the documented backoff.
  servicedesk.booking.noshow:
    post:
      tags:
      - Webhooks
      summary: A booking you created was marked no-show.
      description: 'Sent when: A booking you created was marked no-show.


        Verify `X-Eqomos-Signature` and reject a timestamp older than 5 minutes; dedupe on `eventId`; do not assume ordering.
        Reply `2xx` as soon as you have durably accepted it - **a `4xx` is terminal and we stop retrying**, and anything slower
        than 10s is treated as a failure. See the Webhooks section above for the full contract.'
      parameters:
      - name: X-Eqomos-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - servicedesk.booking.noshow
      - name: X-Eqomos-Event-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
        description: The dedupe key.
      - name: X-Eqomos-Timestamp
        in: header
        required: true
        schema:
          type: integer
        description: Unix seconds. Reject if more than 5 minutes old.
      - name: X-Eqomos-Signature
        in: header
        required: true
        schema:
          type: string
        description: t=<ts>,v1=<hex HMAC-SHA256 of "<ts>.<raw body>" keyed with your webhook secret>.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                eventId:
                  type: string
                  format: uuid
                  description: Stable across every retry of this occurrence. DEDUPE ON THIS.
                event:
                  type: string
                  enum:
                  - servicedesk.booking.noshow
                occurredAt:
                  type: string
                  format: date-time
                  description: ISO-8601 UTC, when the change happened - not when it was sent.
                id:
                  type: string
                  description: The id of the resource the event is about.
                status:
                  description: The booking's new status id.
              required:
              - eventId
              - event
              - occurredAt
              - id
            example:
              eventId: 297fa9be-b7ea-4919-93b4-a8de04164cd6
              event: servicedesk.booking.noshow
              occurredAt: '2026-07-29T11:20:11Z'
              id: AGS496
              status: 4107
      responses:
        '200':
          description: Accepted. Any 2xx ends delivery.
        '400':
          description: TERMINAL - we stop retrying. Only reply 4xx if you will never accept it.
        '500':
          description: Retried on the documented backoff.
