{
  "openapi": "3.1.0",
  "info": {
    "title": "API de Campanhas",
    "description": "Campanhas de desconto do marketplace: calendário, anúncios elegíveis e adesão da loja.",
    "version": "1.0.0",
    "contact": {
      "name": "UniSupri"
    }
  },
  "servers": [
    {
      "url": "https://api.unisupri.com",
      "description": "Produção"
    },
    {
      "url": "https://api.sandbox.samdevel.com.br",
      "description": "Sandbox (ambiente de homologação)"
    }
  ],
  "tags": [
    {
      "name": "Campanhas",
      "description": "Campanhas de desconto criadas pelo marketplace, em que a loja opta por entrar com os anúncios que quiser.\n\n**Como funciona:** a plataforma monta a campanha (nome, vigência, prazo de adesão e o desconto em `rules.coupon_config`). A loja consulta o calendário, vê quais anúncios são elegíveis e inscreve os que quiser pelo opt-in. Durante a vigência, o desconto é aplicado pela plataforma nos anúncios inscritos.\n\n**Identificador:** as rotas usam o `id` numérico da campanha, o mesmo que vem no calendário. O `uid` também é devolvido, mas não é aceito nas rotas.\n\n**Tipos:** `standard` é desconto comum; `collective_buying` é compra coletiva, que represa o pedido até a campanha encerrar (ver o guia de [Compra coletiva](/guia/pedidos-coletiva)).\n\nEscopos exigidos: `store_products_read` para consultar e `store_products_write` para entrar e sair de campanha."
    }
  ],
  "paths": {
    "/api/seller/discounts/campaigns/calendar": {
      "get": {
        "tags": [
          "Campanhas"
        ],
        "summary": "Calendário de Campanhas",
        "description": "Lista paginada das campanhas do marketplace que ainda não terminaram (`ends_at` no futuro), da mais próxima para a mais distante. Campanhas canceladas ficam de fora; as que ainda estão em montagem aparecem com `status: \"draft\"`.\n\nÉ por aqui que você descobre o `id` de cada campanha, usado em todas as outras rotas.\n\nResponde no envelope paginado padrão: itens em `data.data[]`, paginação em `data.meta.pagination`.\n\nExige o escopo `store_products_read`.",
        "security": [
          {
            "integrationToken": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1
            },
            "description": "Página."
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 15
            },
            "description": "Itens por página. Default `15`."
          }
        ],
        "responses": {
          "200": {
            "description": "Campanhas em aberto",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message_code": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "meta": {
                          "type": "object",
                          "properties": {
                            "search_query": {
                              "type": "string"
                            },
                            "filters": {
                              "description": "Filtros recebidos na requisição"
                            },
                            "pagination": {
                              "type": "object",
                              "properties": {
                                "page": {
                                  "type": "integer"
                                },
                                "per_page": {
                                  "type": "integer"
                                },
                                "last_page": {
                                  "type": "integer"
                                },
                                "has_prev_page": {
                                  "type": "boolean"
                                },
                                "has_next_page": {
                                  "type": "boolean"
                                },
                                "records": {
                                  "type": "object",
                                  "properties": {
                                    "from": {
                                      "type": "integer"
                                    },
                                    "to": {
                                      "type": "integer"
                                    },
                                    "records": {
                                      "type": "integer",
                                      "description": "Total de registros"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "integer",
                                "description": "Identificador da campanha. **É este valor que vai em `{id}` nas outras rotas** — as rotas de campanha não aceitam o `uid`."
                              },
                              "uid": {
                                "type": "string",
                                "description": "ULID público da campanha."
                              },
                              "name": {
                                "type": "string"
                              },
                              "slug": {
                                "type": "string"
                              },
                              "type": {
                                "type": "string",
                                "enum": [
                                  "standard",
                                  "collective_buying"
                                ],
                                "description": "`standard` é desconto comum. `collective_buying` é compra coletiva: o pedido fica represado até a campanha encerrar (ver [Compra coletiva](/guia/pedidos-coletiva))."
                              },
                              "status": {
                                "type": "string",
                                "enum": [
                                  "draft",
                                  "active",
                                  "finished",
                                  "cancelled"
                                ],
                                "description": "`draft` é campanha ainda em montagem pela plataforma; `active` está no ar. Adesão é recusada em `finished` e `cancelled`."
                              },
                              "starts_at": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true,
                                "description": "Início da vigência do desconto."
                              },
                              "ends_at": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true,
                                "description": "Fim da vigência."
                              },
                              "opt_in_deadline": {
                                "type": "string",
                                "format": "date-time",
                                "nullable": true,
                                "description": "Prazo para aderir. Depois dele o opt-in devolve `422 CAMPAIGN_OPT_IN_CLOSED`. `null` significa sem prazo."
                              },
                              "primary_color": {
                                "type": "string",
                                "nullable": true,
                                "description": "Cor da identidade visual, em hexadecimal."
                              },
                              "secondary_color": {
                                "type": "string",
                                "nullable": true
                              },
                              "has_landing_page": {
                                "type": "boolean",
                                "description": "A campanha tem página própria na vitrine."
                              },
                              "landing_page_slug": {
                                "type": "string",
                                "nullable": true
                              },
                              "show_in_menu": {
                                "type": "boolean",
                                "description": "A campanha aparece no menu da vitrine."
                              },
                              "rules": {
                                "type": "object",
                                "nullable": true,
                                "description": "Configuração da campanha. `coupon_config.discount_type` (`percentage` ou `fixed`) e `coupon_config.value` são o desconto que a plataforma aplica aos anúncios inscritos."
                              },
                              "created_at": {
                                "type": "string",
                                "format": "date-time"
                              },
                              "updated_at": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message_code": "SUCCESS",
                  "data": {
                    "meta": {
                      "search_query": "",
                      "filters": [],
                      "pagination": {
                        "page": 1,
                        "per_page": 15,
                        "last_page": 1,
                        "has_prev_page": false,
                        "has_next_page": false,
                        "records": {
                          "from": 1,
                          "to": 1,
                          "records": 1
                        }
                      }
                    },
                    "data": [
                      {
                        "id": 128,
                        "uid": "01KS3PRGYQHHDCRYNRXGSZHP41",
                        "name": "Black Friday 2026",
                        "slug": "black-friday-2026",
                        "type": "standard",
                        "status": "active",
                        "starts_at": "2026-11-27T00:00:00.000000Z",
                        "ends_at": "2026-11-30T23:59:59.000000Z",
                        "opt_in_deadline": "2026-11-20T23:59:59.000000Z",
                        "primary_color": "#111111",
                        "secondary_color": "#F5C518",
                        "has_landing_page": true,
                        "landing_page_slug": "black-friday",
                        "show_in_menu": true,
                        "rules": {
                          "coupon_config": {
                            "discount_type": "percentage",
                            "value": 15
                          }
                        },
                        "created_at": "2026-09-01T12:00:00.000000Z",
                        "updated_at": "2026-09-01T12:00:00.000000Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token não fornecido, inválido ou expirado",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 401,
                  "message_code": "UNAUTHORIZED",
                  "description": "A autenticação é necessária e falhou ou não foi fornecida.",
                  "data": [],
                  "errors": [
                    "O access_token da loja é obrigatório no cabeçalho Authorization"
                  ],
                  "meta": []
                }
              }
            }
          },
          "403": {
            "description": "Falta um escopo exigido pela rota",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 403,
                  "message_code": "FORBIDDEN",
                  "description": "O servidor entende a requisição, mas se recusa a autorizá-la.",
                  "data": [],
                  "errors": [
                    "Token de integração sem permissão para este recurso (abilities ausentes: store_products_write)"
                  ],
                  "meta": []
                }
              }
            }
          }
        }
      }
    },
    "/api/seller/discounts/campaigns/summary": {
      "get": {
        "tags": [
          "Campanhas"
        ],
        "summary": "Resumo das Campanhas da Loja",
        "description": "Números agregados para o painel: quantas campanhas estão em aberto, em quantas a loja já entrou, quantos anúncios estão inscritos e quais prazos de adesão vencem primeiro.\n\nExige o escopo `store_products_read`.",
        "security": [
          {
            "integrationToken": []
          }
        ],
        "responses": {
          "200": {
            "description": "Resumo da loja",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message_code": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "active_campaigns": {
                          "type": "integer",
                          "description": "Campanhas do marketplace ainda em aberto (não canceladas, com `ends_at` no futuro). É o mesmo conjunto do calendário, não só as de status `active`."
                        },
                        "joined_campaigns": {
                          "type": "integer",
                          "description": "Campanhas distintas em que a loja tem alguma inscrição."
                        },
                        "enrolled_products": {
                          "type": "integer",
                          "description": "Total de anúncios inscritos pela loja, somando todas as campanhas."
                        },
                        "upcoming_deadlines": {
                          "type": "array",
                          "description": "Até 5 campanhas com prazo de adesão ainda aberto, do mais próximo ao mais distante.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "integer"
                              },
                              "name": {
                                "type": "string"
                              },
                              "opt_in_deadline": {
                                "type": "string",
                                "format": "date-time"
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message_code": "SUCCESS",
                  "data": {
                    "active_campaigns": 4,
                    "joined_campaigns": 2,
                    "enrolled_products": 37,
                    "upcoming_deadlines": [
                      {
                        "id": 128,
                        "name": "Black Friday 2026",
                        "opt_in_deadline": "2026-11-20T23:59:59.000000Z"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token não fornecido, inválido ou expirado",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 401,
                  "message_code": "UNAUTHORIZED",
                  "description": "A autenticação é necessária e falhou ou não foi fornecida.",
                  "data": [],
                  "errors": [
                    "O access_token da loja é obrigatório no cabeçalho Authorization"
                  ],
                  "meta": []
                }
              }
            }
          },
          "403": {
            "description": "Falta um escopo exigido pela rota",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 403,
                  "message_code": "FORBIDDEN",
                  "description": "O servidor entende a requisição, mas se recusa a autorizá-la.",
                  "data": [],
                  "errors": [
                    "Token de integração sem permissão para este recurso (abilities ausentes: store_products_write)"
                  ],
                  "meta": []
                }
              }
            }
          }
        }
      }
    },
    "/api/seller/discounts/campaigns/{id}": {
      "get": {
        "tags": [
          "Campanhas"
        ],
        "summary": "Detalhes da Campanha",
        "description": "Retorna a campanha pelo `id`. Use para ler o desconto que será aplicado (`rules.coupon_config`) e o prazo de adesão antes de inscrever anúncios.\n\nExige o escopo `store_products_read`.",
        "security": [
          {
            "integrationToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 128
            },
            "description": "`id` da campanha, como vem no calendário. Não é o `uid`."
          }
        ],
        "responses": {
          "200": {
            "description": "Detalhes da campanha",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message_code": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "Identificador da campanha. **É este valor que vai em `{id}` nas outras rotas** — as rotas de campanha não aceitam o `uid`."
                        },
                        "uid": {
                          "type": "string",
                          "description": "ULID público da campanha."
                        },
                        "name": {
                          "type": "string"
                        },
                        "slug": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "standard",
                            "collective_buying"
                          ],
                          "description": "`standard` é desconto comum. `collective_buying` é compra coletiva: o pedido fica represado até a campanha encerrar (ver [Compra coletiva](/guia/pedidos-coletiva))."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "draft",
                            "active",
                            "finished",
                            "cancelled"
                          ],
                          "description": "`draft` é campanha ainda em montagem pela plataforma; `active` está no ar. Adesão é recusada em `finished` e `cancelled`."
                        },
                        "starts_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Início da vigência do desconto."
                        },
                        "ends_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Fim da vigência."
                        },
                        "opt_in_deadline": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true,
                          "description": "Prazo para aderir. Depois dele o opt-in devolve `422 CAMPAIGN_OPT_IN_CLOSED`. `null` significa sem prazo."
                        },
                        "primary_color": {
                          "type": "string",
                          "nullable": true,
                          "description": "Cor da identidade visual, em hexadecimal."
                        },
                        "secondary_color": {
                          "type": "string",
                          "nullable": true
                        },
                        "has_landing_page": {
                          "type": "boolean",
                          "description": "A campanha tem página própria na vitrine."
                        },
                        "landing_page_slug": {
                          "type": "string",
                          "nullable": true
                        },
                        "show_in_menu": {
                          "type": "boolean",
                          "description": "A campanha aparece no menu da vitrine."
                        },
                        "rules": {
                          "type": "object",
                          "nullable": true,
                          "description": "Configuração da campanha. `coupon_config.discount_type` (`percentage` ou `fixed`) e `coupon_config.value` são o desconto que a plataforma aplica aos anúncios inscritos."
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "updated_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message_code": "SUCCESS",
                  "data": {
                    "id": 128,
                    "uid": "01KS3PRGYQHHDCRYNRXGSZHP41",
                    "name": "Black Friday 2026",
                    "slug": "black-friday-2026",
                    "type": "standard",
                    "status": "active",
                    "starts_at": "2026-11-27T00:00:00.000000Z",
                    "ends_at": "2026-11-30T23:59:59.000000Z",
                    "opt_in_deadline": "2026-11-20T23:59:59.000000Z",
                    "primary_color": "#111111",
                    "secondary_color": "#F5C518",
                    "has_landing_page": true,
                    "landing_page_slug": "black-friday",
                    "show_in_menu": true,
                    "rules": {
                      "coupon_config": {
                        "discount_type": "percentage",
                        "value": 15
                      }
                    },
                    "created_at": "2026-09-01T12:00:00.000000Z",
                    "updated_at": "2026-09-01T12:00:00.000000Z"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token não fornecido, inválido ou expirado",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 401,
                  "message_code": "UNAUTHORIZED",
                  "description": "A autenticação é necessária e falhou ou não foi fornecida.",
                  "data": [],
                  "errors": [
                    "O access_token da loja é obrigatório no cabeçalho Authorization"
                  ],
                  "meta": []
                }
              }
            }
          },
          "403": {
            "description": "Falta um escopo exigido pela rota",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 403,
                  "message_code": "FORBIDDEN",
                  "description": "O servidor entende a requisição, mas se recusa a autorizá-la.",
                  "data": [],
                  "errors": [
                    "Token de integração sem permissão para este recurso (abilities ausentes: store_products_write)"
                  ],
                  "meta": []
                }
              }
            }
          },
          "404": {
            "description": "Campanha inexistente",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 404,
                  "message_code": "NOT_FOUND",
                  "description": "O recurso solicitado não foi encontrado.",
                  "data": [],
                  "errors": [
                    "Recurso não encontrado."
                  ],
                  "meta": []
                }
              }
            }
          }
        }
      }
    },
    "/api/seller/discounts/campaigns/{id}/eligible-products": {
      "get": {
        "tags": [
          "Campanhas"
        ],
        "summary": "Anúncios Elegíveis",
        "description": "Lista paginada dos anúncios da loja que **ainda não estão** nesta campanha e podem ser inscritos: ofertas ativas da loja, já descontando o que foi inscrito.\n\nCada item traz `discount_preview`, o preço que o anúncio ficaria com o desconto da campanha. Vem `null` quando a campanha não tem desconto configurado ou o anúncio não tem preço.\n\nExige o escopo `store_products_read`.",
        "security": [
          {
            "integrationToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 128
            },
            "description": "`id` da campanha, como vem no calendário. Não é o `uid`."
          },
          {
            "name": "search",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "Busca por título ou por `item_id` do anúncio."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1
            },
            "description": "Página."
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 15
            },
            "description": "Itens por página. Default `15`."
          }
        ],
        "responses": {
          "200": {
            "description": "Anúncios que podem entrar na campanha",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message_code": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "meta": {
                          "type": "object",
                          "properties": {
                            "search_query": {
                              "type": "string"
                            },
                            "filters": {
                              "description": "Filtros recebidos na requisição"
                            },
                            "pagination": {
                              "type": "object",
                              "properties": {
                                "page": {
                                  "type": "integer"
                                },
                                "per_page": {
                                  "type": "integer"
                                },
                                "last_page": {
                                  "type": "integer"
                                },
                                "has_prev_page": {
                                  "type": "boolean"
                                },
                                "has_next_page": {
                                  "type": "boolean"
                                },
                                "records": {
                                  "type": "object",
                                  "properties": {
                                    "from": {
                                      "type": "integer"
                                    },
                                    "to": {
                                      "type": "integer"
                                    },
                                    "records": {
                                      "type": "integer",
                                      "description": "Total de registros"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "item_id": {
                                "type": "string",
                                "description": "Identificador do anúncio (ex.: `US-0000000001234`). É o valor a enviar em `publication_ids` no opt-in."
                              },
                              "title": {
                                "type": "string"
                              },
                              "image": {
                                "type": "string",
                                "nullable": true,
                                "description": "URL da thumbnail do anúncio, quando houver."
                              },
                              "price": {
                                "type": "number",
                                "nullable": true,
                                "description": "Menor preço unitário ofertado pela loja neste anúncio."
                              },
                              "discount_preview": {
                                "type": "number",
                                "nullable": true,
                                "description": "Preço estimado com o desconto da campanha."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message_code": "SUCCESS",
                  "data": {
                    "meta": {
                      "search_query": "",
                      "filters": [],
                      "pagination": {
                        "page": 1,
                        "per_page": 15,
                        "last_page": 1,
                        "has_prev_page": false,
                        "has_next_page": false,
                        "records": {
                          "from": 1,
                          "to": 1,
                          "records": 1
                        }
                      }
                    },
                    "data": [
                      {
                        "item_id": "US-0000000001234",
                        "title": "Camiseta algodão 30.1 branca",
                        "image": "https://cdn.example.com/thumb.jpg",
                        "price": 59.9,
                        "discount_preview": 50.92
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token não fornecido, inválido ou expirado",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 401,
                  "message_code": "UNAUTHORIZED",
                  "description": "A autenticação é necessária e falhou ou não foi fornecida.",
                  "data": [],
                  "errors": [
                    "O access_token da loja é obrigatório no cabeçalho Authorization"
                  ],
                  "meta": []
                }
              }
            }
          },
          "403": {
            "description": "Falta um escopo exigido pela rota",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 403,
                  "message_code": "FORBIDDEN",
                  "description": "O servidor entende a requisição, mas se recusa a autorizá-la.",
                  "data": [],
                  "errors": [
                    "Token de integração sem permissão para este recurso (abilities ausentes: store_products_write)"
                  ],
                  "meta": []
                }
              }
            }
          },
          "404": {
            "description": "Campanha inexistente",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 404,
                  "message_code": "NOT_FOUND",
                  "description": "O recurso solicitado não foi encontrado.",
                  "data": [],
                  "errors": [
                    "Recurso não encontrado."
                  ],
                  "meta": []
                }
              }
            }
          }
        }
      }
    },
    "/api/seller/discounts/campaigns/{id}/my-products": {
      "get": {
        "tags": [
          "Campanhas"
        ],
        "summary": "Anúncios Inscritos",
        "description": "Lista paginada dos anúncios que a loja já inscreveu nesta campanha, com o preço promocional autorizado no momento da adesão.\n\nExige o escopo `store_products_read`.",
        "security": [
          {
            "integrationToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 128
            },
            "description": "`id` da campanha, como vem no calendário. Não é o `uid`."
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 1
            },
            "description": "Página."
          },
          {
            "name": "per_page",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 15
            },
            "description": "Itens por página. Default `15`."
          }
        ],
        "responses": {
          "200": {
            "description": "Anúncios inscritos pela loja",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message_code": {
                      "type": "string"
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "meta": {
                          "type": "object",
                          "properties": {
                            "search_query": {
                              "type": "string"
                            },
                            "filters": {
                              "description": "Filtros recebidos na requisição"
                            },
                            "pagination": {
                              "type": "object",
                              "properties": {
                                "page": {
                                  "type": "integer"
                                },
                                "per_page": {
                                  "type": "integer"
                                },
                                "last_page": {
                                  "type": "integer"
                                },
                                "has_prev_page": {
                                  "type": "boolean"
                                },
                                "has_next_page": {
                                  "type": "boolean"
                                },
                                "records": {
                                  "type": "object",
                                  "properties": {
                                    "from": {
                                      "type": "integer"
                                    },
                                    "to": {
                                      "type": "integer"
                                    },
                                    "records": {
                                      "type": "integer",
                                      "description": "Total de registros"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "publication_id": {
                                "type": "string",
                                "nullable": true,
                                "description": "`item_id` do anúncio inscrito."
                              },
                              "title": {
                                "type": "string",
                                "nullable": true
                              },
                              "image": {
                                "type": "string",
                                "nullable": true
                              },
                              "authorized_discount_price": {
                                "type": "string",
                                "nullable": true,
                                "description": "Preço promocional calculado **na adesão**. Não é recalculado se você mudar o preço do anúncio depois."
                              },
                              "status": {
                                "type": "string",
                                "description": "Situação da inscrição. O opt-in pela API grava `ACCEPTED`."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message_code": "SUCCESS",
                  "data": {
                    "meta": {
                      "search_query": "",
                      "filters": [],
                      "pagination": {
                        "page": 1,
                        "per_page": 15,
                        "last_page": 1,
                        "has_prev_page": false,
                        "has_next_page": false,
                        "records": {
                          "from": 1,
                          "to": 1,
                          "records": 1
                        }
                      }
                    },
                    "data": [
                      {
                        "publication_id": "US-0000000001234",
                        "title": "Camiseta algodão 30.1 branca",
                        "image": "https://cdn.example.com/thumb.jpg",
                        "authorized_discount_price": "50.92",
                        "status": "ACCEPTED"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token não fornecido, inválido ou expirado",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 401,
                  "message_code": "UNAUTHORIZED",
                  "description": "A autenticação é necessária e falhou ou não foi fornecida.",
                  "data": [],
                  "errors": [
                    "O access_token da loja é obrigatório no cabeçalho Authorization"
                  ],
                  "meta": []
                }
              }
            }
          },
          "403": {
            "description": "Falta um escopo exigido pela rota",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 403,
                  "message_code": "FORBIDDEN",
                  "description": "O servidor entende a requisição, mas se recusa a autorizá-la.",
                  "data": [],
                  "errors": [
                    "Token de integração sem permissão para este recurso (abilities ausentes: store_products_write)"
                  ],
                  "meta": []
                }
              }
            }
          },
          "404": {
            "description": "Campanha inexistente",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 404,
                  "message_code": "NOT_FOUND",
                  "description": "O recurso solicitado não foi encontrado.",
                  "data": [],
                  "errors": [
                    "Recurso não encontrado."
                  ],
                  "meta": []
                }
              }
            }
          }
        }
      }
    },
    "/api/seller/discounts/campaigns/{id}/opt-in": {
      "post": {
        "tags": [
          "Campanhas"
        ],
        "summary": "Inscrever Anúncios na Campanha",
        "description": "Inscreve anúncios da loja na campanha. A chamada é **idempotente por anúncio**: reenviar um `item_id` já inscrito atualiza a inscrição em vez de duplicar.\n\nO preço promocional (`authorized_discount_price`) é calculado no momento da adesão, a partir do preço vigente do anúncio e do desconto da campanha. **Mudar o preço do anúncio depois não recalcula esse valor** — se o preço mudou, refaça o opt-in.\n\nExige o escopo `store_products_write`.",
        "security": [
          {
            "integrationToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 128
            },
            "description": "`id` da campanha, como vem no calendário. Não é o `uid`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "publication_ids"
                ],
                "properties": {
                  "publication_ids": {
                    "type": "array",
                    "minItems": 1,
                    "description": "`item_id` dos anúncios a inscrever, no formato `XX-0000000000000` (2 a 5 letras maiúsculas, hífen, 13 dígitos). Pegue os valores em `eligible-products`.",
                    "items": {
                      "type": "string",
                      "pattern": "^[A-Z]{2,5}-\\d{13}$"
                    }
                  }
                }
              },
              "example": {
                "publication_ids": [
                  "US-0000000001234",
                  "US-0000000005678"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Anúncios inscritos",
            "content": {
              "application/json": {
                "example": {
                  "success": true,
                  "message_code": "SUCCESS",
                  "data": {
                    "message": "OPT_IN_SUCCESSFUL"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Token não fornecido, inválido ou expirado",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 401,
                  "message_code": "UNAUTHORIZED",
                  "description": "A autenticação é necessária e falhou ou não foi fornecida.",
                  "data": [],
                  "errors": [
                    "O access_token da loja é obrigatório no cabeçalho Authorization"
                  ],
                  "meta": []
                }
              }
            }
          },
          "403": {
            "description": "Falta um escopo exigido pela rota",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 403,
                  "message_code": "FORBIDDEN",
                  "description": "O servidor entende a requisição, mas se recusa a autorizá-la.",
                  "data": [],
                  "errors": [
                    "Token de integração sem permissão para este recurso (abilities ausentes: store_products_write)"
                  ],
                  "meta": []
                }
              }
            }
          },
          "404": {
            "description": "Campanha inexistente",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 404,
                  "message_code": "NOT_FOUND",
                  "description": "O recurso solicitado não foi encontrado.",
                  "data": [],
                  "errors": [
                    "Recurso não encontrado."
                  ],
                  "meta": []
                }
              }
            }
          },
          "422": {
            "description": "Adesão recusada ou payload inválido",
            "content": {
              "application/json": {
                "examples": {
                  "prazo_encerrado": {
                    "summary": "Passou do `opt_in_deadline`",
                    "value": {
                      "success": false,
                      "code": 422,
                      "message_code": "CAMPAIGN_OPT_IN_CLOSED",
                      "description": "O prazo de adesão a esta campanha já encerrou.",
                      "data": [],
                      "errors": [
                        "O prazo de adesão a esta campanha já encerrou."
                      ],
                      "meta": []
                    }
                  },
                  "campanha_fechada": {
                    "summary": "Campanha `finished` ou `cancelled`",
                    "value": {
                      "success": false,
                      "code": 422,
                      "message_code": "CAMPAIGN_NOT_JOINABLE",
                      "description": "Esta campanha não está disponível para adesão.",
                      "data": [],
                      "errors": [
                        "Esta campanha não está disponível para adesão."
                      ],
                      "meta": []
                    }
                  },
                  "limite_de_produtos": {
                    "summary": "A loja tem um teto de anúncios nesta campanha",
                    "value": {
                      "success": false,
                      "code": 422,
                      "message_code": "CAMPAIGN_PRODUCT_LIMIT_REACHED",
                      "description": "Você atingiu o limite de produtos permitido nesta campanha.",
                      "data": [],
                      "errors": [
                        "Você atingiu o limite de produtos permitido nesta campanha."
                      ],
                      "meta": []
                    }
                  },
                  "formato_invalido": {
                    "summary": "`publication_ids` ausente ou fora do formato",
                    "value": {
                      "success": false,
                      "code": 422,
                      "message_code": "VALIDATION_ERROR",
                      "description": "Foram encontrados erros de validação na requisição.",
                      "data": [],
                      "errors": {
                        "publication_ids": [
                          "O campo publication_ids é obrigatório."
                        ]
                      },
                      "meta": []
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "tags": [
          "Campanhas"
        ],
        "summary": "Remover Anúncios da Campanha",
        "description": "Tira anúncios da campanha. Com `publication_ids`, remove só os informados; **sem corpo, remove todos os anúncios que a loja tinha inscrito nesta campanha**.\n\nResponde `204` sem corpo, inclusive quando não havia nada para remover.\n\nDiferente do opt-in, aqui não há checagem de prazo: dá para sair de uma campanha depois do `opt_in_deadline`.\n\nExige o escopo `store_products_write`.",
        "security": [
          {
            "integrationToken": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "example": 128
            },
            "description": "`id` da campanha, como vem no calendário. Não é o `uid`."
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "publication_ids": {
                    "type": "array",
                    "description": "`item_id` dos anúncios a remover. Omita para remover todos.",
                    "items": {
                      "type": "string",
                      "pattern": "^[A-Z]{2,5}-\\d{13}$"
                    }
                  }
                }
              },
              "example": {
                "publication_ids": [
                  "US-0000000001234"
                ]
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "Inscrições removidas. Sem corpo."
          },
          "401": {
            "description": "Token não fornecido, inválido ou expirado",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 401,
                  "message_code": "UNAUTHORIZED",
                  "description": "A autenticação é necessária e falhou ou não foi fornecida.",
                  "data": [],
                  "errors": [
                    "O access_token da loja é obrigatório no cabeçalho Authorization"
                  ],
                  "meta": []
                }
              }
            }
          },
          "403": {
            "description": "Falta um escopo exigido pela rota",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 403,
                  "message_code": "FORBIDDEN",
                  "description": "O servidor entende a requisição, mas se recusa a autorizá-la.",
                  "data": [],
                  "errors": [
                    "Token de integração sem permissão para este recurso (abilities ausentes: store_products_write)"
                  ],
                  "meta": []
                }
              }
            }
          },
          "404": {
            "description": "Campanha inexistente",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 404,
                  "message_code": "NOT_FOUND",
                  "description": "O recurso solicitado não foi encontrado.",
                  "data": [],
                  "errors": [
                    "Recurso não encontrado."
                  ],
                  "meta": []
                }
              }
            }
          },
          "422": {
            "description": "`publication_ids` fora do formato",
            "content": {
              "application/json": {
                "example": {
                  "success": false,
                  "code": 422,
                  "message_code": "VALIDATION_ERROR",
                  "description": "Foram encontrados erros de validação na requisição.",
                  "data": [],
                  "errors": {
                    "publication_ids.0": [
                      "O formato de publication_ids.0 é inválido."
                    ]
                  },
                  "meta": []
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "integrationToken": {
        "type": "http",
        "scheme": "bearer",
        "description": "Token de Integração da loja (formato: sk_...). Criado em Configurações → Tokens de Integração no painel do seller."
      }
    },
    "schemas": {
      "Product": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID do produto (26 caracteres)"
          },
          "name": {
            "type": "string"
          },
          "sku": {
            "type": "string"
          },
          "price_type": {
            "type": "string",
            "enum": [
              "default",
              "wholesale"
            ]
          },
          "base_unit": {
            "type": "string",
            "enum": [
              "un",
              "kg",
              "pc",
              "cx",
              "pct",
              "lt",
              "mt",
              "m2",
              "m3"
            ]
          },
          "dimensions": {
            "type": "object",
            "properties": {
              "width": {
                "type": "number",
                "description": "Largura em cm"
              },
              "height": {
                "type": "number",
                "description": "Altura em cm"
              },
              "length": {
                "type": "number",
                "description": "Comprimento em cm"
              },
              "weight": {
                "type": "number",
                "description": "Peso em kg"
              }
            }
          },
          "is_available_for_sale": {
            "type": "boolean",
            "description": "Indica se o produto está disponível para venda",
            "default": true
          },
          "is_industrializable": {
            "type": "boolean",
            "description": "Indica se o produto pode ser fabricado sob demanda"
          },
          "auto_wholesale_pricing": {
            "type": "boolean",
            "description": "Indica se os preços das faixas de atacado são derivados automaticamente do percentual de desconto. O preço de cada faixa é arredondado na escala do SKU (`price_scale`)"
          },
          "advanced_pricing": {
            "type": "boolean",
            "description": "Preço avançado ligado: o preço unitário do SKU aceita 3 casas decimais (por exemplo, R$ 0,375). Desligado, o preço unitário usa 2 casas",
            "default": false
          },
          "price_scale": {
            "type": "integer",
            "enum": [
              2,
              3
            ],
            "readOnly": true,
            "description": "Somente leitura. Quantidade de casas decimais do preço unitário do SKU, derivada de `advanced_pricing` (`false` resulta em `2`, `true` resulta em `3`). Não aceita entrada. Subtotais e valores derivados continuam em 2 casas, arredondados para cima"
          },
          "min_purchase_quantity": {
            "type": "integer",
            "minimum": 1,
            "description": "Piso de compra do SKU em unidades físicas (quantidade do item multiplicada pelo multiplicador da variação), nunca em packs",
            "default": 1
          },
          "allow_fractional_quantity": {
            "type": "boolean",
            "description": "Define o comportamento do piso. `false`: venda apenas em múltiplos exatos de `min_purchase_quantity`. `true`: venda fracionada, bastando alcançar o mínimo",
            "default": false
          },
          "allow_sale_without_stock": {
            "type": "boolean",
            "description": "Permite venda sem estoque disponível (pedido sob encomenda)"
          },
          "keep_flat": {
            "type": "boolean",
            "description": "Empacotamento: trava a rotação no eixo vertical. O item viaja deitado (este lado para cima) e não pode ser girado em pé na cubagem de frete",
            "default": false
          },
          "ship_isolated": {
            "type": "boolean",
            "description": "Empacotamento: o SKU sai em volume próprio, nunca dividindo a mesma caixa com outro SKU",
            "default": false
          },
          "dimensions_formatted": {
            "type": "object",
            "nullable": true,
            "description": "Dimensões formatadas para exibição (somente se include_dimensions_formatted=true)",
            "properties": {
              "width": {
                "type": "string",
                "nullable": true,
                "example": "10,00 cm"
              },
              "height": {
                "type": "string",
                "nullable": true,
                "example": "10,00 cm"
              },
              "length": {
                "type": "string",
                "nullable": true,
                "example": "10,00 cm"
              },
              "weight": {
                "type": "string",
                "nullable": true,
                "example": "500g"
              }
            }
          },
          "quantity": {
            "type": "number",
            "description": "Quantidade física total em estoque. Só é debitada no despacho."
          },
          "reserved_quantity": {
            "type": "number",
            "description": "Quantidade presa em carrinho/checkout ainda não pago."
          },
          "sold_reserved_quantity": {
            "type": "number",
            "description": "Quantidade vendida e paga, ainda não despachada. Continua contada em `quantity` (a mercadoria está na prateleira), mas não é mais vendável."
          },
          "available_quantity": {
            "type": "number",
            "description": "Quantidade disponível para venda (`quantity - reserved_quantity - sold_reserved_quantity`, nunca negativo)"
          },
          "price": {
            "type": "number",
            "description": "Preço de venda (somente para price_type=default)"
          },
          "min_price": {
            "type": "number",
            "description": "Menor preço entre as faixas (somente para price_type=wholesale)"
          },
          "max_price": {
            "type": "number",
            "description": "Maior preço entre as faixas (somente para price_type=wholesale)"
          },
          "images_count": {
            "type": "integer",
            "description": "Quantidade de imagens na galeria do produto. Presente na listagem e no detalhe. O corpo de criação e de atualização não traz este campo: ali vem o array `images` completo"
          },
          "thumbnail": {
            "type": "object",
            "nullable": true,
            "description": "Imagem de destaque do produto (variantes thumbnail e md)",
            "properties": {
              "id": {
                "type": "string",
                "description": "ID da imagem"
              },
              "resources": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "description": "Nome da variante (thumbnail, sm, md, lg)"
                    },
                    "size": {
                      "type": "string",
                      "description": "Dimensões da variante (ex: 400x400)"
                    },
                    "url": {
                      "type": "string",
                      "format": "uri"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "ProductInput": {
        "type": "object",
        "required": [
          "name",
          "sku",
          "base_unit",
          "price_type"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "sku": {
            "type": "string",
            "maxLength": 50,
            "description": "Deve ser único por loja"
          },
          "base_unit": {
            "type": "string",
            "enum": [
              "un",
              "kg",
              "pc",
              "cx",
              "pct",
              "lt",
              "mt",
              "m2",
              "m3"
            ]
          },
          "price_type": {
            "type": "string",
            "enum": [
              "default",
              "wholesale"
            ]
          },
          "is_available_for_sale": {
            "type": "boolean",
            "default": true
          },
          "is_industrializable": {
            "type": "boolean",
            "nullable": true
          },
          "allow_sale_without_stock": {
            "type": "boolean",
            "nullable": true,
            "description": "Permite venda sem estoque disponível (pedido sob encomenda)"
          },
          "auto_wholesale_pricing": {
            "type": "boolean",
            "description": "Opcional. Deriva automaticamente os preços das faixas de atacado a partir do percentual de desconto. O preço de cada faixa é arredondado na escala do SKU (`price_scale`)"
          },
          "advanced_pricing": {
            "type": "boolean",
            "default": false,
            "description": "Opcional. Liga o preço avançado: o preço unitário do SKU passa a aceitar 3 casas decimais (por exemplo, R$ 0,375). Define o `price_scale` retornado (`false` resulta em `2`, `true` resulta em `3`)"
          },
          "min_purchase_quantity": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "Opcional. Piso de compra do SKU em unidades físicas (quantidade do item multiplicada pelo multiplicador da variação), nunca em packs"
          },
          "allow_fractional_quantity": {
            "type": "boolean",
            "default": false,
            "description": "Opcional. `false`: o SKU só é vendido em múltiplos exatos de `min_purchase_quantity` (mínimo 25 aceita 25, 50 e 75, e rejeita 30). `true`: venda fracionada, basta alcançar o mínimo"
          },
          "keep_flat": {
            "type": "boolean",
            "default": false,
            "description": "Opcional. Empacotamento: trava a rotação no eixo vertical (item viaja deitado, este lado para cima)"
          },
          "ship_isolated": {
            "type": "boolean",
            "default": false,
            "description": "Opcional. Empacotamento: SKU sai em volume próprio (nunca divide caixa com outro SKU)"
          },
          "dimensions": {
            "type": "object",
            "properties": {
              "width": {
                "type": "number",
                "minimum": 0.001,
                "description": "Largura em cm",
                "nullable": true
              },
              "height": {
                "type": "number",
                "minimum": 0.001,
                "description": "Altura em cm",
                "nullable": true
              },
              "length": {
                "type": "number",
                "minimum": 0.001,
                "description": "Comprimento em cm",
                "nullable": true
              },
              "weight": {
                "type": "number",
                "minimum": 0.001,
                "description": "Peso em kg",
                "nullable": true
              }
            },
            "nullable": true,
            "description": "Opcional. Peso e dimensões da unidade. Pode ser omitido ou enviado como null no cadastro; sem medidas o produto não é cotado no frete"
          }
        }
      },
      "ProductUpdateInput": {
        "type": "object",
        "description": "Corpo da atualização de produto. Diferente da criação, o `sku` não é aceito (é ignorado se enviado) e apenas `name` é obrigatório: os demais campos, incluindo `dimensions`, mantêm o valor atual quando omitidos.",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255
          },
          "base_unit": {
            "type": "string",
            "description": "Opcional. Mantém o valor atual quando omitido",
            "enum": [
              "un",
              "kg",
              "pc",
              "cx",
              "pct",
              "lt",
              "mt",
              "m2",
              "m3"
            ]
          },
          "price_type": {
            "type": "string",
            "description": "Opcional. Veja as regras de troca na descrição do endpoint",
            "enum": [
              "default",
              "wholesale"
            ]
          },
          "is_available_for_sale": {
            "type": "boolean",
            "description": "Opcional"
          },
          "is_industrializable": {
            "type": "boolean",
            "description": "Opcional"
          },
          "allow_sale_without_stock": {
            "type": "boolean",
            "description": "Opcional. Permite venda sem estoque disponível (pedido sob encomenda)"
          },
          "auto_wholesale_pricing": {
            "type": "boolean",
            "description": "Opcional. Deriva automaticamente os preços das faixas de atacado a partir do percentual de desconto. O preço de cada faixa é arredondado na escala do SKU (`price_scale`)"
          },
          "advanced_pricing": {
            "type": "boolean",
            "default": false,
            "description": "Opcional. Liga o preço avançado: o preço unitário do SKU passa a aceitar 3 casas decimais. Define o `price_scale` retornado (`false` resulta em `2`, `true` resulta em `3`). Ao desligar, faixas com 3 casas já salvas deixam de ser aceitas em novas gravações de preço"
          },
          "min_purchase_quantity": {
            "type": "integer",
            "minimum": 1,
            "default": 1,
            "description": "Opcional. Piso de compra do SKU em unidades físicas (quantidade do item multiplicada pelo multiplicador da variação), nunca em packs"
          },
          "allow_fractional_quantity": {
            "type": "boolean",
            "default": false,
            "description": "Opcional. `false`: o SKU só é vendido em múltiplos exatos de `min_purchase_quantity` (mínimo 25 aceita 25, 50 e 75, e rejeita 30). `true`: venda fracionada, basta alcançar o mínimo"
          },
          "keep_flat": {
            "type": "boolean",
            "default": false,
            "description": "Opcional. Empacotamento: trava a rotação no eixo vertical (item viaja deitado, este lado para cima)"
          },
          "ship_isolated": {
            "type": "boolean",
            "default": false,
            "description": "Opcional. Empacotamento: SKU sai em volume próprio (nunca divide caixa com outro SKU)"
          },
          "dimensions": {
            "type": "object",
            "properties": {
              "width": {
                "type": "number",
                "minimum": 0.001,
                "description": "Largura em cm",
                "nullable": true
              },
              "height": {
                "type": "number",
                "minimum": 0.001,
                "description": "Altura em cm",
                "nullable": true
              },
              "length": {
                "type": "number",
                "minimum": 0.001,
                "description": "Comprimento em cm",
                "nullable": true
              },
              "weight": {
                "type": "number",
                "minimum": 0.001,
                "description": "Peso em kg",
                "nullable": true
              }
            },
            "nullable": true,
            "description": "Opcional. Peso e dimensões da unidade; mantém o valor atual quando omitido"
          }
        }
      },
      "Price": {
        "type": "object",
        "properties": {
          "value": {
            "type": "number",
            "description": "Valor unitário da faixa"
          },
          "min_quantity": {
            "type": "integer",
            "description": "Quantidade mínima para a faixa valer"
          },
          "discount_percent": {
            "type": "number",
            "nullable": true,
            "description": "Percentual de desconto da faixa em relação ao preço-base (usado no atacado automático)"
          }
        }
      },
      "Stock": {
        "type": "object",
        "properties": {
          "location_stock": {
            "type": "object",
            "properties": {
              "location_id": {
                "type": "string",
                "description": "ID do local de estoque"
              },
              "store_id": {
                "type": "string",
                "description": "ID da loja"
              },
              "name": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "available",
                  "unavailable"
                ]
              },
              "location_type": {
                "type": "string",
                "enum": [
                  "seller_location",
                  "fulfillment"
                ]
              },
              "allows_pickup": {
                "type": "boolean",
                "description": "Local permite retirada"
              },
              "allows_production": {
                "type": "boolean",
                "description": "Local permite produção sob demanda"
              }
            }
          },
          "quantity": {
            "type": "number",
            "description": "Quantidade física neste local. Só é debitada no despacho."
          },
          "reserved_quantity": {
            "type": "number",
            "description": "Quantidade presa em carrinho/checkout ainda não pago, neste local."
          },
          "sold_reserved_quantity": {
            "type": "number",
            "description": "Quantidade vendida e paga neste local, ainda não despachada. Continua contada em `quantity` (a mercadoria está na prateleira), mas não é mais vendável."
          },
          "available_quantity": {
            "type": "number",
            "description": "Quantidade disponível para venda (`quantity - reserved_quantity - sold_reserved_quantity`, nunca negativo)"
          }
        }
      },
      "PaginationMeta": {
        "type": "object",
        "properties": {
          "search_query": {
            "type": "string"
          },
          "filters": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pagination": {
            "type": "object",
            "properties": {
              "page": {
                "type": "integer"
              },
              "per_page": {
                "type": "integer"
              },
              "last_page": {
                "type": "integer"
              },
              "has_prev_page": {
                "type": "boolean"
              },
              "has_next_page": {
                "type": "boolean"
              },
              "records": {
                "type": "object",
                "properties": {
                  "from": {
                    "type": "integer"
                  },
                  "to": {
                    "type": "integer"
                  },
                  "records": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      },
      "SkuMeasureTier": {
        "type": "object",
        "properties": {
          "min_quantity": {
            "type": "integer",
            "description": "Quantidade mínima a partir da qual esta embalagem fechada é usada (sempre >= 2)"
          },
          "weight": {
            "type": "number",
            "nullable": true,
            "description": "Peso da embalagem fechada, em kg"
          },
          "height": {
            "type": "number",
            "nullable": true,
            "description": "Altura da embalagem fechada, em cm"
          },
          "width": {
            "type": "number",
            "nullable": true,
            "description": "Largura da embalagem fechada, em cm"
          },
          "length": {
            "type": "number",
            "nullable": true,
            "description": "Comprimento da embalagem fechada, em cm"
          }
        }
      },
      "SkuMeasureTierInput": {
        "type": "object",
        "required": [
          "min_quantity"
        ],
        "properties": {
          "min_quantity": {
            "type": "integer",
            "minimum": 1,
            "description": "Quantidade mínima da faixa. Valor 1 é ignorado (a medida da unidade vive no produto); faixas úteis usam >= 2"
          },
          "weight": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "description": "Peso da embalagem fechada, em kg. Obrigatório junto com as demais medidas nas faixas >= 2"
          },
          "height": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "description": "Altura da embalagem fechada, em cm"
          },
          "width": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "description": "Largura da embalagem fechada, em cm"
          },
          "length": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "description": "Comprimento da embalagem fechada, em cm"
          }
        }
      },
      "ProductSummary": {
        "type": "object",
        "properties": {
          "total_products": {
            "type": "integer",
            "description": "Total de produtos no catálogo do seller"
          },
          "ativos": {
            "type": "integer",
            "description": "Disponíveis para venda"
          },
          "vendendo": {
            "type": "integer",
            "description": "Ativos com ao menos um anúncio ativo"
          },
          "disponiveis": {
            "type": "integer",
            "description": "Ativos ainda sem nenhum anúncio"
          },
          "sem_estoque": {
            "type": "integer",
            "description": "Ativos sem saldo de estoque"
          },
          "inativos": {
            "type": "integer",
            "description": "Indisponíveis para venda"
          },
          "industrializaveis": {
            "type": "integer",
            "description": "Fabricados sob demanda"
          },
          "price_types": {
            "type": "object",
            "properties": {
              "standard": {
                "type": "integer",
                "description": "Produtos com preço padrão (default)"
              },
              "wholesale": {
                "type": "integer",
                "description": "Produtos com preço de atacado (wholesale)"
              }
            }
          }
        }
      },
      "BulkAssociation": {
        "type": "object",
        "description": "Rastreador de progresso da associação em massa de SKUs.",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID do rastreador"
          },
          "total": {
            "type": "integer",
            "description": "Total de SKUs a processar"
          },
          "processed": {
            "type": "integer",
            "description": "SKUs processados com sucesso"
          },
          "failed": {
            "type": "integer",
            "description": "SKUs que falharam"
          },
          "failures": {
            "type": "array",
            "description": "Últimas falhas registradas (limitado às 100 mais recentes)",
            "items": {
              "type": "object",
              "properties": {
                "sku_id": {
                  "type": "string",
                  "description": "ID do SKU que falhou"
                },
                "reason": {
                  "type": "string",
                  "description": "Motivo da falha"
                }
              }
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "completed",
              "failed"
            ],
            "description": "Situação do processamento. `completed` quando termina com ao menos um sucesso; `failed` quando o total falhou"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "PriceInput": {
        "type": "object",
        "properties": {
          "price": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "description": "Valor monetário unitário da faixa, com no máximo `price_scale` casas decimais (2 por padrão; 3 quando o produto tem `advanced_pricing = true`). Enviar 3 casas em um SKU sem `advanced_pricing` retorna 422 de validação. Obrigatório na precificação manual (se omitido vira 0). Em produtos `wholesale` com `auto_wholesale_pricing` ligado é ignorado nas faixas `min_quantity >= 2`: o preço é calculado a partir do preço base e do `discount_percent`. O subtotal da linha e os valores derivados continuam em 2 casas, arredondados para cima."
          },
          "min_quantity": {
            "type": "integer",
            "default": 1,
            "description": "Quantidade mínima para ativar este preço (Padrão: 1). Produtos `default` só aceitam `min_quantity = 1`."
          },
          "discount_percent": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "description": "Percentual de desconto sobre o preço base unitário (0 a menos de 100). Usado nas faixas de atacado automáticas; os descontos precisam ser progressivos (faixa de quantidade maior exige desconto maior).",
            "exclusiveMaximum": 100
          }
        }
      },
      "PriceList": {
        "type": "object",
        "description": "Tabela de preço da loja (força de vendas).",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID da tabela"
          },
          "name": {
            "type": "string",
            "description": "Nome exibido (ex.: Ouro, Revenda)"
          },
          "mode": {
            "type": "string",
            "enum": [
              "manual",
              "auto"
            ],
            "description": "`manual`: preço digitado por faixa; `auto`: preço derivado de base + desconto"
          },
          "position": {
            "type": "integer",
            "description": "Ordem de exibição (menor primeiro)"
          },
          "is_active": {
            "type": "boolean",
            "description": "Se a tabela está ativa na loja"
          }
        }
      },
      "PriceListCreateInput": {
        "type": "object",
        "required": [
          "name",
          "mode"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "description": "Nome da tabela"
          },
          "mode": {
            "type": "string",
            "enum": [
              "manual",
              "auto"
            ],
            "description": "Modo de precificação da tabela"
          }
        }
      },
      "PriceListUpdateInput": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 120,
            "description": "Novo nome"
          },
          "mode": {
            "type": "string",
            "enum": [
              "manual",
              "auto"
            ],
            "description": "Novo modo (em geral imutável se a tabela já tiver produtos)"
          },
          "is_active": {
            "type": "boolean",
            "description": "Ativa ou desativa a tabela"
          },
          "position": {
            "type": "integer",
            "minimum": 0,
            "description": "Nova posição na ordenação"
          }
        }
      },
      "PriceListSettings": {
        "type": "object",
        "required": [
          "price_lists_enabled"
        ],
        "properties": {
          "price_lists_enabled": {
            "type": "boolean",
            "description": "Se o sistema de tabelas de preço está ligado na loja"
          }
        }
      },
      "ProductPriceListPricing": {
        "type": "object",
        "description": "Precificação de um produto numa tabela de preço da loja.",
        "properties": {
          "price_list_id": {
            "type": "string",
            "description": "ID da tabela de preço"
          },
          "name": {
            "type": "string",
            "description": "Nome da tabela definido pelo seller"
          },
          "mode": {
            "type": "string",
            "enum": [
              "manual",
              "auto"
            ],
            "description": "Modo de precificação da tabela: `manual` (preço digitado por faixa) ou `auto` (derivado de base_price − discount_percent)"
          },
          "active": {
            "type": "boolean",
            "description": "Indica se o produto participa desta tabela"
          },
          "base_price": {
            "type": "number",
            "nullable": true,
            "description": "Preço base usado no modo `auto` para derivar as faixas; `null` no modo `manual`"
          },
          "tiers": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "min_quantity": {
                  "type": "integer",
                  "description": "Quantidade mínima da faixa (a base é 1)"
                },
                "price": {
                  "type": "number",
                  "description": "Preço da faixa. No modo `auto` é calculado a partir do base_price e do desconto"
                },
                "discount_percent": {
                  "type": "number",
                  "nullable": true,
                  "description": "Desconto da faixa sobre o base_price (modo `auto`; base com 0). `null` no modo `manual`"
                }
              }
            }
          }
        }
      },
      "ProductPriceListPutInput": {
        "type": "object",
        "required": [
          "active",
          "tiers"
        ],
        "properties": {
          "active": {
            "type": "boolean",
            "description": "Se o produto participa da tabela. `false` mantém as faixas salvas mas tira o produto da tabela"
          },
          "base_price": {
            "type": "number",
            "nullable": true,
            "minimum": 0,
            "description": "Preço base para tabelas de modo `auto`. Ignorado no modo `manual`"
          },
          "tiers": {
            "type": "array",
            "minItems": 1,
            "maxItems": 5,
            "description": "Lista completa de faixas desejada (substitui a existente; faixas ausentes são removidas). Máximo de 5.",
            "items": {
              "type": "object",
              "required": [
                "min_quantity"
              ],
              "properties": {
                "min_quantity": {
                  "type": "integer",
                  "minimum": 1,
                  "description": "Quantidade mínima da faixa; a base é 1"
                },
                "price": {
                  "type": "number",
                  "nullable": true,
                  "minimum": 0,
                  "description": "Preço da faixa (modo `manual`). Ignorado no modo `auto`"
                },
                "discount_percent": {
                  "type": "number",
                  "nullable": true,
                  "minimum": 0,
                  "maximum": 99.99,
                  "description": "Desconto sobre o base_price (modo `auto`); a faixa base é sempre 0 e os descontos precisam ser progressivos"
                }
              }
            }
          }
        }
      },
      "ProductStockOverview": {
        "type": "object",
        "properties": {
          "total": {
            "type": "integer",
            "description": "Soma do `quantity` de todas as localizações. É saldo físico: conta também o que já foi vendido e ainda não despachou.",
            "example": 100
          },
          "stocks": {
            "type": "array",
            "description": "Lista detalhada de estoque do produto em cada localização.",
            "items": {
              "$ref": "#/components/schemas/ProductStockDetail"
            }
          },
          "locations": {
            "type": "array",
            "description": "Lista de todas as localizações disponíveis para a loja.",
            "items": {
              "$ref": "#/components/schemas/LocationStock"
            }
          }
        }
      },
      "ProductStock": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Identificador interno do registro de estoque.",
            "example": 321
          },
          "product_id": {
            "type": "string",
            "description": "ID do produto.",
            "example": "01H81AV32307PVBSV4RXF15EK9"
          },
          "location_id": {
            "type": "string",
            "description": "ID da localização de estoque.",
            "example": "01H81AV32307PVBSV4RXF15LOC"
          },
          "quantity": {
            "type": "integer",
            "description": "Quantidade física em estoque neste local. Só é debitada no despacho.",
            "example": 50
          },
          "reserved_quantity": {
            "type": "integer",
            "description": "Saldo preso em carrinho/checkout ainda não pago.",
            "example": 0
          },
          "sold_reserved_quantity": {
            "type": "integer",
            "description": "Saldo vendido e pago, ainda não despachado. Continua contado em `quantity` (a mercadoria está na prateleira), mas já não é vendável.",
            "example": 0
          },
          "available_quantity": {
            "type": "integer",
            "description": "Quantidade disponível para venda (`quantity - reserved_quantity - sold_reserved_quantity`, nunca negativo). É o teto físico: a quantidade comprável pelo cliente ainda é restringida pelo `min_purchase_quantity` e pelo `allow_fractional_quantity` do SKU (veja o guia de Produtos).",
            "example": 50
          }
        },
        "description": "Registro de saldo devolvido pela movimentação. Atenção: é um eco do payload enviado, não o saldo final — com `increment`/`decrement` o `quantity` é o delta enviado, e os dois contadores de reserva saem sempre `0`."
      },
      "ProductStockDetail": {
        "type": "object",
        "description": "Registro de estoque do produto em uma localização, com o produto e o local aninhados.",
        "properties": {
          "id": {
            "type": "integer",
            "description": "Identificador interno do registro de estoque.",
            "example": 321
          },
          "product_sku": {
            "type": "object",
            "description": "Dados do produto (id, name, sku, base_unit, dimensions, flags de venda, thumbnail e images). Nesta rota `prices` vem vazio e os totais de estoque dentro do objeto saem zerados — os saldos que valem são os desta linha."
          },
          "location_stock": {
            "$ref": "#/components/schemas/LocationStock"
          },
          "quantity": {
            "type": "integer",
            "description": "Quantidade física nesta localização. Inclui o que já foi vendido e ainda não despachou.",
            "example": 100
          },
          "reserved_quantity": {
            "type": "integer",
            "description": "Quantidade presa em carrinhos/checkouts ainda não pagos nesta localização.",
            "example": 5
          },
          "sold_reserved_quantity": {
            "type": "integer",
            "description": "Quantidade vendida e paga nesta localização, aguardando despacho. Sai de `quantity` só no empacotamento (posto avançado) ou na marcação de pronto para envio.",
            "example": 20
          },
          "available_quantity": {
            "type": "integer",
            "description": "Quantidade disponível para venda nesta localização (`quantity - reserved_quantity - sold_reserved_quantity`, nunca negativo). É o teto físico: a quantidade comprável pelo cliente ainda é restringida pelo `min_purchase_quantity` e pelo `allow_fractional_quantity` do SKU (veja o guia de Produtos).",
            "example": 75
          }
        }
      },
      "LocationStock": {
        "type": "object",
        "properties": {
          "location_id": {
            "type": "string",
            "description": "ID da localização.",
            "example": "01H81AV32307PVBSV4RXF15LOC"
          },
          "store_id": {
            "type": "integer",
            "description": "Identificador interno da loja dona do local.",
            "example": 42
          },
          "name": {
            "type": "string",
            "description": "Nome da localização.",
            "example": "Matriz - São Paulo"
          },
          "status": {
            "type": "string",
            "enum": [
              "available",
              "unavailable"
            ],
            "description": "Status da localização.",
            "example": "available"
          },
          "location_type": {
            "type": "string",
            "enum": [
              "seller_location",
              "fulfillment"
            ],
            "description": "Tipo da localização.",
            "example": "seller_location"
          },
          "allows_pickup": {
            "type": "boolean",
            "description": "Indica se o local permite retirada em mãos.",
            "example": false
          },
          "allows_production": {
            "type": "boolean",
            "description": "Indica se o local permite produção sob demanda.",
            "example": false
          }
        }
      },
      "StockUpdateInput": {
        "type": "object",
        "required": [
          "location_id",
          "quantity"
        ],
        "properties": {
          "location_id": {
            "type": "string",
            "description": "ID da localização onde o estoque será alterado.",
            "example": "01H81AV32307PVBSV4RXF15LOC"
          },
          "quantity": {
            "type": "integer",
            "minimum": 0,
            "description": "Quantidade a ser definida, incrementada ou decrementada. No modo balanço (sem `increment`/`decrement`) aceita `0` para zerar o saldo; com `increment` ou `decrement` o mínimo é `1`.",
            "example": 10
          },
          "increment": {
            "type": "boolean",
            "description": "Se verdadeiro, soma a quantidade ao estoque atual.",
            "default": false,
            "example": false
          },
          "decrement": {
            "type": "boolean",
            "description": "Se verdadeiro, subtrai a quantidade do estoque atual.",
            "default": false,
            "example": false
          }
        }
      },
      "SuccessResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message_code": {
            "type": "string",
            "example": "SUCCESS"
          },
          "data": {
            "type": "object"
          },
          "meta": {
            "type": "object",
            "description": "Presente apenas quando há metadados a retornar."
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": false
          },
          "code": {
            "type": "integer",
            "example": 400
          },
          "message_code": {
            "type": "string",
            "example": "BAD_REQUEST"
          },
          "description": {
            "type": "string",
            "example": "Erro na requisição."
          },
          "data": {
            "type": "array",
            "items": {},
            "example": []
          },
          "errors": {
            "type": "object",
            "additionalProperties": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          },
          "meta": {
            "type": "array",
            "items": {},
            "example": []
          }
        }
      },
      "ProductStockHolds": {
        "type": "object",
        "description": "Reservas ativas que seguram o saldo de um SKU, com os totais por balde.",
        "properties": {
          "totals": {
            "type": "object",
            "description": "Soma das reservas ativas em cada balde. Bate com o `reserved_quantity` e o `sold_reserved_quantity` do saldo do produto.",
            "properties": {
              "reserved": {
                "type": "integer",
                "description": "Total preso em carrinho/checkout ainda não pago.",
                "example": 30
              },
              "sold_reserved": {
                "type": "integer",
                "description": "Total vendido e pago, aguardando despacho.",
                "example": 70
              }
            }
          },
          "holds": {
            "type": "array",
            "description": "Uma linha por reserva ativa. Vendido primeiro; dentro de cada balde, o mais antigo na frente.",
            "items": {
              "$ref": "#/components/schemas/StockHold"
            }
          }
        }
      },
      "StockHold": {
        "type": "object",
        "description": "Uma reserva ativa segurando saldo do SKU.",
        "properties": {
          "bucket": {
            "type": "string",
            "enum": [
              "reserved",
              "sold_reserved"
            ],
            "description": "`reserved`: carrinho/checkout não pago. `sold_reserved`: pago, esperando despacho.",
            "example": "sold_reserved"
          },
          "quantity": {
            "type": "integer",
            "description": "Unidades que esta reserva segura.",
            "example": 70
          },
          "order_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "ID do pedido que segura o saldo. `null` quando a reserva ainda é de carrinho.",
            "example": "01H81AV32307PVBSV4RXF15ORD"
          },
          "order_number": {
            "type": [
              "string",
              "null"
            ],
            "description": "Número do pedido. `null` enquanto a reserva é de carrinho.",
            "example": "STD-ABC-999"
          },
          "order_status": {
            "type": [
              "string",
              "null"
            ],
            "description": "Status do pedido no momento da consulta (veja os enums de pedido). `null` enquanto a reserva é de carrinho.",
            "example": "paid"
          },
          "customer_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Nome do cliente do pedido. `null` enquanto a reserva é de carrinho.",
            "example": "Maria Souza"
          },
          "location_name": {
            "type": [
              "string",
              "null"
            ],
            "description": "Local de estoque onde o saldo está preso.",
            "example": "Matriz - São Paulo"
          },
          "held_since": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "Quando a reserva foi criada (ISO 8601). É o relógio para achar o que está parado.",
            "example": "2026-09-15T14:32:10-03:00"
          }
        }
      },
      "LocationStockInput": {
        "type": "object",
        "required": [
          "name",
          "status",
          "location_type"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Nome do local. Obrigatório. O par nome + `location_type` é único por loja."
          },
          "status": {
            "type": "string",
            "enum": [
              "available",
              "unavailable"
            ],
            "description": "Obrigatório: não há valor assumido. Use `available` para o local já nascer operacional."
          },
          "location_type": {
            "type": "string",
            "enum": [
              "seller_location"
            ],
            "description": "Obrigatório. Na criação, só `seller_location` é aceito; locais `fulfillment` são criados pela plataforma."
          },
          "allows_pickup": {
            "type": "boolean",
            "default": false,
            "description": "Marca o local como ponto de retirada pelo cliente. Opcional."
          },
          "allows_production": {
            "type": "boolean",
            "default": false,
            "description": "Marca o local como apto a produção sob encomenda. Opcional."
          },
          "company_branch_id": {
            "type": "string",
            "nullable": true,
            "description": "ID da filial a vincular ao local. Precisa ser uma filial ativa da mesma empresa; omita para deixar o local respondendo pela matriz. Consulte os valores em `GET /api/locations-stock/available-branches`."
          }
        }
      },
      "LocationStockAddress": {
        "type": "object",
        "description": "Endereço vinculado a um local de estoque. `id` e `uid` carregam o mesmo ULID; `zip_code` volta formatado (`00000-000`), enquanto `full_address` monta a linha com o CEP sem máscara.",
        "properties": {
          "id": {
            "type": "string",
            "description": "ULID do endereço, usado como `{addressId}` nas rotas."
          },
          "uid": {
            "type": "string",
            "description": "Mesmo valor de `id`."
          },
          "type": {
            "type": "string",
            "enum": [
              "logistics",
              "local_real",
              "local_devolucao"
            ],
            "description": "Tipo do vínculo com o local."
          },
          "type_label": {
            "type": "string",
            "description": "Rótulo em pt-BR do tipo (`Logística`, `Local Real`, `Local de Devolução`)."
          },
          "street": {
            "type": "string"
          },
          "number": {
            "type": "string"
          },
          "complement": {
            "type": "string",
            "nullable": true
          },
          "reference": {
            "type": "string",
            "nullable": true,
            "description": "Ponto de referência, até 60 caracteres."
          },
          "can_deliver_to_neighbor": {
            "type": "boolean",
            "description": "Autoriza deixar a entrega com o vizinho."
          },
          "delivery_instructions": {
            "type": "string",
            "nullable": true,
            "description": "Instruções de entrega, até 150 caracteres."
          },
          "district": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "description": "UF com 2 letras."
          },
          "country": {
            "type": "string",
            "description": "Código do país com 2 letras. Default `BR`."
          },
          "zip_code": {
            "type": "string",
            "description": "CEP formatado `00000-000`."
          },
          "latitude": {
            "type": "number"
          },
          "longitude": {
            "type": "number"
          },
          "place_id": {
            "type": "string",
            "nullable": true,
            "description": "Identificador do provedor de geocodificação, quando resolvido."
          },
          "address_components": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "object"
            },
            "description": "Componentes devolvidos pela geocodificação, quando resolvidos."
          },
          "full_address": {
            "type": "string",
            "description": "Endereço em uma linha. O CEP aqui sai sem máscara."
          },
          "is_complete": {
            "type": "boolean",
            "description": "`true` quando latitude e longitude foram resolvidas (ambas diferentes de zero)."
          }
        }
      },
      "LocationStockAddressInput": {
        "type": "object",
        "required": [
          "type",
          "street",
          "number",
          "district",
          "city",
          "state",
          "zip_code"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "logistics",
              "local_real",
              "local_devolucao"
            ],
            "description": "Tipo do endereço no local. **Obrigatório na criação.**"
          },
          "street": {
            "type": "string",
            "minLength": 3,
            "description": "Logradouro. **Obrigatório na criação.**"
          },
          "number": {
            "type": "string",
            "maxLength": 20,
            "description": "Número. **Obrigatório na criação.**"
          },
          "complement": {
            "type": "string",
            "maxLength": 255,
            "nullable": true
          },
          "reference": {
            "type": "string",
            "maxLength": 60,
            "nullable": true,
            "description": "Ponto de referência."
          },
          "can_deliver_to_neighbor": {
            "type": "boolean",
            "description": "Autoriza entrega ao vizinho. Default `false`."
          },
          "delivery_instructions": {
            "type": "string",
            "maxLength": 150,
            "nullable": true,
            "description": "Instruções de entrega."
          },
          "district": {
            "type": "string",
            "minLength": 2,
            "description": "Bairro. **Obrigatório na criação.**"
          },
          "city": {
            "type": "string",
            "minLength": 2,
            "description": "Cidade. **Obrigatório na criação.**"
          },
          "state": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "description": "UF com exatamente 2 letras. **Obrigatório na criação.**"
          },
          "country": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "description": "País com 2 letras. Opcional, default `BR`."
          },
          "zip_code": {
            "type": "string",
            "pattern": "^[0-9]{5}-?[0-9]{3}$",
            "description": "CEP com ou sem hífen. **Obrigatório na criação.**"
          },
          "latitude": {
            "type": "number",
            "description": "Envie junto com `longitude` para fixar a coordenada. Sem elas, a plataforma tenta resolver pelo CEP."
          },
          "longitude": {
            "type": "number"
          },
          "place_id": {
            "type": "string",
            "nullable": true
          },
          "address_components": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "nullable": true
          }
        }
      },
      "CategoriesResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message_code": {
            "type": "string"
          },
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Category"
            }
          }
        },
        "required": [
          "success",
          "message_code",
          "data"
        ]
      },
      "Category": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID da categoria"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "departament": {
            "$ref": "#/components/schemas/Department"
          },
          "parent": {
            "$ref": "#/components/schemas/ParentCategory"
          },
          "is_visible": {
            "type": "boolean"
          },
          "priority": {
            "type": "integer"
          },
          "domain": {
            "type": "string"
          },
          "level": {
            "type": "integer"
          },
          "hierarchy": {
            "type": "array",
            "description": "Breadcrumb completo da categoria (cada nível com id e nome)",
            "items": {
              "$ref": "#/components/schemas/HierarchyLevel"
            }
          },
          "settings": {
            "type": "array",
            "items": {}
          },
          "catalog_overrides": {
            "type": [
              "object",
              "null"
            ]
          },
          "total_children": {
            "type": "integer"
          },
          "children": {
            "type": "array",
            "description": "Subcategorias (recursivo). Na busca, só voltam folhas, portanto vazio.",
            "items": {
              "$ref": "#/components/schemas/Category"
            }
          }
        },
        "required": [
          "id",
          "name",
          "departament",
          "parent"
        ]
      },
      "HierarchyLevel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "Department": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID do departamento"
          },
          "name": {
            "type": "string"
          },
          "icon_svg": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "id",
          "name"
        ]
      },
      "ParentCategory": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer"
          },
          "parent_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "hierarchy": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HierarchyLevel"
            }
          }
        },
        "required": [
          "id",
          "parent_id",
          "name"
        ]
      },
      "CategoryAttributesResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message_code": {
            "type": "string"
          },
          "data": {
            "type": "array",
            "description": "Com `matrix=true`, lista de grupos (`AttributeGroup`). Sem `matrix`, lista plana de atributos (`AttributeItem`).",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/AttributeGroup"
                },
                {
                  "$ref": "#/components/schemas/AttributeItem"
                }
              ]
            }
          }
        },
        "required": [
          "success",
          "message_code",
          "data"
        ]
      },
      "AttributeGroup": {
        "type": "object",
        "properties": {
          "key": {
            "type": [
              "string",
              "null"
            ],
            "description": "Chave da matriz (ex: identification, appearance, technical). `null` para atributos sem matriz."
          },
          "label": {
            "type": "string"
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AttributeItem"
            }
          }
        },
        "required": [
          "key",
          "label",
          "items"
        ]
      },
      "AttributeItem": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID do vínculo categoria-atributo"
          },
          "attribute_id": {
            "type": "integer",
            "description": "ID do atributo"
          },
          "category_id": {
            "type": "integer",
            "description": "ID da categoria"
          },
          "is_required": {
            "type": "boolean",
            "description": "Indica se o atributo e obrigatorio para a categoria"
          },
          "is_feature": {
            "type": "boolean",
            "description": "Indica se e uma caracteristica do produto"
          },
          "is_variant": {
            "type": "boolean",
            "description": "Indica se e um atributo de variacao"
          },
          "is_combinable": {
            "type": "boolean",
            "description": "Indica se pode ser usado em combinacoes para variacoes"
          },
          "is_filter": {
            "type": "boolean",
            "description": "Indica se o atributo aparece como filtro na vitrine"
          },
          "attribute_data": {
            "$ref": "#/components/schemas/AttributeData"
          }
        },
        "required": [
          "id",
          "attribute_id",
          "category_id",
          "is_required",
          "is_feature",
          "is_variant",
          "is_combinable",
          "is_filter"
        ]
      },
      "AttributeData": {
        "type": "object",
        "description": "Definição do atributo. O bloco `value_definition` é autodescritivo: traz os campos esperados (`fields`), as opções pré-cadastradas (`options`, quando houver) e as unidades disponíveis.",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID do atributo"
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "default",
              "default_unit",
              "default_list",
              "dimension_3d",
              "dimension_2d",
              "color",
              "image",
              "brand",
              "packaging"
            ],
            "description": "Tipo estrutural do atributo. `default_unit` exige `unit`; `dimension_2d/3d` exigem width/height(/depth)+unit; `color` aceita opção pré-cadastrada ou cor customizada (value + hex)."
          },
          "value_type": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "text",
              "float",
              "number",
              "date",
              "boolean",
              "select",
              "radio",
              "checkbox",
              null
            ],
            "description": "Tipo do valor para atributos default. Tipos especializados (color, image, brand, packaging) ignoram este campo."
          },
          "is_feature": {
            "type": "boolean"
          },
          "is_variant": {
            "type": "boolean"
          },
          "is_calculable": {
            "type": "boolean",
            "description": "Atributo usado em cálculos (ex: Quantidade, que precisa casar com a unidade base do SKU)"
          },
          "domain": {
            "type": [
              "string",
              "null"
            ]
          },
          "ui": {
            "type": "object",
            "properties": {
              "public_name": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "description": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "matrix": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Matriz de organização (identification, appearance, technical, dimensions, ...)"
              },
              "select_type": {
                "type": "string",
                "enum": [
                  "select",
                  "radio",
                  "checkbox",
                  "text"
                ],
                "description": "Como o valor é escolhido. `text` = digitação livre; os demais exigem opção pré-cadastrada (exceto atributos de cor, que aceitam cor customizada)."
              }
            }
          },
          "value_definition": {
            "type": "object",
            "properties": {
              "fields": {
                "type": "object",
                "description": "Schema dos campos esperados no valor (montagem dinâmica de formulário)"
              },
              "options": {
                "type": "array",
                "description": "Opções pré-cadastradas (presente apenas quando o atributo tem opções)",
                "items": {
                  "$ref": "#/components/schemas/AttributeOption"
                }
              },
              "default_unit": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "available_units": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "AttributeOption": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID da opção (use em `value_id` ao criar o anúncio)"
          },
          "attribute_id": {
            "type": "integer"
          },
          "value": {
            "type": "string"
          },
          "component": {
            "type": "object",
            "description": "Payload visual da opção, varia por tipo de atributo. Para cor: `{ value, main_color, hex, brightness }`.",
            "additionalProperties": true
          },
          "position": {
            "type": "integer"
          },
          "is_default": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "attribute_id",
          "value",
          "component",
          "position",
          "is_default"
        ]
      },
      "AttributeCombinationsResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message_code": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "properties": {
              "combinations": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AttributeCombination"
                }
              },
              "primary_attribute": {
                "$ref": "#/components/schemas/PrimaryAttributeInfo"
              }
            },
            "required": [
              "combinations",
              "primary_attribute"
            ]
          }
        },
        "required": [
          "success",
          "message_code",
          "data"
        ]
      },
      "AttributeCombination": {
        "type": "object",
        "properties": {
          "attributes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CombinationAttribute"
            }
          },
          "attributes_details": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "description": {
            "type": "string"
          }
        },
        "required": [
          "attributes",
          "attributes_details",
          "description"
        ]
      },
      "CombinationAttribute": {
        "type": "object",
        "properties": {
          "attribute_id": {
            "type": "integer",
            "description": "ID do atributo"
          },
          "attribute_name": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "unit": {
            "type": "string",
            "description": "Unidade de medida (presente apenas quando aplicável)"
          },
          "hex": {
            "type": "string",
            "description": "Cor em hexadecimal (presente apenas para atributos de cor)"
          },
          "main_color": {
            "type": "string",
            "description": "Cor principal (presente apenas para atributos de cor)"
          },
          "brightness": {
            "type": "string",
            "enum": [
              "light",
              "dark"
            ],
            "description": "Luminosidade calculada da cor (presente apenas para atributos de cor)"
          },
          "width": {
            "type": [
              "string",
              "number"
            ],
            "description": "Largura (presente apenas para atributos de dimensão)"
          },
          "height": {
            "type": [
              "string",
              "number"
            ],
            "description": "Altura (presente apenas para atributos de dimensão)"
          }
        },
        "required": [
          "attribute_id",
          "attribute_name",
          "value"
        ]
      },
      "PrimaryAttributeInfo": {
        "type": "object",
        "description": "Atributo principal das combinações; facilita organizar fotos por variação no front.",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID do atributo principal"
          },
          "name": {
            "type": [
              "string",
              "null"
            ]
          },
          "has_options": {
            "type": "boolean"
          },
          "default_unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "values": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "value": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "hex": {
                  "type": "string"
                },
                "main_color": {
                  "type": "string"
                },
                "brightness": {
                  "type": "string"
                }
              },
              "required": [
                "value",
                "label"
              ]
            }
          }
        },
        "required": [
          "id",
          "name",
          "has_options",
          "default_unit",
          "values"
        ]
      },
      "CreateAdvertisementRequest": {
        "type": "object",
        "description": "É obrigatório informar `seller_sku` (anúncio sem variações) ou `variations`: um dos dois precisa estar presente. Os SKUs devem existir previamente na loja.",
        "properties": {
          "title": {
            "type": "string",
            "maxLength": 100,
            "description": "Titulo do anuncio"
          },
          "category_id": {
            "type": "integer",
            "description": "ID da categoria selecionada (precisa ser categoria folha existente)"
          },
          "gtin": {
            "$ref": "#/components/schemas/GTIN"
          },
          "seller_sku": {
            "type": [
              "string",
              "null"
            ],
            "description": "SKU do produto para anúncio sem variações. Obrigatório quando `variations` não for enviado. O SKU precisa existir na loja."
          },
          "attributes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AdvertisementAttribute"
            },
            "description": "Atributos de caracteristicas do produto. Obrigatório quando a categoria possui atributos com `is_required=true`."
          },
          "variations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AdvertisementVariation"
            },
            "description": "Variacoes do produto. Obrigatório quando `seller_sku` não for enviado."
          },
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImageReference"
            },
            "description": "Imagens do anuncio principal. Opcional na criação, mas o checklist exige pelo menos uma imagem para publicar."
          },
          "description": {
            "$ref": "#/components/schemas/PublicationDescription",
            "description": "Descrição longa do anúncio. Opcional. Pode ser informada na criação ou depois via PUT /api/items/{id}/description."
          },
          "technical_sheets": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TechnicalSheetInput"
            },
            "description": "Fichas técnicas do anúncio. Opcionais. Também podem ser criadas ou editadas depois via /api/items/{id}/technical-sheets."
          },
          "video_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "ID de um vídeo já enviado pela Mídia e com `status: \"ready\"`. É um vídeo por anúncio. Omita a chave para criar o anúncio sem vídeo. Fluxo de upload em [Mídia › Vídeos](/guia/midia#videos).\n\nVídeo que ainda não está `ready` devolve **422**, vídeo de outra loja **404** e vídeo já vinculado a outro anúncio ou produto **409**, e o anúncio inteiro é desfeito, não é criado sem o vídeo.",
            "example": "01K8PBVID00001VWXYZ12345678"
          }
        },
        "required": [
          "title",
          "category_id"
        ]
      },
      "PublicationDescription": {
        "type": "object",
        "description": "Aceita um objeto `{ layout, raw_content }` ou uma string simples (legado, equivale a `layout=markdown`).",
        "properties": {
          "layout": {
            "type": "string",
            "enum": [
              "text",
              "html",
              "markdown"
            ],
            "description": "Formato do `raw_content`. Default: `markdown`."
          },
          "raw_content": {
            "type": "string",
            "description": "Conteúdo bruto da descrição no formato indicado por `layout`."
          }
        }
      },
      "TechnicalSheetInput": {
        "type": "object",
        "required": [
          "type",
          "title"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "technical_specification",
              "characteristics",
              "materials",
              "installation",
              "maintenance",
              "safety",
              "environmental",
              "custom"
            ],
            "description": "Tipo da ficha técnica."
          },
          "title": {
            "type": "string",
            "maxLength": 255,
            "description": "Título exibido para a seção da ficha."
          },
          "items": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "item_key",
                "item_value"
              ],
              "properties": {
                "item_key": {
                  "type": "string",
                  "maxLength": 255
                },
                "item_value": {
                  "type": "string",
                  "maxLength": 1000
                },
                "display_order": {
                  "type": "integer",
                  "minimum": 0
                }
              }
            }
          }
        }
      },
      "GTIN": {
        "type": "object",
        "properties": {
          "type": {
            "type": [
              "integer",
              "string"
            ],
            "enum": [
              8,
              12,
              13,
              14,
              "8",
              "12",
              "13",
              "14"
            ],
            "description": "Tipo de GTIN: 8, 12, 13 ou 14 dígitos (13 para EAN-13). Nas respostas, vem como string."
          },
          "value": {
            "type": "string",
            "description": "Número do código de barras, apenas dígitos. A quantidade de dígitos deve ser igual ao `type` e o dígito verificador GS1 é validado. Espaços, pontos e hífens são removidos antes da validação."
          }
        },
        "description": "Identificador do produto (código de barras). Usado no schema.org da página e no feed do Google Merchant da loja virtual: sem GTIN nem marca, o item não casa no catálogo do Google."
      },
      "AdvertisementAttribute": {
        "type": "object",
        "description": "Valor de um atributo do anúncio. Campos extras dependem do tipo do atributo: cor customizada usa `hex`/`main_color`/`brightness`; dimensões usam `width`/`height`/`depth` + `unit`; listas usam `items`.",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID do atributo"
          },
          "value_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "ID da opção selecionada (para atributos com opcoes pré-cadastradas)"
          },
          "option_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Alias aceito para `value_id`"
          },
          "value": {
            "type": [
              "string",
              "integer",
              "null"
            ],
            "description": "Valor do atributo"
          },
          "unit": {
            "type": [
              "string",
              "null"
            ],
            "description": "Unidade de medida (obrigatória em atributos do tipo default_unit; precisa estar em available_units)"
          },
          "hex": {
            "type": [
              "string",
              "null"
            ],
            "description": "Cor customizada em hexadecimal (#RGB ou #RRGGBB). Para atributos de cor, `value` (nome da cor) + `hex` válido dispensam opção pré-cadastrada."
          },
          "main_color": {
            "type": [
              "string",
              "null"
            ],
            "description": "Cor principal da cor customizada (ex: Vermelho)"
          },
          "brightness": {
            "type": [
              "string",
              "null"
            ],
            "description": "Luminosidade da cor (light/dark). Se omitido, é calculada a partir do hex."
          },
          "width": {
            "type": [
              "string",
              "number",
              "null"
            ],
            "description": "Largura (atributos dimension_2d/dimension_3d)"
          },
          "height": {
            "type": [
              "string",
              "number",
              "null"
            ],
            "description": "Altura (atributos dimension_2d/dimension_3d)"
          },
          "depth": {
            "type": [
              "string",
              "number",
              "null"
            ],
            "description": "Profundidade (atributos dimension_3d)"
          },
          "fields": {
            "type": [
              "object",
              "null"
            ],
            "description": "Forma alternativa de enviar dimensões: `{ width, height, depth, unit }`",
            "properties": {
              "width": {},
              "height": {},
              "depth": {},
              "unit": {
                "type": "string"
              }
            }
          },
          "items": {
            "type": [
              "array",
              "null"
            ],
            "description": "Itens do atributo (obrigatório em atributos do tipo default_list)"
          }
        }
      },
      "AdvertisementVariation": {
        "type": "object",
        "properties": {
          "seller_sku": {
            "type": "string",
            "description": "SKU do produto para esta variacao (precisa existir na loja)"
          },
          "attributes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VariationAttribute"
            },
            "description": "Atributos que definem esta variacao"
          },
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ImageReference"
            },
            "description": "Imagens especificas desta variacao"
          }
        },
        "required": [
          "seller_sku"
        ]
      },
      "VariationAttribute": {
        "type": "object",
        "description": "Informe `attribute_id` e `value` (ou `value_id` para opção pré-cadastrada). Atributos de cor aceitam cor customizada com `value` + `hex` (+ `main_color`/`brightness` opcionais), sem opção pré-cadastrada.",
        "properties": {
          "attribute_id": {
            "type": "integer",
            "description": "ID do atributo"
          },
          "attribute_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "value": {
            "type": [
              "string",
              "integer",
              "null"
            ]
          },
          "unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "value_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "ID da opção pré-cadastrada"
          },
          "option_id": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Alias aceito para `value_id`"
          },
          "hex": {
            "type": [
              "string",
              "null"
            ],
            "description": "Cor customizada em hexadecimal (#RGB ou #RRGGBB)"
          },
          "main_color": {
            "type": [
              "string",
              "null"
            ]
          },
          "brightness": {
            "type": [
              "string",
              "null"
            ]
          },
          "width": {
            "type": [
              "string",
              "number",
              "null"
            ]
          },
          "height": {
            "type": [
              "string",
              "number",
              "null"
            ]
          },
          "depth": {
            "type": [
              "string",
              "number",
              "null"
            ]
          },
          "fields": {
            "type": [
              "object",
              "null"
            ],
            "description": "Forma alternativa de enviar dimensões: `{ width, height, depth, unit }`"
          }
        }
      },
      "ImageReference": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID da imagem (UUID retornado por POST /api/media/upload)"
          }
        },
        "required": [
          "id"
        ]
      },
      "SimulatedAdvertisementResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message_code": {
            "type": "string"
          },
          "data": {
            "$ref": "#/components/schemas/CreatedAdvertisementData"
          }
        },
        "required": [
          "success",
          "message_code",
          "data"
        ]
      },
      "CreatedAdvertisementResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message_code": {
            "type": "string"
          },
          "data": {
            "$ref": "#/components/schemas/CreatedAdvertisementData"
          }
        },
        "required": [
          "success",
          "message_code",
          "data"
        ]
      },
      "CreatedAdvertisementData": {
        "type": "object",
        "description": "Objeto do anúncio, retornado por create, publish e simulate.",
        "properties": {
          "item_id": {
            "type": "string",
            "description": "ID do anúncio: prefixo da plataforma + 13 dígitos (ex: SAM-0000000000007)"
          },
          "title": {
            "type": "string"
          },
          "short_description": {
            "type": [
              "string",
              "null"
            ]
          },
          "slug": {
            "type": [
              "string",
              "null"
            ]
          },
          "type": {
            "allOf": [
              {
                "$ref": "#/components/schemas/TypeValue"
              }
            ],
            "description": "Tipo do anúncio: `default` (Padrão) ou `catalog` (Catálogo)"
          },
          "status": {
            "allOf": [
              {
                "$ref": "#/components/schemas/StatusValue"
              }
            ],
            "description": "Status do anúncio: `draft`, `pending_review`, `active`, `paused` ou `inactive`"
          },
          "seller_sku": {
            "type": [
              "string",
              "null"
            ],
            "description": "SKU vinculado diretamente ao anúncio (quando não há variações)"
          },
          "price_range": {
            "type": [
              "array",
              "null"
            ],
            "description": "Faixa de preço calculada a partir das ofertas (pode ser null em rascunhos)"
          },
          "score": {
            "type": [
              "integer",
              "null"
            ],
            "description": "Score de qualidade do anúncio"
          },
          "campaigns": {
            "type": "array"
          },
          "pricing_context": {
            "type": "array",
            "description": "Contexto de precificação por faixa de quantidade (descontos, campanhas)"
          },
          "frontend_sync_status": {
            "type": "string",
            "description": "Status de sincronização com a vitrine (ex: pending)"
          },
          "last_frontend_sync_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Formato Y-m-d H:i:s"
          },
          "submitted_for_review_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Quando o anúncio foi enviado para revisão. Formato Y-m-d H:i:s"
          },
          "reviewed_at": {
            "type": [
              "string",
              "null"
            ],
            "description": "Quando a plataforma revisou o anúncio. Formato Y-m-d H:i:s"
          },
          "rejection_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "Motivo da rejeição quando o anúncio volta para rascunho"
          },
          "gtin": {
            "allOf": [
              {
                "$ref": "#/components/schemas/GTIN"
              }
            ],
            "description": "Presente apenas quando informado A chave é omitida da resposta quando o anúncio não tem GTIN (não vem como null)."
          },
          "store": {
            "allOf": [
              {
                "$ref": "#/components/schemas/Store"
              }
            ],
            "description": "Loja dona do anúncio (presente quando carregada)"
          },
          "department": {
            "$ref": "#/components/schemas/Department"
          },
          "category": {
            "$ref": "#/components/schemas/CategoryRef"
          },
          "thumbnail": {
            "type": [
              "object",
              "null"
            ],
            "description": "Miniatura no tamanho `sm`: `{ id, resource }`"
          },
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Image"
            }
          },
          "attributes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicationAttributeOut"
            }
          },
          "variations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/PublicationVariationOut"
            }
          }
        },
        "required": [
          "item_id",
          "title",
          "type",
          "status",
          "department",
          "category",
          "images",
          "attributes",
          "variations"
        ]
      },
      "Image": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID da imagem (UUID)"
          },
          "resources": {
            "type": "array",
            "description": "Variações de tamanho da imagem (`{ name, url, ... }`)",
            "items": {
              "type": "object"
            }
          }
        },
        "required": [
          "id",
          "resources"
        ]
      },
      "PublicationAttributeOut": {
        "type": "object",
        "properties": {
          "attribute_id": {
            "type": "integer",
            "description": "ID do atributo"
          },
          "attribute_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "attribute_value": {
            "type": [
              "string",
              "integer",
              "null"
            ]
          },
          "value_unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "value_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "component": {
            "type": [
              "object",
              "null"
            ],
            "description": "Payload visual do valor. Para cor: `{ value, main_color, hex, brightness }`."
          }
        },
        "required": [
          "attribute_id",
          "attribute_name",
          "attribute_value",
          "value_unit",
          "value_id",
          "component"
        ]
      },
      "PublicationVariationOut": {
        "type": "object",
        "description": "Variação do anúncio. Em anúncios padrão o identificador vem como `offer_id`; em anúncios de catálogo, como `option_id`.",
        "properties": {
          "offer_id": {
            "type": "string",
            "description": "ID da variação (26 caracteres). Presente em anúncios padrão."
          },
          "option_id": {
            "type": "string",
            "description": "ID da opção de catálogo (26 caracteres). Presente em anúncios de catálogo."
          },
          "description": {
            "type": "string",
            "description": "Descrição legível da combinação (ex: Voltagem: 110 V, Cor: Azul)"
          },
          "attributes": {
            "type": "array",
            "description": "Atributos da variação (`{ attribute_id, attribute_name, value, unit?, value_id?, hex?, main_color?, brightness? }`)",
            "items": {
              "type": "object"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "pending",
              "hidden"
            ],
            "description": "Status da variação"
          },
          "type": {
            "type": "string",
            "enum": [
              "offer",
              "option"
            ]
          },
          "images": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Image"
            }
          },
          "seller_sku": {
            "type": [
              "string",
              "null"
            ],
            "description": "Presente quando `type=offer`"
          },
          "offer": {
            "$ref": "#/components/schemas/OfferData"
          }
        },
        "required": [
          "description",
          "attributes",
          "status",
          "type",
          "images",
          "offer"
        ]
      },
      "OfferData": {
        "type": "object",
        "properties": {
          "price_type": {
            "type": "string",
            "description": "Tipo de precificação (ex: default, wholesale)"
          },
          "price_scale": {
            "type": "integer",
            "enum": [
              2,
              3
            ],
            "readOnly": true,
            "description": "Casas decimais do preço unitário desta oferta. Vale `3` quando o SKU está com precificação avançada (`advanced_pricing`) ligada, e `2` nos demais casos. Use este valor para formatar e arredondar o preço unitário na sua vitrine."
          },
          "min_purchase_quantity": {
            "type": "integer",
            "readOnly": true,
            "description": "Piso de compra em unidades físicas. Compare sempre `quantidade escolhida × quantity_multiplier da variação` com este valor: numa variação que agrupa 10 unidades por item, um mínimo de 50 exige 5 itens."
          },
          "allow_fractional_quantity": {
            "type": "boolean",
            "readOnly": true,
            "description": "Regra de degrau da quantidade mínima.\n\n- **`false`** (venda em múltiplos): quando `min_purchase_quantity` é maior que 1, a compra só é aceita em múltiplos exatos do mínimo. Com mínimo 25, valem 25, 50 e 75; a quantidade 30 é rejeitada.\n- **`true`** (venda fracionada): basta atingir o mínimo. Com mínimo 25, valem 25, 30, 31 e assim por diante."
          },
          "price_from": {
            "type": "number",
            "description": "Preço \"De\" quando há desconto"
          },
          "prices": {
            "type": "array",
            "description": "Faixas de preço (atacado)",
            "items": {
              "type": "object"
            }
          },
          "quantity": {
            "type": "integer"
          },
          "price": {
            "type": "number",
            "description": "Preço \"Por\""
          },
          "original_price": {
            "type": [
              "number",
              "null"
            ]
          },
          "has_discount": {
            "type": "boolean"
          },
          "discount_percent": {
            "type": "integer"
          },
          "wholesale_tiers": {
            "type": "array",
            "description": "Presente apenas quando há faixas de atacado",
            "items": {
              "type": "object"
            }
          },
          "buybox": {
            "type": "object",
            "description": "Dados da buybox (presente apenas em anúncios de catálogo)"
          }
        },
        "required": [
          "price_type",
          "price_scale",
          "min_purchase_quantity",
          "allow_fractional_quantity",
          "price_from",
          "prices",
          "quantity",
          "price",
          "original_price",
          "has_discount",
          "discount_percent"
        ]
      },
      "TypeValue": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string",
            "enum": [
              "default",
              "catalog"
            ]
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "value",
          "label"
        ]
      },
      "StatusValue": {
        "type": "object",
        "properties": {
          "value": {
            "type": "string",
            "enum": [
              "draft",
              "pending_review",
              "active",
              "paused",
              "inactive"
            ]
          },
          "label": {
            "type": "string"
          }
        },
        "required": [
          "value",
          "label"
        ]
      },
      "Store": {
        "type": "object",
        "properties": {
          "store_id": {
            "type": "string",
            "description": "ID da loja (26 caracteres)"
          },
          "store_name": {
            "type": "string"
          },
          "store_code": {
            "type": "string"
          },
          "store_status": {
            "type": "string"
          },
          "store_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "store_type": {
            "type": "string"
          },
          "max_locations": {
            "type": [
              "integer",
              "null"
            ]
          },
          "features": {
            "type": "array"
          },
          "company": {
            "type": "object",
            "description": "Dados cadastrais da empresa"
          },
          "shares_products": {
            "type": "boolean"
          },
          "shares_stock_locations": {
            "type": "boolean"
          },
          "shares_logistics": {
            "type": "boolean"
          },
          "is_primary": {
            "type": "boolean"
          },
          "primary_store": {
            "type": [
              "object",
              "null"
            ]
          }
        },
        "required": [
          "store_id",
          "store_name",
          "store_code"
        ]
      },
      "CategoryRef": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID da categoria"
          },
          "parent_id": {
            "type": [
              "integer",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "hierarchy": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/HierarchyLevel"
            }
          }
        },
        "required": [
          "id",
          "parent_id",
          "name"
        ]
      },
      "AttachSKURequest": {
        "type": "object",
        "properties": {
          "seller_sku": {
            "type": "string",
            "maxLength": 64,
            "description": "SKU do produto a vincular. Precisa pertencer (ou estar associado) à loja autenticada."
          },
          "status": {
            "type": "string",
            "description": "Status inicial da oferta. Default: `active`.",
            "enum": [
              "active",
              "paused",
              "inactive"
            ]
          }
        },
        "required": [
          "seller_sku"
        ]
      },
      "AttachedSKUResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean"
          },
          "message_code": {
            "type": "string"
          },
          "data": {
            "$ref": "#/components/schemas/AttachedSKUData"
          }
        },
        "required": [
          "success",
          "message_code",
          "data"
        ]
      },
      "AttachedSKUData": {
        "type": "object",
        "properties": {
          "offer_id": {
            "type": "string",
            "description": "ID da oferta criada (26 caracteres). Use em PUT/DELETE /api/items/catalog/offers/{offerId}."
          },
          "seller_sku": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "paused",
              "inactive",
              "pending"
            ]
          },
          "is_buybox_winner": {
            "type": "boolean",
            "description": "Recalculado em background após o vínculo; costuma vir `false` na resposta imediata"
          },
          "last_buybox_calculation": {
            "type": [
              "string",
              "null"
            ]
          },
          "price_data": {
            "$ref": "#/components/schemas/PriceData"
          },
          "stock_data": {
            "$ref": "#/components/schemas/StockData"
          },
          "publication": {
            "type": [
              "object",
              "null"
            ],
            "description": "Resumo do anúncio de catálogo",
            "properties": {
              "item_id": {
                "type": "string",
                "description": "ID do anúncio"
              },
              "title": {
                "type": "string"
              },
              "status": {
                "type": "string"
              },
              "type": {
                "type": "string"
              },
              "thumbnail_id": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "ID da imagem de capa (UUID)"
              }
            }
          },
          "option": {
            "$ref": "#/components/schemas/OptionData"
          }
        },
        "required": [
          "offer_id",
          "seller_sku",
          "status",
          "is_buybox_winner",
          "last_buybox_calculation",
          "price_data",
          "stock_data",
          "publication",
          "option"
        ]
      },
      "PriceData": {
        "type": "object",
        "description": "Snapshot de preço da oferta. Preço único: `{ price }`. Atacado: `{ type: \"wholesale\", tiers: [...] }`.",
        "properties": {
          "price": {
            "type": "number",
            "description": "Preço único (presente quando não há faixas de atacado)"
          },
          "type": {
            "type": "string",
            "enum": [
              "wholesale"
            ],
            "description": "Presente apenas quando há faixas de atacado"
          },
          "tiers": {
            "type": "array",
            "description": "Faixas de preço por quantidade (presente apenas no atacado)",
            "items": {
              "$ref": "#/components/schemas/PriceTier"
            }
          }
        }
      },
      "PriceTier": {
        "type": "object",
        "properties": {
          "min_quantity": {
            "type": "integer"
          },
          "price": {
            "type": "number"
          }
        },
        "required": [
          "min_quantity",
          "price"
        ]
      },
      "StockData": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "description": "ID interno do registro de estoque"
          },
          "product_id": {
            "type": "string",
            "description": "ID do SKU do produto (26 caracteres)"
          },
          "location_id": {
            "type": "string",
            "description": "ID do local de estoque (26 caracteres)"
          },
          "quantity": {
            "type": "integer",
            "description": "Quantidade física neste local. Só é debitada no despacho."
          },
          "reserved_quantity": {
            "type": "integer",
            "description": "Quantidade presa em carrinho/checkout ainda não pago, neste local."
          },
          "sold_reserved_quantity": {
            "type": "integer",
            "description": "Quantidade vendida e paga neste local, ainda não despachada. Continua contada em `quantity` (a mercadoria está na prateleira), mas não é mais vendável."
          },
          "available_quantity": {
            "type": "integer",
            "description": "Quantidade disponível para venda (`quantity - reserved_quantity - sold_reserved_quantity`, nunca negativo)"
          }
        },
        "required": [
          "id",
          "product_id",
          "location_id",
          "quantity",
          "reserved_quantity",
          "sold_reserved_quantity",
          "available_quantity"
        ]
      },
      "OptionData": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID da opção de catálogo (26 caracteres)"
          },
          "description": {
            "type": "string"
          },
          "attributes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OptionAttribute"
            }
          },
          "type": {
            "type": "string",
            "enum": [
              "option",
              "offer"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "pending",
              "hidden"
            ]
          },
          "images": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        },
        "required": [
          "id",
          "description",
          "attributes",
          "type",
          "status",
          "images"
        ]
      },
      "OptionAttribute": {
        "type": "object",
        "properties": {
          "attribute_id": {
            "type": "integer",
            "description": "ID do atributo"
          },
          "attribute_name": {
            "type": "string"
          },
          "value": {
            "type": "string"
          },
          "unit": {
            "type": [
              "string",
              "null"
            ]
          },
          "value_id": {
            "type": [
              "integer",
              "null"
            ]
          }
        },
        "required": [
          "attribute_id",
          "attribute_name",
          "value"
        ]
      },
      "TechnicalSheet": {
        "type": "object",
        "description": "Ficha técnica de um anúncio: lista ordenada de pares chave/valor agrupada por tipo (especificações, materiais, segurança etc.).",
        "properties": {
          "sheet_id": {
            "type": "string",
            "description": "ID da ficha técnica (26 caracteres)"
          },
          "publication_id": {
            "type": "string",
            "description": "`item_id` do anúncio dono da ficha"
          },
          "type": {
            "type": "object",
            "description": "Tipo da ficha técnica",
            "properties": {
              "value": {
                "type": "string",
                "enum": [
                  "technical_specification",
                  "characteristics",
                  "materials",
                  "installation",
                  "maintenance",
                  "safety",
                  "environmental",
                  "custom"
                ]
              },
              "label": {
                "type": "string",
                "description": "Rótulo amigável do tipo (ex.: Ficha Técnica, Materiais)"
              },
              "description": {
                "type": "string"
              }
            },
            "required": [
              "value",
              "label",
              "description"
            ]
          },
          "title": {
            "type": "string",
            "maxLength": 255
          },
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TechnicalSheetItem"
            }
          }
        },
        "required": [
          "sheet_id",
          "publication_id",
          "type",
          "title",
          "items"
        ]
      },
      "TechnicalSheetItem": {
        "type": "object",
        "description": "Linha da ficha técnica (par chave/valor).",
        "properties": {
          "item_id": {
            "type": "string",
            "description": "ID do item da ficha (26 caracteres)"
          },
          "item_key": {
            "type": "string",
            "maxLength": 255,
            "description": "Nome da característica (ex.: Potência)"
          },
          "item_value": {
            "type": "string",
            "maxLength": 1000,
            "description": "Valor da característica (ex.: 650 W)"
          },
          "display_order": {
            "type": "integer",
            "minimum": 0,
            "description": "Posição de exibição (0 = primeiro)"
          }
        },
        "required": [
          "item_id",
          "item_key",
          "item_value",
          "display_order"
        ]
      },
      "MediaCreatedResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message_code": {
            "type": "string",
            "example": "RESOURCE_CREATED"
          },
          "data": {
            "$ref": "#/components/schemas/MediaItem"
          }
        },
        "required": [
          "success",
          "message_code",
          "data"
        ]
      },
      "MediaItemResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message_code": {
            "type": "string",
            "example": "SUCCESS"
          },
          "data": {
            "$ref": "#/components/schemas/MediaItem"
          }
        },
        "required": [
          "success",
          "message_code",
          "data"
        ]
      },
      "MediaCollectionResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message_code": {
            "type": "string",
            "example": "SUCCESS"
          },
          "data": {
            "type": "object",
            "properties": {
              "meta": {
                "$ref": "#/components/schemas/PaginationMeta"
              },
              "data": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/MediaItem"
                }
              }
            }
          }
        },
        "required": [
          "success",
          "message_code",
          "data"
        ]
      },
      "MediaItem": {
        "type": "object",
        "description": "Objeto que representa uma imagem/mídia na API de seller. Campos internos de propriedade (`owner_id`, `owner_model`) ficam de fora do payload de propósito: você não precisa deles para integrar, então não vai encontrá-los aqui.",
        "properties": {
          "id": {
            "type": "string",
            "description": "Identificador único da imagem (26 caracteres). É o valor usado como `{file_hash}` nas rotas de detalhe e exclusão.",
            "example": "01JMZXZ72881MD2P37N2K97YJJ"
          },
          "original_source": {
            "type": "string",
            "format": "uri",
            "description": "URL da imagem original, já convertida para WebP em alta qualidade.",
            "example": "https://cdn.example.com/products/2026/05/28/original_01JMZXZ72881MD2P37N2K97YJJ.webp"
          },
          "urls": {
            "type": "array",
            "description": "Variações de tamanho geradas automaticamente (todas em WebP). Uma entrada por variação: `thumbnail` (135x135), `sm` (200x200), `md` (400x400), `lg` (800x800) e `xl` (1600x1600).",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "enum": [
                    "thumbnail",
                    "sm",
                    "md",
                    "lg",
                    "xl"
                  ],
                  "description": "Nome da variação de tamanho.",
                  "example": "thumbnail"
                },
                "size": {
                  "type": "string",
                  "description": "Dimensões máximas da variação, no formato largura x altura.",
                  "example": "135x135"
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "description": "URL pública da variação.",
                  "example": "https://cdn.example.com/products/2026/05/28/thumbnail_01JMZXZ72881MD2P37N2K97YJJ.webp"
                }
              },
              "required": [
                "name",
                "size",
                "url"
              ]
            }
          },
          "in_use": {
            "type": "boolean",
            "description": "Indica se a imagem está associada a algum recurso.",
            "example": false
          },
          "reference_id": {
            "type": "string",
            "nullable": true,
            "description": "ID do recurso referenciado (se houver)."
          },
          "reference_model": {
            "type": "string",
            "nullable": true,
            "enum": [
              "product",
              "publication",
              "store"
            ],
            "description": "Tipo do recurso vinculado, em formato curto. Use o mesmo valor no filtro `filter[reference_model]=...`."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "Data de criação da imagem.",
            "example": "2026-05-28T10:00:00-03:00"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "description": "Data da última atualização da imagem.",
            "example": "2026-05-28T10:00:00-03:00"
          }
        },
        "required": [
          "id",
          "original_source",
          "urls",
          "in_use",
          "reference_id",
          "reference_model",
          "created_at",
          "updated_at"
        ]
      },
      "MediaCloneFromSkusResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message_code": {
            "type": "string",
            "example": "OK"
          },
          "data": {
            "type": "object",
            "properties": {
              "results": {
                "type": "array",
                "description": "Uma linha por alvo enviado, na mesma ordem do request.",
                "items": {
                  "$ref": "#/components/schemas/MediaCloneTargetResult"
                }
              }
            },
            "required": [
              "results"
            ]
          }
        },
        "required": [
          "success",
          "data"
        ]
      },
      "ClonedMediaItem": {
        "type": "object",
        "description": "Mídia recém-clonada a partir de uma foto de produto. Nasce sem vínculo (`in_use=false`). Vincule ao anúncio normalmente via `images[].id`; se não for usada, a limpeza diária remove a cópia após ~72 horas.",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID da nova mídia (26 caracteres). Use este valor nas `images` do anúncio/variação.",
            "example": "01JNB2T4G93QRT5V6W7X8Y9Z0A"
          },
          "source_image_id": {
            "type": "string",
            "description": "ID da imagem de origem (foto da galeria do produto). Útil para rastrear de onde a cópia veio e evitar duplicar sugestões.",
            "example": "01JMZXZ72881MD2P37N2K97YJJ"
          },
          "original_source": {
            "type": "string",
            "format": "uri",
            "description": "URL da cópia em alta qualidade (WebP).",
            "example": "https://cdn.example.com/products/2026/06/11/original_01JNB2T4G93QRT5V6W7X8Y9Z0A.webp"
          },
          "urls": {
            "type": "array",
            "description": "Variações de tamanho copiadas da imagem de origem (mesmos nomes do upload: `thumbnail`, `sm`, `md`, `lg`, `xl`).",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "example": "sm"
                },
                "size": {
                  "type": "string",
                  "nullable": true,
                  "example": "200x200"
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "example": "https://cdn.example.com/products/2026/06/11/sm_01JNB2T4G93QRT5V6W7X8Y9Z0A.webp"
                }
              },
              "required": [
                "name",
                "url"
              ]
            }
          }
        },
        "required": [
          "id",
          "source_image_id",
          "original_source",
          "urls"
        ]
      },
      "MediaCloneTargetResult": {
        "type": "object",
        "description": "Resultado da clonagem de um alvo (`key` + `sku`) enviado no request.",
        "properties": {
          "key": {
            "type": "string",
            "description": "A mesma `key` enviada no alvo correspondente.",
            "example": "Azul"
          },
          "sku": {
            "type": "string",
            "description": "O mesmo `sku` enviado no alvo correspondente.",
            "example": "CAMISETA-AZUL-M"
          },
          "status": {
            "type": "string",
            "enum": [
              "cloned",
              "partial",
              "failed",
              "no_images",
              "sku_not_found"
            ],
            "description": "Resultado deste alvo:\n- `cloned`: todas as fotos da galeria foram copiadas.\n- `partial`: parte foi copiada; o resto está em `errors`.\n- `failed`: o SKU tem galeria, mas nenhuma cópia deu certo.\n- `no_images`: o SKU é da sua loja, mas não tem foto na galeria.\n- `sku_not_found`: o SKU não pertence (ou não está associado) à sua loja.",
            "example": "cloned"
          },
          "images": {
            "type": "array",
            "description": "Cópias criadas para este alvo. Vazio quando nada foi copiado.",
            "items": {
              "$ref": "#/components/schemas/ClonedMediaItem"
            }
          },
          "errors": {
            "type": "array",
            "description": "Fotos da galeria que não puderam ser copiadas. Vazio no caso feliz.",
            "items": {
              "$ref": "#/components/schemas/MediaCloneError"
            }
          }
        },
        "required": [
          "key",
          "sku",
          "status",
          "images",
          "errors"
        ]
      },
      "MediaCloneError": {
        "type": "object",
        "description": "Falha na cópia de uma foto específica da galeria de origem.",
        "properties": {
          "image_id": {
            "type": "string",
            "description": "ID da imagem de origem que falhou.",
            "example": "01JMZXZ72881MD2P37N2K97YJJ"
          },
          "reason": {
            "type": "string",
            "enum": [
              "source_not_found",
              "copy_failed"
            ],
            "description": "- `source_not_found`: a foto está na galeria do SKU, mas o registro de mídia não existe mais.\n- `copy_failed`: falha ao copiar o arquivo no storage.",
            "example": "copy_failed"
          }
        },
        "required": [
          "image_id",
          "reason"
        ]
      },
      "SourceMediaItem": {
        "type": "object",
        "description": "Foto da galeria do produto, como ela existe hoje. É a imagem de **origem**: para usá-la em um anúncio, clone antes via `POST /api/media/clone-from-skus`.",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID da mídia de origem (26 caracteres).",
            "example": "01JMZXZ72881MD2P37N2K97YJJ"
          },
          "original_source": {
            "type": "string",
            "format": "uri",
            "description": "URL da imagem em alta qualidade (WebP).",
            "example": "https://cdn.example.com/products/2026/06/11/original_01JMZXZ72881MD2P37N2K97YJJ.webp"
          },
          "urls": {
            "type": "array",
            "description": "Variações de tamanho disponíveis (`thumbnail`, `sm`, `md`, `lg`, `xl`).",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "example": "sm"
                },
                "size": {
                  "type": "string",
                  "nullable": true,
                  "example": "200x200"
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "example": "https://cdn.example.com/products/2026/06/11/sm_01JMZXZ72881MD2P37N2K97YJJ.webp"
                }
              },
              "required": [
                "name",
                "url"
              ]
            }
          }
        },
        "required": [
          "id",
          "original_source",
          "urls"
        ]
      },
      "MediaSkuGalleryResult": {
        "type": "object",
        "description": "Galeria de um SKU consultado.",
        "properties": {
          "sku": {
            "type": "string",
            "description": "O mesmo SKU enviado na consulta.",
            "example": "CAMISETA-AZUL-M"
          },
          "status": {
            "type": "string",
            "enum": [
              "found",
              "no_images",
              "sku_not_found"
            ],
            "description": "Resultado desta consulta:\n- `found`: o SKU é da sua loja e tem foto.\n- `no_images`: o SKU é da sua loja, mas a galeria está vazia.\n- `sku_not_found`: o SKU não pertence (ou não está associado) à sua loja.",
            "example": "found"
          },
          "images": {
            "type": "array",
            "description": "Fotos da galeria, na ordem de exibição (thumbnail primeiro).",
            "items": {
              "$ref": "#/components/schemas/SourceMediaItem"
            }
          },
          "video": {
            "allOf": [
              {
                "$ref": "#/components/schemas/VideoItem"
              }
            ],
            "nullable": true,
            "description": "Vídeo do SKU, ou `null` quando ele não tem nenhum. A chave está sempre presente. Para reaproveitá-lo em um anúncio, clone antes via `POST /api/media/videos/clone-from-sku`."
          }
        },
        "required": [
          "sku",
          "status",
          "images",
          "video"
        ]
      },
      "MediaSkusGalleryResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message_code": {
            "type": "string",
            "example": "OK"
          },
          "data": {
            "type": "object",
            "properties": {
              "results": {
                "type": "array",
                "description": "Uma linha por SKU consultado, na mesma ordem do request (SKUs repetidos são consultados uma vez só).",
                "items": {
                  "$ref": "#/components/schemas/MediaSkuGalleryResult"
                }
              }
            },
            "required": [
              "results"
            ]
          }
        },
        "required": [
          "success",
          "data"
        ]
      },
      "VideoIntentResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message_code": {
            "type": "string",
            "example": "CREATED"
          },
          "data": {
            "type": "object",
            "properties": {
              "video_id": {
                "type": "string",
                "description": "ID do vídeo (ULID, 26 caracteres). Use nas rotas de confirm, consulta e vínculo.",
                "example": "01K8PBVID00001VWXYZ12345678"
              },
              "upload_url": {
                "type": "string",
                "format": "uri",
                "description": "URL pré-assinada para o `PUT` do arquivo. Não envie o header `Authorization` nela: a assinatura já está na própria URL.",
                "example": "https://cdn.example.com/cdn-content/2026/08/17/video_01K8PBVID00001VWXYZ12345678.mp4?X-Amz-Signature=..."
              },
              "method": {
                "type": "string",
                "enum": [
                  "PUT"
                ],
                "description": "Método HTTP a usar no `upload_url`.",
                "example": "PUT"
              },
              "expires_at": {
                "type": "string",
                "format": "date-time",
                "description": "Quando a `upload_url` deixa de valer (15 minutos após o intent).",
                "example": "2026-08-17T10:15:00-03:00"
              }
            },
            "required": [
              "video_id",
              "upload_url",
              "method",
              "expires_at"
            ]
          }
        },
        "required": [
          "success",
          "data"
        ]
      },
      "VideoPoster": {
        "type": "object",
        "nullable": true,
        "description": "Capa do vídeo: um frame extraído no processamento e publicado como imagem WebP, nos mesmos tamanhos da Mídia. Use no atributo `poster` do seu player.\n\nÉ *best-effort*: se a extração falhar o vídeo continua `ready`, só que com `poster: null`. Trate esse caso.",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID da imagem da capa (26 caracteres).",
            "example": "01K8PBIMG00009VWXYZ12345678"
          },
          "original_source": {
            "type": "string",
            "format": "uri",
            "description": "URL da capa em alta qualidade (WebP).",
            "example": "https://cdn.example.com/2026/08/17/original_01K8PBIMG00009VWXYZ12345678.webp"
          },
          "resources": {
            "type": "array",
            "description": "Variações de tamanho da capa (`thumbnail`, `sm`, `md`, `lg`, `xl`).",
            "items": {
              "type": "object",
              "properties": {
                "name": {
                  "type": "string",
                  "example": "sm"
                },
                "size": {
                  "type": "string",
                  "nullable": true,
                  "example": "200x200"
                },
                "url": {
                  "type": "string",
                  "format": "uri",
                  "example": "https://cdn.example.com/2026/08/17/sm_01K8PBIMG00009VWXYZ12345678.webp"
                }
              },
              "required": [
                "name",
                "url"
              ]
            }
          }
        },
        "required": [
          "id",
          "original_source",
          "resources"
        ]
      },
      "VideoItem": {
        "type": "object",
        "description": "Vídeo da sua loja. `status`, `rejection_reason` e `size_bytes` só aparecem para o dono. Nas respostas públicas (vitrine, página do produto) o vídeo vem sem eles, e vídeo que não está `ready` simplesmente não aparece.",
        "properties": {
          "id": {
            "type": "string",
            "description": "ID do vídeo (ULID, 26 caracteres).",
            "example": "01K8PBVID00001VWXYZ12345678"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "nullable": true,
            "description": "URL pública do arquivo MP4. `null` enquanto o upload não foi confirmado.",
            "example": "https://cdn.example.com/cdn-content/2026/08/17/video_01K8PBVID00001VWXYZ12345678.mp4"
          },
          "duration_seconds": {
            "type": "number",
            "format": "float",
            "nullable": true,
            "description": "Duração medida no processamento. `null` antes de `ready`.",
            "example": 32.5
          },
          "width": {
            "type": "integer",
            "nullable": true,
            "description": "Largura em pixels, medida no processamento.",
            "example": 1080
          },
          "height": {
            "type": "integer",
            "nullable": true,
            "description": "Altura em pixels, medida no processamento.",
            "example": 1920
          },
          "poster": {
            "$ref": "#/components/schemas/VideoPoster"
          },
          "status": {
            "type": "string",
            "enum": [
              "reserved",
              "uploaded",
              "processing",
              "ready",
              "rejected",
              "failed"
            ],
            "description": "Estado do vídeo:\n- `reserved`: slot criado no intent, arquivo ainda não enviado.\n- `uploaded`: arquivo no storage, na fila de processamento.\n- `processing`: em análise (codec, duração, extração da capa).\n- `ready`: **pronto para vincular**. Só neste estado o vídeo pode ir para um produto ou anúncio.\n- `rejected`: recusado por regra de conteúdo. O motivo vem em `rejection_reason`.\n- `failed`: erro no processamento. Suba o arquivo de novo.",
            "example": "ready"
          },
          "rejection_reason": {
            "type": "string",
            "nullable": true,
            "description": "Motivo legível da recusa ou da falha. `null` quando não houve.",
            "example": "Vídeo muito longo (140s). O máximo é 90s."
          },
          "size_bytes": {
            "type": "integer",
            "nullable": true,
            "description": "Tamanho do arquivo, relido do storage no confirm.",
            "example": 8342100
          }
        },
        "required": [
          "id",
          "url",
          "duration_seconds",
          "width",
          "height",
          "poster",
          "status"
        ]
      },
      "VideoItemResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message_code": {
            "type": "string",
            "example": "SUCCESS"
          },
          "data": {
            "$ref": "#/components/schemas/VideoItem"
          }
        },
        "required": [
          "success",
          "data"
        ]
      },
      "VideoCloneFromSkuResponse": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "example": true
          },
          "message_code": {
            "type": "string",
            "example": "SUCCESS"
          },
          "data": {
            "type": "object",
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "cloned",
                  "no_video",
                  "sku_not_found",
                  "failed"
                ],
                "description": "Resultado da clonagem:\n- `cloned`: cópia criada; o vídeo vem em `video`.\n- `no_video`: o SKU não tem vídeo, ou o vídeo ainda não está `ready`.\n- `sku_not_found`: o SKU não existe ou não pertence (nem está associado) à sua loja.\n- `failed`: a cópia no storage falhou; tente de novo.",
                "example": "cloned"
              },
              "video": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/VideoItem"
                  }
                ],
                "nullable": true,
                "description": "A cópia recém-criada. `null` em qualquer status diferente de `cloned`."
              }
            },
            "required": [
              "status",
              "video"
            ]
          }
        },
        "required": [
          "success",
          "data"
        ]
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Token não fornecido, inválido ou expirado",
        "content": {
          "application/json": {
            "example": {
              "success": false,
              "code": 401,
              "message_code": "UNAUTHORIZED",
              "description": "A autenticação é necessária e falhou ou não foi fornecida.",
              "data": [],
              "errors": [
                "O access_token da loja é obrigatório no cabeçalho Authorization"
              ],
              "meta": []
            }
          }
        }
      },
      "Forbidden": {
        "description": "Sem permissão para acessar este recurso",
        "content": {
          "application/json": {
            "example": {
              "success": false,
              "code": 403,
              "message_code": "FORBIDDEN",
              "description": "Você não tem permissão para acessar este recurso.",
              "data": [],
              "errors": [
                "Você não tem permissão para acessar este recurso (escopos ausentes: store_products_write)"
              ],
              "meta": []
            }
          }
        }
      },
      "NotFound": {
        "description": "Recurso não encontrado",
        "content": {
          "application/json": {
            "example": {
              "success": false,
              "code": 404,
              "message_code": "NOT_FOUND",
              "description": "O recurso solicitado não foi encontrado.",
              "data": [],
              "errors": [
                "Produto não encontrado."
              ],
              "meta": []
            }
          }
        }
      },
      "Duplicated": {
        "description": "Recurso duplicado (ex: SKU já existe nesta loja)",
        "content": {
          "application/json": {
            "example": {
              "success": false,
              "code": 409,
              "message_code": "DUPLICATED",
              "description": "Este SKU já está cadastrado para esta loja.",
              "data": [],
              "errors": [
                "Este SKU já está cadastrado para esta loja."
              ],
              "meta": []
            }
          }
        }
      },
      "ValidationError": {
        "description": "Erro de validação nos campos enviados",
        "content": {
          "application/json": {
            "example": {
              "success": false,
              "code": 422,
              "message_code": "VALIDATION_ERROR",
              "description": "Foram encontrados erros de validação na requisição.",
              "data": [],
              "errors": {
                "sku": [
                  "O campo SKU é obrigatório."
                ],
                "name": [
                  "O campo Nome é obrigatório."
                ]
              },
              "meta": []
            }
          }
        }
      },
      "Conflict": {
        "description": "Conflito. O recurso está em uso e não pode ser removido.",
        "content": {
          "application/json": {
            "example": {
              "success": false,
              "code": 409,
              "message_code": "CONFLICT",
              "description": "A imagem está em uso e não pode ser removida ou alterada.",
              "data": [],
              "errors": [
                "A imagem está em uso e não pode ser removida ou alterada."
              ],
              "meta": []
            }
          }
        }
      },
      "VideoNotFound": {
        "description": "Vídeo não encontrado ou não pertencente à sua loja",
        "content": {
          "application/json": {
            "example": {
              "success": false,
              "code": 404,
              "message_code": "NOT_FOUND",
              "description": "O recurso solicitado não foi encontrado.",
              "data": [],
              "errors": [
                "Vídeo não encontrado."
              ],
              "meta": []
            }
          }
        }
      },
      "VideoConflict": {
        "description": "Conflito. O vídeo está em uso e não pode ser removido ou vinculado a outro recurso.",
        "content": {
          "application/json": {
            "example": {
              "success": false,
              "code": 409,
              "message_code": "CONFLICT",
              "description": "O vídeo está em uso por um produto ou anúncio.",
              "data": [],
              "errors": [
                "O vídeo está em uso por um produto ou anúncio."
              ],
              "meta": []
            }
          }
        }
      }
    }
  },
  "security": [
    {
      "integrationToken": []
    }
  ]
}