{
  "openapi": "3.1.0",
  "info": {
    "title": "Automeli API",
    "version": "v2",
    "description": "API pública de Automeli para publicar productos de Amazon en Mercado Libre. Las publicaciones se modelan como jobs asíncronos; el flujo recomendado es test → promote → live. Autenticación por header X-API-Key. v2 usa nombres de campo limpios y paginación por cursor en todos los listados. Esta URL sirve la versión vigente: hasta 2026-08 servía el spec de v1, que ahora vive congelado en https://www.automeli.com/api-docs/v1/openapi.json (guía de migración: https://www.automeli.com/api-docs/migration).",
    "contact": {
      "name": "Soporte Automeli",
      "url": "https://www.automeli.com/api-docs"
    },
    "x-stability": "beta"
  },
  "externalDocs": {
    "description": "Documentación",
    "url": "https://www.automeli.com/api-docs"
  },
  "servers": [
    {
      "url": "https://api.automeli.com/api/v2",
      "description": "Producción"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Products",
      "description": "Publicar productos y promover de prueba a real."
    },
    {
      "name": "Jobs",
      "description": "Estado, listado, reintento y cancelación de jobs."
    },
    {
      "name": "Account",
      "description": "Cuenta, créditos y categorías arancelarias."
    },
    {
      "name": "System",
      "description": "Health check / verificación de la API Key."
    }
  ],
  "paths": {
    "/products": {
      "get": {
        "operationId": "v2-products-list",
        "summary": "Listar el catálogo de la cuenta real",
        "description": "El endpoint principal de lectura de v2. Devuelve las publicaciones del catálogo del seller, paginadas por cursor, con nombres limpios (sin columnas internas de BD) y las infracciones abiertas de cada producto.\n\nScope requerido: `products:read`.\n\nCosto: Sin costo (lectura).",
        "tags": [
          "Products"
        ],
        "responses": {
          "200": {
            "description": "Página del catálogo. total sólo en la primera petición (sin cursor); para seguir, repetir con ?cursor=<next_cursor> hasta que has_more sea false.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "listing_id": {
                            "type": "string"
                          },
                          "sku": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "brand": {
                            "type": "string"
                          },
                          "permalink": {
                            "type": "string"
                          },
                          "image_url": {
                            "type": "string"
                          },
                          "ml_status": {
                            "type": "string"
                          },
                          "ml_sub_status": {
                            "type": "null"
                          },
                          "amazon_status": {
                            "type": "string"
                          },
                          "ml_category": {
                            "type": "string"
                          },
                          "ml_main_category": {
                            "type": "string"
                          },
                          "ml_listing_type": {
                            "type": "string"
                          },
                          "published_with_automeli": {
                            "type": "boolean"
                          },
                          "pause_reason": {
                            "type": "string"
                          },
                          "paused_since": {
                            "type": "null"
                          },
                          "amazon_total_price": {
                            "type": "number"
                          },
                          "amazon_price": {
                            "type": "number"
                          },
                          "amazon_shipping_cost": {
                            "type": "integer"
                          },
                          "amazon_taxes": {
                            "type": "integer"
                          },
                          "ml_price": {
                            "type": "integer"
                          },
                          "stock": {
                            "type": "integer"
                          },
                          "weight_lb": {
                            "type": "number"
                          },
                          "manufacturing_time": {
                            "type": "string"
                          },
                          "shipping_origin": {
                            "type": "string"
                          },
                          "created_at": {
                            "type": "string"
                          },
                          "amazon_reviewed_at": {
                            "type": "string"
                          },
                          "ml_updated_at": {
                            "type": "string"
                          },
                          "automeli_sync_status": {
                            "type": "string"
                          },
                          "automeli_tax_category": {
                            "type": "integer"
                          },
                          "last_change": {
                            "type": "string"
                          },
                          "discount_percentage": {
                            "type": "integer"
                          },
                          "image_differs_from_amazon": {
                            "type": "boolean"
                          },
                          "amazon_image_url": {
                            "type": "null"
                          },
                          "infractions": {
                            "type": "array",
                            "items": {}
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "next_cursor": {
                      "type": "string"
                    },
                    "has_more": {
                      "type": "boolean"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "data": [
                    {
                      "listing_id": "MCO1234567890",
                      "sku": "B003H03SDQ",
                      "title": "Ejemplo de producto",
                      "brand": "ACME",
                      "permalink": "https://articulo.mercadolibre.com.co/…",
                      "image_url": "https://http2.mlstatic.com/…jpg",
                      "ml_status": "active",
                      "ml_sub_status": null,
                      "amazon_status": "Disponible",
                      "ml_category": "Soluciones Limpiadoras",
                      "ml_main_category": "Hogar y Muebles",
                      "ml_listing_type": "gold_pro",
                      "published_with_automeli": true,
                      "pause_reason": "",
                      "paused_since": null,
                      "amazon_total_price": 24.99,
                      "amazon_price": 19.99,
                      "amazon_shipping_cost": 0,
                      "amazon_taxes": 0,
                      "ml_price": 89000,
                      "stock": 8,
                      "weight_lb": 1.2,
                      "manufacturing_time": "5",
                      "shipping_origin": "amazonUSA",
                      "created_at": "2026-05-08T12:00:00.000Z",
                      "amazon_reviewed_at": "2026-06-30T03:11:00.000Z",
                      "ml_updated_at": "2026-06-30T04:00:00.000Z",
                      "automeli_sync_status": "enabled",
                      "automeli_tax_category": 0,
                      "last_change": "Disponible",
                      "discount_percentage": -12,
                      "image_differs_from_amazon": false,
                      "amazon_image_url": null,
                      "infractions": []
                    }
                  ],
                  "next_cursor": "eyJsYXN0X2lkIjoi…",
                  "has_more": true,
                  "count": 1,
                  "total": 12840
                }
              }
            }
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE"
            ]
          },
          "422": {
            "description": "E_PRODUCT_INVALID_BODY: Body o query malformado (campo, fecha o estado inválido)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_PRODUCT_INVALID_BODY"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": false,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/catalog#list",
        "x-error-codes": [
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_PRODUCT_INVALID_BODY"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Tamaño de página. Default 100.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Token opaco de la página siguiente (next_cursor de la respuesta anterior). Omitir para la primera página — sólo esa incluye total.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "listing_id",
            "in": "query",
            "required": false,
            "description": "Filtra por un ID de publicación exacto.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sku",
            "in": "query",
            "required": false,
            "description": "Filtra por SKU exacto.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ml_status",
            "in": "query",
            "required": false,
            "description": "Estado de la publicación en Mercado Libre (active, paused, closed, deleted, under_review, …).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "amazon_status",
            "in": "query",
            "required": false,
            "description": "Estado del producto en Amazon.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "published_with_automeli",
            "in": "query",
            "required": false,
            "description": "Sólo publicaciones creadas (1) o no creadas (0) con el publicador de Automeli.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "automeli_sync_status",
            "in": "query",
            "required": false,
            "description": "Estado de sincronización, como palabra: enabled o disabled. Omitir = todos. Valor no habilitado para su cuenta → 422 (el mensaje lista los válidos; algunas cuentas tienen estados adicionales habilitados).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "deleted_in_automeli",
            "in": "query",
            "required": false,
            "description": "Default 0 (sólo no eliminados en Automeli). 2 = incluye ambos.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "created_from",
            "in": "query",
            "required": false,
            "description": "Rango sobre created_at (desde, inclusive). También created_to.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "amazon_reviewed_from",
            "in": "query",
            "required": false,
            "description": "Rango sobre amazon_reviewed_at. También amazon_reviewed_to.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "ml_updated_from",
            "in": "query",
            "required": false,
            "description": "Rango sobre ml_updated_at. También ml_updated_to.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "x-scope": "products:read",
        "x-credit-cost": "Sin costo (lectura)."
      },
      "post": {
        "operationId": "v2-products-create",
        "summary": "Crear un job de publicación",
        "description": "Crea un job asíncrono que la API procesa en segundo plano. Cada job admite hasta 10.000 items. El modo de prueba lo decide el environment de la API Key (automeli_test_* publica en la cuenta de prueba), no el body.\n\nScope requerido: `products:write`.\n\nSoporta `Idempotency-Key` para reintentos seguros.\n\nCosto: 1 crédito por item publicado. Las keys test consumen créditos de prueba.",
        "tags": [
          "Products"
        ],
        "responses": {
          "202": {
            "description": "Job aceptado. Devuelve el job_id para hacer seguimiento. Para conciliar: accepted / total_items incluyen los SKUs que quedaron duplicate (ya publicados y vivos, o ya en cola en otro job) y no se publican — lo que realmente se publica es queued (accepted = queued + duplicates; ambos vienen siempre, con 0 incluido). Si todo el lote era duplicado, el job nace directamente completed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "accepted": {
                      "type": "integer"
                    },
                    "rejected": {
                      "type": "integer"
                    },
                    "total_items": {
                      "type": "integer"
                    },
                    "queued": {
                      "type": "integer"
                    },
                    "duplicates": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "job_id": "8a3f2b10-4c9d-4e21-9f8a-1b2c3d4e5f60",
                  "status": "queued",
                  "name": "8 may 2026, 12:00:00",
                  "accepted": 2,
                  "rejected": 0,
                  "total_items": 2,
                  "queued": 2,
                  "duplicates": 0
                }
              }
            }
          },
          "400": {
            "description": "E_PRODUCT_CREDIT_EXHAUSTED: Sin créditos disponibles",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_PRODUCT_CREDIT_EXHAUSTED"
            ]
          },
          "401": {
            "description": "E_AUTH_MISSING_KEY: Falta el header X-API-Key\nE_AUTH_INVALID_KEY: Key con formato inválido o no reconocida",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_MISSING_KEY",
              "E_AUTH_INVALID_KEY"
            ]
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE"
            ]
          },
          "404": {
            "description": "E_ACCOUNT_NOT_FOUND: Cuenta Meli no encontrada",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_ACCOUNT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "E_IDEMPOTENCY_CONFLICT: Misma Idempotency-Key con body distinto",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_IDEMPOTENCY_CONFLICT"
            ]
          },
          "422": {
            "description": "E_PRODUCT_INVALID_BODY: Body o query malformado (campo, fecha o estado inválido)\nE_PRODUCT_INVALID_SKU: SKU no cumple regex (10 alfanum)\nE_CATEGORY_INVALID: La categoría de Mercado Libre no cumple el formato (MCO…)\nE_CATEGORY_AND_AUTO_CONFLICT: Un item manda la categoría y auto_categorize a la vez",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_PRODUCT_INVALID_BODY",
              "E_PRODUCT_INVALID_SKU",
              "E_CATEGORY_INVALID",
              "E_CATEGORY_AND_AUTO_CONFLICT"
            ]
          },
          "429": {
            "description": "E_RATE_LIMITED: Excedió el rate limit. Ver Retry-After\nE_PRODUCT_MAX_CONCURRENT_JOBS: Ya tiene 6 jobs activos",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_RATE_LIMITED",
              "E_PRODUCT_MAX_CONCURRENT_JOBS"
            ]
          },
          "503": {
            "description": "E_INTERNAL: Error inesperado. Reintente con backoff",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_INTERNAL"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": true,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/products",
        "x-error-codes": [
          "E_AUTH_MISSING_KEY",
          "E_AUTH_INVALID_KEY",
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_RATE_LIMITED",
          "E_IDEMPOTENCY_CONFLICT",
          "E_PRODUCT_INVALID_BODY",
          "E_PRODUCT_INVALID_SKU",
          "E_PRODUCT_CREDIT_EXHAUSTED",
          "E_PRODUCT_MAX_CONCURRENT_JOBS",
          "E_CATEGORY_INVALID",
          "E_CATEGORY_AND_AUTO_CONFLICT",
          "E_ACCOUNT_NOT_FOUND",
          "E_INTERNAL"
        ],
        "x-scope": "products:write",
        "x-credit-cost": "1 crédito por item publicado. Las keys test consumen créditos de prueba.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "items": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "sku": {
                          "type": "string"
                        },
                        "ml_category_id": {
                          "type": "string"
                        }
                      },
                      "additionalProperties": true
                    },
                    "description": "Cada item: sku + (ml_category_id o auto_categorize)."
                  },
                  "ml_listing_type": {
                    "type": "string",
                    "description": "Tipo de publicación de Mercado Libre, a nivel job. Default: gold_special (Clásica). gold_pro (premium con cuotas) y gold_special (clásica); gold_premium/gold/silver/bronze se aceptan por compatibilidad.",
                    "enum": [
                      "gold_pro",
                      "gold_special",
                      "gold_premium",
                      "gold",
                      "silver",
                      "bronze"
                    ]
                  },
                  "automeli_tax_category": {
                    "type": "integer",
                    "description": "Índice (no nombre) de la categoría fiscal del seller, a nivel job. Default 0 (la primera). Los índices se obtienen con GET /account/tax-categories."
                  },
                  "scheduled_for": {
                    "type": "string",
                    "description": "Programa la publicación a una hora futura. Formato YYYY-MM-DDTHH:MM en UTC, sin segundos ni offset. Entre 5 minutos y 30 días en el futuro."
                  }
                },
                "additionalProperties": true,
                "required": [
                  "items"
                ]
              },
              "example": {
                "items": [
                  {
                    "sku": "B003H03SDQ",
                    "ml_category_id": "MCO420674"
                  },
                  {
                    "sku": "B07JHNJLYH",
                    "auto_categorize": true
                  }
                ],
                "ml_listing_type": "gold_pro",
                "automeli_tax_category": 0
              }
            }
          },
          "x-fields": [
            {
              "name": "items",
              "type": "array (1-10.000)",
              "required": "yes",
              "description": "Cada item: sku + (ml_category_id o auto_categorize)."
            },
            {
              "name": "items[].sku",
              "type": "string",
              "required": "yes",
              "description": "10 caracteres alfanuméricos (ASIN de Amazon)."
            },
            {
              "name": "items[].ml_category_id",
              "type": "string",
              "required": "conditional",
              "description": "Categoría de Mercado Libre, formato MCO420674. Excluyente con auto_categorize."
            },
            {
              "name": "items[].auto_categorize",
              "type": "boolean",
              "required": "conditional",
              "description": "Automeli infiere la categoría desde el ASIN. Excluyente con ml_category_id."
            },
            {
              "name": "ml_listing_type",
              "type": "string",
              "required": "no",
              "description": "Tipo de publicación de Mercado Libre, a nivel job. Default: gold_special (Clásica). gold_pro (premium con cuotas) y gold_special (clásica); gold_premium/gold/silver/bronze se aceptan por compatibilidad.",
              "enum": [
                "gold_pro",
                "gold_special",
                "gold_premium",
                "gold",
                "silver",
                "bronze"
              ]
            },
            {
              "name": "automeli_tax_category",
              "type": "int",
              "required": "no",
              "description": "Índice (no nombre) de la categoría fiscal del seller, a nivel job. Default 0 (la primera). Los índices se obtienen con GET /account/tax-categories."
            },
            {
              "name": "scheduled_for",
              "type": "string",
              "required": "no",
              "description": "Programa la publicación a una hora futura. Formato YYYY-MM-DDTHH:MM en UTC, sin segundos ni offset. Entre 5 minutos y 30 días en el futuro."
            }
          ]
        }
      }
    },
    "/products/sync-status": {
      "patch": {
        "operationId": "v2-products-sync-status",
        "summary": "Cambiar el estado de sincronización de un lote",
        "description": "Cambia, para una lista de publicaciones del seller, qué hace Automeli con cada una a partir de ahora. El estado va como palabra (enabled / disabled); el número crudo se rechaza con 422. Sólo afecta publicaciones del seller de la API Key: los listing_id ajenos se ignoran y no cuentan en updated.\n\nScope requerido: `products:write`.\n\nSoporta `Idempotency-Key` para reintentos seguros.\n\nCosto: Sin costo (no publica).",
        "tags": [
          "Products"
        ],
        "responses": {
          "200": {
            "description": "Cambio aplicado. updated = publicaciones del seller encontradas en la lista.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "string"
                    },
                    "requested": {
                      "type": "integer"
                    },
                    "updated": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "status": "disabled",
                  "requested": 2,
                  "updated": 2
                }
              }
            }
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE"
            ]
          },
          "409": {
            "description": "E_IDEMPOTENCY_CONFLICT: Misma Idempotency-Key con body distinto",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_IDEMPOTENCY_CONFLICT"
            ]
          },
          "422": {
            "description": "E_PRODUCT_INVALID_BODY: Body o query malformado (campo, fecha o estado inválido)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_PRODUCT_INVALID_BODY"
            ]
          },
          "429": {
            "description": "E_RATE_LIMITED: Excedió el rate limit. Ver Retry-After",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_RATE_LIMITED"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": true,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/catalog#sync-status",
        "x-error-codes": [
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_RATE_LIMITED",
          "E_IDEMPOTENCY_CONFLICT",
          "E_PRODUCT_INVALID_BODY"
        ],
        "x-scope": "products:write",
        "x-credit-cost": "Sin costo (no publica).",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "status": {
                    "type": "string",
                    "description": "El estado destino, como palabra: enabled o disabled. Se rechaza el número crudo (422); el mensaje de error lista los estados válidos para su cuenta (algunas tienen adicionales habilitados)."
                  },
                  "listing_ids": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "listing_id a actualizar. Se normalizan (trim) y deduplican. Máximo 1000 por llamada; para más, dividir en lotes."
                  },
                  "include_not_found": {
                    "type": "boolean",
                    "description": "Si es true, la respuesta agrega matched (cuántos existían) y not_found (los listing_id que no pertenecen al seller). Opt-in porque cuesta una lectura extra."
                  }
                },
                "additionalProperties": true,
                "required": [
                  "status",
                  "listing_ids"
                ]
              },
              "example": {
                "status": "disabled",
                "listing_ids": [
                  "MCO1234567890",
                  "MCO9876543210"
                ]
              }
            }
          },
          "x-fields": [
            {
              "name": "status",
              "type": "string",
              "required": "yes",
              "description": "El estado destino, como palabra: enabled o disabled. Se rechaza el número crudo (422); el mensaje de error lista los estados válidos para su cuenta (algunas tienen adicionales habilitados)."
            },
            {
              "name": "listing_ids",
              "type": "array (1-1000)",
              "required": "yes",
              "description": "listing_id a actualizar. Se normalizan (trim) y deduplican. Máximo 1000 por llamada; para más, dividir en lotes."
            },
            {
              "name": "include_not_found",
              "type": "boolean",
              "required": "no",
              "description": "Si es true, la respuesta agrega matched (cuántos existían) y not_found (los listing_id que no pertenecen al seller). Opt-in porque cuesta una lectura extra."
            }
          ]
        }
      }
    },
    "/products/test": {
      "get": {
        "operationId": "v2-products-test-list",
        "summary": "Listar productos en cuenta de prueba",
        "description": "Devuelve los productos creados al publicar con una key automeli_test_*, paginados por cursor. El campo published_to_live indica si ese producto ya se promovió a la cuenta real; listing_id_test es el ID que se usa para promover.\n\nScope requerido: `products:read`.\n\nCosto: Sin costo (lectura).",
        "tags": [
          "Products"
        ],
        "responses": {
          "200": {
            "description": "Página de productos en la cuenta de prueba.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "sku": {
                            "type": "string"
                          },
                          "listing_id_test": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "image_url": {
                            "type": "string"
                          },
                          "permalink_test": {
                            "type": "string"
                          },
                          "ml_listing_type": {
                            "type": "string"
                          },
                          "price": {
                            "type": "integer"
                          },
                          "ml_currency": {
                            "type": "string"
                          },
                          "ml_category_id": {
                            "type": "string"
                          },
                          "ml_category_name": {
                            "type": "string"
                          },
                          "automeli_tax_category": {
                            "type": "integer"
                          },
                          "ml_status": {
                            "type": "string"
                          },
                          "automeli_sync_status": {
                            "type": "string"
                          },
                          "published_to_live": {
                            "type": "boolean"
                          },
                          "test_published_at": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "next_cursor": {
                      "type": "null"
                    },
                    "has_more": {
                      "type": "boolean"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "data": [
                    {
                      "sku": "B003H03SDQ",
                      "listing_id_test": "MCO1943839161",
                      "title": "Producto de prueba",
                      "image_url": "https://http2.mlstatic.com/…jpg",
                      "permalink_test": "https://articulo.mercadolibre.com.co/…",
                      "ml_listing_type": "gold_pro",
                      "price": 89000,
                      "ml_currency": "COP",
                      "ml_category_id": "MCO420674",
                      "ml_category_name": "Soluciones Limpiadoras",
                      "automeli_tax_category": 0,
                      "ml_status": "active",
                      "automeli_sync_status": "enabled",
                      "published_to_live": false,
                      "test_published_at": "2026-05-08T12:00:00.000Z"
                    }
                  ],
                  "next_cursor": null,
                  "has_more": false,
                  "count": 1,
                  "total": 1
                }
              }
            }
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE"
            ]
          },
          "422": {
            "description": "E_PRODUCT_INVALID_BODY: Body o query malformado (campo, fecha o estado inválido)\nE_PRODUCT_INVALID_SKU: SKU no cumple regex (10 alfanum)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_PRODUCT_INVALID_BODY",
              "E_PRODUCT_INVALID_SKU"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": false,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/test-products#list",
        "x-error-codes": [
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_PRODUCT_INVALID_BODY",
          "E_PRODUCT_INVALID_SKU"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Tamaño de página. Default 50.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Token opaco de la página siguiente (next_cursor de la respuesta anterior). Omitir para la primera página — sólo esa incluye total.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "ml_status",
            "in": "query",
            "required": false,
            "description": "Estado del listing de prueba en Mercado Libre.",
            "schema": {
              "type": "string",
              "enum": [
                "active",
                "paused",
                "closed",
                "under_review",
                "inactive",
                "not_yet_active",
                "payment_required"
              ]
            }
          },
          {
            "name": "published_to_live",
            "in": "query",
            "required": false,
            "description": "0 → sólo los pendientes de promover; 1 → los que ya pasaron a real.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "automeli_sync_status",
            "in": "query",
            "required": false,
            "description": "Estado de sincronización, como palabra: enabled o disabled (algunas cuentas tienen estados adicionales habilitados).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sku",
            "in": "query",
            "required": false,
            "description": "Filtra por SKU exacto.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "x-scope": "products:read",
        "x-credit-cost": "Sin costo (lectura)."
      }
    },
    "/products/test/promote": {
      "post": {
        "operationId": "v2-products-test-promote",
        "summary": "Promover productos de prueba a la cuenta real",
        "description": "Publica en la cuenta real productos que ya existen en la cuenta de prueba, reutilizando la categoría de Mercado Libre, la categoría fiscal y el tipo de publicación que ya tenían. La selección es por listing_id_test (no por SKU). Sólo se promueven publicaciones active o paused; el resto se reporta en skipped_not_publishable. Como la categoría fiscal y el tipo son a nivel job, una llamada puede crear varios jobs (uno por combinación). Requiere una key automeli_live_*.\n\nScope requerido: `products:write`.\n\nRequiere una API Key live (`automeli_live_*`).\n\nSoporta `Idempotency-Key` para reintentos seguros.\n\nCosto: 1 crédito real por producto promovido con éxito.",
        "tags": [
          "Products"
        ],
        "responses": {
          "202": {
            "description": "Promoción aceptada. jobs[] lista un job por combinación de categoría fiscal + tipo de publicación; cada uno se sigue con GET /products/jobs/{jobId}. Para conciliar: promoted incluye los SKUs que quedaron duplicate (ya en cola en otro job) y nunca se publican — lo que realmente se encola es queued (promoted = queued + duplicates; ídem promoted_total = queued_total + duplicates_total). skipped_duplicate_sku lista los repetidos dentro de la misma llamada. Todos esos campos vienen siempre, con 0 o vacío incluido.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "jobs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "job_id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "automeli_tax_category": {
                            "type": "integer"
                          },
                          "ml_listing_type": {
                            "type": "string"
                          },
                          "promoted": {
                            "type": "integer"
                          },
                          "queued": {
                            "type": "integer"
                          },
                          "duplicates": {
                            "type": "integer"
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "requested": {
                      "type": "integer"
                    },
                    "promoted_total": {
                      "type": "integer"
                    },
                    "queued_total": {
                      "type": "integer"
                    },
                    "duplicates_total": {
                      "type": "integer"
                    },
                    "skipped_not_publishable": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "listing_id_test": {
                            "type": "string"
                          },
                          "ml_status": {
                            "type": "string"
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "not_found": {
                      "type": "array",
                      "items": {}
                    },
                    "skipped_duplicate_sku": {
                      "type": "array",
                      "items": {}
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "jobs": [
                    {
                      "job_id": "a1b2c3d4-…",
                      "status": "queued",
                      "name": "8 may 2026, 12:00:00",
                      "automeli_tax_category": 0,
                      "ml_listing_type": "gold_pro",
                      "promoted": 2,
                      "queued": 2,
                      "duplicates": 0
                    }
                  ],
                  "requested": 3,
                  "promoted_total": 2,
                  "queued_total": 2,
                  "duplicates_total": 0,
                  "skipped_not_publishable": [
                    {
                      "listing_id_test": "MCO7777777777",
                      "ml_status": "under_review"
                    }
                  ],
                  "not_found": [],
                  "skipped_duplicate_sku": []
                }
              }
            }
          },
          "400": {
            "description": "E_PROMOTE_NO_CANDIDATES: Ningún producto de prueba publicable coincide con lo pedido\nE_PRODUCT_CREDIT_EXHAUSTED: Sin créditos disponibles",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_PROMOTE_NO_CANDIDATES",
              "E_PRODUCT_CREDIT_EXHAUSTED"
            ]
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)\nE_PROMOTE_REQUIRES_LIVE_KEY: Endpoint /products/test/promote sólo acepta key live",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE",
              "E_PROMOTE_REQUIRES_LIVE_KEY"
            ]
          },
          "404": {
            "description": "E_ACCOUNT_NOT_FOUND: Cuenta Meli no encontrada",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_ACCOUNT_NOT_FOUND"
            ]
          },
          "409": {
            "description": "E_IDEMPOTENCY_CONFLICT: Misma Idempotency-Key con body distinto",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_IDEMPOTENCY_CONFLICT"
            ]
          },
          "422": {
            "description": "E_PRODUCT_INVALID_BODY: Body o query malformado (campo, fecha o estado inválido)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_PRODUCT_INVALID_BODY"
            ]
          },
          "429": {
            "description": "E_PRODUCT_MAX_CONCURRENT_JOBS: Ya tiene 6 jobs activos",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_PRODUCT_MAX_CONCURRENT_JOBS"
            ]
          }
        },
        "x-key-env": "live",
        "x-idempotent": true,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/test-products#promote",
        "x-error-codes": [
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_PROMOTE_REQUIRES_LIVE_KEY",
          "E_PROMOTE_NO_CANDIDATES",
          "E_IDEMPOTENCY_CONFLICT",
          "E_PRODUCT_INVALID_BODY",
          "E_PRODUCT_CREDIT_EXHAUSTED",
          "E_PRODUCT_MAX_CONCURRENT_JOBS",
          "E_ACCOUNT_NOT_FOUND"
        ],
        "x-scope": "products:write",
        "x-credit-cost": "1 crédito real por producto promovido con éxito.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "listing_ids_test": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "description": "IDs de las publicaciones en la cuenta de prueba (el listing_id_test de GET /products/test). Se normalizan (trim) y deduplican."
                  }
                },
                "additionalProperties": true,
                "required": [
                  "listing_ids_test"
                ]
              },
              "example": {
                "listing_ids_test": [
                  "MCO1943839161",
                  "MCO1943839175"
                ]
              }
            }
          },
          "x-fields": [
            {
              "name": "listing_ids_test",
              "type": "array (1-10.000)",
              "required": "yes",
              "description": "IDs de las publicaciones en la cuenta de prueba (el listing_id_test de GET /products/test). Se normalizan (trim) y deduplican."
            }
          ]
        }
      }
    },
    "/products/jobs/{jobId}": {
      "get": {
        "operationId": "v2-jobs-get",
        "summary": "Consultar el estado de un job",
        "description": "Devuelve el detalle del job y sus items, con los items paginados por cursor. Haga poll cada 5-10 segundos hasta que el status sea final (completed, failed o cancelled). Si el job publica el mismo SKU en más de un tipo de publicación, job.by_listing_type trae el desglose por tipo.\n\nScope requerido: `products:read`.\n\nCosto: Sin costo (lectura).",
        "tags": [
          "Jobs"
        ],
        "responses": {
          "200": {
            "description": "Estado del job + sus items, paginados por cursor.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {
                      "type": "object",
                      "properties": {
                        "job_id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string"
                        },
                        "total_items": {
                          "type": "integer"
                        },
                        "successful": {
                          "type": "integer"
                        },
                        "failed": {
                          "type": "integer"
                        },
                        "completed_at": {
                          "type": "string"
                        }
                      },
                      "additionalProperties": true
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "sku": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "listing_id": {
                            "type": "string"
                          },
                          "ml_listing_type": {
                            "type": "string"
                          },
                          "title": {
                            "type": "string"
                          },
                          "permalink": {
                            "type": "string"
                          },
                          "price": {
                            "type": "integer"
                          },
                          "message": {
                            "type": "null"
                          },
                          "error_category": {
                            "type": "null"
                          },
                          "retryable": {
                            "type": "boolean"
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "next_cursor": {
                      "type": "null"
                    },
                    "has_more": {
                      "type": "boolean"
                    },
                    "count": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "job": {
                    "job_id": "8a3f2b10-4c9d-4e21-9f8a-1b2c3d4e5f60",
                    "status": "completed",
                    "total_items": 2,
                    "successful": 2,
                    "failed": 0,
                    "completed_at": "2026-05-08T12:00:09.000Z"
                  },
                  "data": [
                    {
                      "sku": "B003H03SDQ",
                      "status": "success",
                      "listing_id": "MCO1234567890",
                      "ml_listing_type": "gold_pro",
                      "title": "Ejemplo de producto",
                      "permalink": "https://articulo.mercadolibre.com.co/…",
                      "price": 89000,
                      "message": null,
                      "error_category": null,
                      "retryable": false
                    }
                  ],
                  "next_cursor": null,
                  "has_more": false,
                  "count": 1
                }
              }
            }
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE"
            ]
          },
          "404": {
            "description": "E_JOB_NOT_FOUND: jobId no existe o no es de su seller",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_JOB_NOT_FOUND"
            ]
          },
          "422": {
            "description": "E_PRODUCT_INVALID_BODY: Body o query malformado (campo, fecha o estado inválido)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_PRODUCT_INVALID_BODY"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": false,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/jobs#status",
        "x-error-codes": [
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_JOB_NOT_FOUND",
          "E_PRODUCT_INVALID_BODY"
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "El job_id devuelto al crear el job.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Tamaño de página. Default 100.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Token opaco de la página siguiente (next_cursor de la respuesta anterior). Omitir para la primera página — sólo esa incluye total.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filtra los items por estado, ej. failed. duplicate = el SKU ya estaba publicado y vivo, o ya en cola en otro job: se saltó sin consumir crédito.",
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "dispatched",
                "success",
                "failed",
                "skipped",
                "duplicate"
              ]
            }
          }
        ],
        "x-scope": "products:read",
        "x-credit-cost": "Sin costo (lectura)."
      }
    },
    "/products/jobs": {
      "get": {
        "operationId": "v2-jobs-list",
        "summary": "Listar jobs",
        "description": "Listado paginado por cursor. Para auditoría o reconciliación con su sistema interno.\n\nScope requerido: `products:read`.\n\nCosto: Sin costo (lectura).",
        "tags": [
          "Jobs"
        ],
        "responses": {
          "200": {
            "description": "Página de jobs del seller que matchean el filtro.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "job_id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "ml_listing_type": {
                            "type": "string"
                          },
                          "test_mode": {
                            "type": "boolean"
                          },
                          "ml_site_id": {
                            "type": "string"
                          },
                          "total_items": {
                            "type": "integer"
                          },
                          "processed": {
                            "type": "integer"
                          },
                          "successful": {
                            "type": "integer"
                          },
                          "failed": {
                            "type": "integer"
                          },
                          "skipped": {
                            "type": "integer"
                          },
                          "scheduled_for": {
                            "type": "null"
                          },
                          "created_at": {
                            "type": "string"
                          },
                          "started_at": {
                            "type": "string"
                          },
                          "completed_at": {
                            "type": "string"
                          },
                          "updated_at": {
                            "type": "string"
                          },
                          "error_message": {
                            "type": "null"
                          }
                        },
                        "additionalProperties": true
                      }
                    },
                    "next_cursor": {
                      "type": "null"
                    },
                    "has_more": {
                      "type": "boolean"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "total": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "data": [
                    {
                      "job_id": "8a3f2b10-4c9d-4e21-9f8a-1b2c3d4e5f60",
                      "status": "completed",
                      "name": "8 may 2026, 12:00:00",
                      "ml_listing_type": "gold_pro",
                      "test_mode": false,
                      "ml_site_id": "MCO",
                      "total_items": 2,
                      "processed": 2,
                      "successful": 2,
                      "failed": 0,
                      "skipped": 0,
                      "scheduled_for": null,
                      "created_at": "2026-05-08T12:00:00.000Z",
                      "started_at": "2026-05-08T12:00:01.000Z",
                      "completed_at": "2026-05-08T12:00:09.000Z",
                      "updated_at": "2026-05-08T12:00:09.000Z",
                      "error_message": null
                    }
                  ],
                  "next_cursor": null,
                  "has_more": false,
                  "count": 1,
                  "total": 1
                }
              }
            }
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE"
            ]
          },
          "422": {
            "description": "E_PRODUCT_INVALID_BODY: Body o query malformado (campo, fecha o estado inválido)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_PRODUCT_INVALID_BODY"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": false,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/jobs#list",
        "x-error-codes": [
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_PRODUCT_INVALID_BODY"
        ],
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Tamaño de página. Default 50.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "Token opaco de la página siguiente (next_cursor de la respuesta anterior). Omitir para la primera página — sólo esa incluye total.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Filtra por estado del job.",
            "schema": {
              "type": "string",
              "enum": [
                "queued",
                "processing",
                "scheduled",
                "completed",
                "failed",
                "cancelled"
              ]
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Fecha desde (inclusive), formato YYYY-MM-DD.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Fecha hasta (inclusive), formato YYYY-MM-DD.",
            "schema": {
              "type": "string",
              "format": "date"
            }
          }
        ],
        "x-scope": "products:read",
        "x-credit-cost": "Sin costo (lectura)."
      }
    },
    "/products/jobs/{jobId}/retry": {
      "post": {
        "operationId": "v2-jobs-retry",
        "summary": "Reintentar items fallidos de un job",
        "description": "Reintenta items en failed con retryable: true (los que fallaron por causas transitorias). Sólo aplica sobre jobs terminales; el job vuelve a queued. Consume créditos por cada item reintentado.\n\nScope requerido: `products:write`.\n\nCosto: 1 crédito por item reintentado.",
        "tags": [
          "Jobs"
        ],
        "responses": {
          "202": {
            "description": "Reintento aceptado para los items retryables del job.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job_id": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    },
                    "retried": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "job_id": "8a3f2b10-4c9d-4e21-9f8a-1b2c3d4e5f60",
                  "status": "queued",
                  "retried": 3
                }
              }
            }
          },
          "400": {
            "description": "E_JOB_NOT_RETRYABLE: Job no terminal o sin items retryables\nE_PRODUCT_CREDIT_EXHAUSTED: Sin créditos disponibles",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_JOB_NOT_RETRYABLE",
              "E_PRODUCT_CREDIT_EXHAUSTED"
            ]
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE"
            ]
          },
          "404": {
            "description": "E_JOB_NOT_FOUND: jobId no existe o no es de su seller",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_JOB_NOT_FOUND"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": false,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/jobs#retry",
        "x-error-codes": [
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_JOB_NOT_FOUND",
          "E_JOB_NOT_RETRYABLE",
          "E_PRODUCT_CREDIT_EXHAUSTED"
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "El job_id terminal cuyos items fallidos se reintentan.",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-scope": "products:write",
        "x-credit-cost": "1 crédito por item reintentado."
      }
    },
    "/products/jobs/{jobId}/cancel": {
      "post": {
        "operationId": "v2-jobs-cancel",
        "summary": "Cancelar un job",
        "description": "Cancela jobs en queued, processing o scheduled. Los items pendientes pasan a skipped. Lo ya publicado no se revierte.\n\nScope requerido: `products:write`.\n\nCosto: Sin costo (no genera publicaciones nuevas).",
        "tags": [
          "Jobs"
        ],
        "responses": {
          "200": {
            "description": "Job cancelado. Los items pendientes quedan en skipped.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job_id": {
                      "type": "string"
                    },
                    "cancelled": {
                      "type": "boolean"
                    },
                    "skipped_items": {
                      "type": "integer"
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "job_id": "8a3f2b10-4c9d-4e21-9f8a-1b2c3d4e5f60",
                  "cancelled": true,
                  "skipped_items": 12
                }
              }
            }
          },
          "400": {
            "description": "E_JOB_ALREADY_TERMINAL: Cancel sobre job ya cerrado",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_JOB_ALREADY_TERMINAL"
            ]
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE"
            ]
          },
          "404": {
            "description": "E_JOB_NOT_FOUND: jobId no existe o no es de su seller",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_JOB_NOT_FOUND"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": false,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/jobs#cancel",
        "x-error-codes": [
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_JOB_NOT_FOUND",
          "E_JOB_ALREADY_TERMINAL"
        ],
        "parameters": [
          {
            "name": "jobId",
            "in": "path",
            "required": true,
            "description": "El job_id a cancelar (debe estar en un estado no terminal).",
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "x-scope": "products:write",
        "x-credit-cost": "Sin costo (no genera publicaciones nuevas)."
      }
    },
    "/account": {
      "get": {
        "operationId": "v2-account-get",
        "summary": "Info de la cuenta y créditos",
        "description": "Datos de la cuenta asociada a la API Key: conexión con Mercado Libre, créditos y la configuración con la que se publica. credits.available se calcula según el environment de la key usada.\n\nScope requerido: `account:read`.\n\nCosto: Sin costo (lectura).",
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "Cuenta, créditos y configuración de publicación efectiva del seller.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "seller_id": {
                      "type": "integer"
                    },
                    "email": {
                      "type": "string"
                    },
                    "ml_nickname": {
                      "type": "string"
                    },
                    "ml_site_id": {
                      "type": "string"
                    },
                    "amazon_site": {
                      "type": "string"
                    },
                    "ml_currency": {
                      "type": "string"
                    },
                    "ml_account_status": {
                      "type": "string"
                    },
                    "ml_connected": {
                      "type": "boolean"
                    },
                    "api_key": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        },
                        "environment": {
                          "type": "string"
                        },
                        "tier": {
                          "type": "string"
                        }
                      },
                      "additionalProperties": true
                    },
                    "credits": {
                      "type": "object",
                      "properties": {
                        "total": {
                          "type": "integer"
                        },
                        "available": {
                          "type": "integer"
                        },
                        "used_live": {
                          "type": "integer"
                        },
                        "used_test": {
                          "type": "integer"
                        }
                      },
                      "additionalProperties": true
                    },
                    "publishing_config": {
                      "type": "object",
                      "properties": {
                        "trm": {
                          "type": "integer"
                        },
                        "warranty_time": {
                          "type": "string"
                        },
                        "manufacturing_time_days": {
                          "type": "integer"
                        },
                        "stock_quantity": {
                          "type": "integer"
                        }
                      },
                      "additionalProperties": true
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "seller_id": 108386,
                  "email": "cuenta@ejemplo.com",
                  "ml_nickname": "MITIENDA",
                  "ml_site_id": "MCO",
                  "amazon_site": "amazon.com",
                  "ml_currency": "COP",
                  "ml_account_status": "active",
                  "ml_connected": true,
                  "api_key": {
                    "id": 12,
                    "name": "ERP Producción",
                    "environment": "live",
                    "tier": "default"
                  },
                  "credits": {
                    "total": 5000,
                    "available": 1240,
                    "used_live": 3760,
                    "used_test": 85
                  },
                  "publishing_config": {
                    "trm": 4100,
                    "warranty_time": "30 días",
                    "manufacturing_time_days": 12,
                    "stock_quantity": 5
                  }
                }
              }
            }
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE"
            ]
          },
          "404": {
            "description": "E_ACCOUNT_NOT_FOUND: Cuenta Meli no encontrada",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_ACCOUNT_NOT_FOUND"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": false,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/account#info",
        "x-error-codes": [
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_ACCOUNT_NOT_FOUND"
        ],
        "x-scope": "account:read",
        "x-credit-cost": "Sin costo (lectura)."
      }
    },
    "/account/tax-categories": {
      "get": {
        "operationId": "v2-account-tax-categories",
        "summary": "Categorías fiscales del seller",
        "description": "Devuelve las categorías fiscales configuradas por el seller. El `id` es exactamente el valor numérico que se pasa como automeli_tax_category en POST /products. Conviene cachear esta lista en lugar de hardcodear ids.\n\nScope requerido: `account:read`.\n\nCosto: Sin costo (lectura).",
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "Array de categorías fiscales tal cual están en la config del seller.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "seller_id": {
                      "type": "integer"
                    },
                    "tax_categories": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "integer"
                          },
                          "name": {
                            "type": "string"
                          },
                          "taxes": {
                            "type": "object",
                            "properties": {
                              "iva": {
                                "type": "integer"
                              },
                              "impuesto2": {
                                "type": "integer"
                              },
                              "impuesto3": {
                                "type": "integer"
                              },
                              "iva_v2": {
                                "type": "integer"
                              },
                              "impuesto2_v2": {
                                "type": "integer"
                              },
                              "impuesto3_v2": {
                                "type": "integer"
                              }
                            },
                            "additionalProperties": true
                          }
                        },
                        "additionalProperties": true
                      }
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "seller_id": 108386,
                  "tax_categories": [
                    {
                      "id": 0,
                      "name": "IVA 19%",
                      "taxes": {
                        "iva": 19,
                        "impuesto2": 0,
                        "impuesto3": 0,
                        "iva_v2": 19,
                        "impuesto2_v2": 0,
                        "impuesto3_v2": 0
                      }
                    }
                  ]
                }
              }
            }
          },
          "403": {
            "description": "E_AUTH_FORBIDDEN_SCOPE: Su key no tiene el permiso requerido (ver scopes)",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_FORBIDDEN_SCOPE"
            ]
          },
          "404": {
            "description": "E_ACCOUNT_NOT_FOUND: Cuenta Meli no encontrada",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_ACCOUNT_NOT_FOUND"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": false,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/account#tax-categories",
        "x-error-codes": [
          "E_AUTH_FORBIDDEN_SCOPE",
          "E_ACCOUNT_NOT_FOUND"
        ],
        "x-scope": "account:read",
        "x-credit-cost": "Sin costo (lectura)."
      }
    },
    "/ping": {
      "get": {
        "operationId": "v2-ping",
        "summary": "Verificar la API Key (health check autenticado)",
        "description": "La forma más rápida de validar el setup completo (DNS, credenciales, conectividad) antes de integrar. No requiere scope: cualquier key válida responde, con api_version: \"v2\".\n\nNo requiere scope: cualquier API Key válida funciona.\n\nCosto: Sin costo.",
        "tags": [
          "System"
        ],
        "responses": {
          "200": {
            "description": "La key es válida. Devuelve el seller asociado, el environment y la versión.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "api_version": {
                      "type": "string"
                    },
                    "seller_id": {
                      "type": "integer"
                    },
                    "environment": {
                      "type": "string"
                    },
                    "key_name": {
                      "type": "string"
                    },
                    "request_id": {
                      "type": "string"
                    },
                    "timestamp": {
                      "type": "string"
                    }
                  },
                  "additionalProperties": true
                },
                "example": {
                  "ok": true,
                  "api_version": "v2",
                  "seller_id": 108386,
                  "environment": "live",
                  "key_name": "ERP Producción",
                  "request_id": "cd66c602-…",
                  "timestamp": "2026-05-08T12:00:00.000Z"
                }
              }
            }
          },
          "401": {
            "description": "E_AUTH_MISSING_KEY: Falta el header X-API-Key\nE_AUTH_INVALID_KEY: Key con formato inválido o no reconocida\nE_AUTH_KEY_REVOKED: Key revocada por el dueño\nE_AUTH_KEY_EXPIRED: Key con expires_at vencido",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            },
            "x-error-codes": [
              "E_AUTH_MISSING_KEY",
              "E_AUTH_INVALID_KEY",
              "E_AUTH_KEY_REVOKED",
              "E_AUTH_KEY_EXPIRED"
            ]
          }
        },
        "x-key-env": "any",
        "x-idempotent": false,
        "x-stability": "beta",
        "x-doc-url": "https://www.automeli.com/api-docs/auth/verify",
        "x-error-codes": [
          "E_AUTH_MISSING_KEY",
          "E_AUTH_INVALID_KEY",
          "E_AUTH_KEY_REVOKED",
          "E_AUTH_KEY_EXPIRED"
        ],
        "x-credit-cost": "Sin costo."
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "API Key del seller, con prefijo automeli_live_* o automeli_test_*."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Problem Details (RFC 7807). `code` es el contrato público estable — haga switch sobre `code`, no sobre `title`.",
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "URI del tipo, https://api.automeli.com/errors/{code}."
          },
          "title": {
            "type": "string",
            "description": "Resumen legible. Puede cambiar."
          },
          "status": {
            "type": "integer",
            "description": "HTTP status code."
          },
          "code": {
            "type": "string",
            "enum": [
              "E_AUTH_MISSING_KEY",
              "E_AUTH_INVALID_KEY",
              "E_AUTH_KEY_REVOKED",
              "E_AUTH_KEY_EXPIRED",
              "E_AUTH_FORBIDDEN_SCOPE",
              "E_RATE_LIMITED",
              "E_IDEMPOTENCY_CONFLICT",
              "E_PRODUCT_INVALID_BODY",
              "E_PRODUCT_INVALID_SKU",
              "E_PRODUCT_CREDIT_EXHAUSTED",
              "E_PRODUCT_MAX_CONCURRENT_JOBS",
              "E_PROMOTE_NO_CANDIDATES",
              "E_PROMOTE_REQUIRES_LIVE_KEY",
              "E_CATEGORY_INVALID",
              "E_CATEGORY_AND_AUTO_CONFLICT",
              "E_JOB_NOT_FOUND",
              "E_JOB_NOT_RETRYABLE",
              "E_JOB_ALREADY_TERMINAL",
              "E_ACCOUNT_NOT_FOUND",
              "E_NOT_FOUND",
              "E_INTERNAL"
            ],
            "description": "Código machine-readable estable."
          },
          "instance": {
            "type": "string",
            "description": "Path de la request que falló."
          },
          "detail": {
            "type": "string",
            "description": "Detalle específico de esta ocurrencia."
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code"
        ],
        "additionalProperties": true
      }
    }
  }
}