openapi: 3.0.3 info: title: 'Ecommerce API Documentation' description: 'This is the documentation for the Ecommerce API.' version: 1.0.0 servers: - url: 'https://api-ecomm.incubator.t2.newss.beer' paths: /external/v1/customers: get: summary: 'Display a listing of registered and unregistered customers.' operationId: displayAListingOfRegisteredAndUnregisteredCustomers description: '' parameters: - in: query name: page description: 'Optional. Page number for pagination. Default: 1.' example: 2 required: false schema: type: integer description: 'Optional. Page number for pagination. Default: 1.' example: 2 - in: query name: limit description: 'Optional. Number of results per page (maximum 100). Default: 15.' example: 20 required: false schema: type: integer description: 'Optional. Number of results per page (maximum 100). Default: 15.' example: 20 - in: query name: search description: 'Search term to filter by name, email or phone. Must not be greater than 255 characters.' example: Juan required: false schema: type: string description: 'Search term to filter by name, email or phone. Must not be greater than 255 characters.' example: Juan - in: query name: registered description: 'Optional. Filter by customer type. true: registered only, false: unregistered only, null: all.' example: true required: false schema: type: boolean description: 'Optional. Filter by customer type. true: registered only, false: unregistered only, null: all.' example: true responses: 200: description: '' content: application/json: schema: type: object example: data: - customer_id: 1 email: customer@example.com firstname: Juan lastname: Pérez telephone: '1234567890' status: 1 date_added: '2025-01-15 10:30:00' - customer_id: 0 email: unregistered@example.com firstname: María lastname: González telephone: '0987654321' status: 1 date_added: '2025-01-15 10:30:00' meta: current_page: 1 from: 1 last_page: 5 links: - url: null label: '« Previous' active: false - url: 'https://api.example.com/external/v1/customers?page=1' label: '1' active: true - url: 'https://api.example.com/external/v1/customers?page=2' label: '2' active: false - url: 'https://api.example.com/external/v1/customers?page=2' label: 'Next »' active: false path: 'https://api.example.com/external/v1/customers' per_page: 15 to: 15 total: 78 properties: data: type: array example: - customer_id: 1 email: customer@example.com firstname: Juan lastname: Pérez telephone: '1234567890' status: 1 date_added: '2025-01-15 10:30:00' - customer_id: 0 email: unregistered@example.com firstname: María lastname: González telephone: '0987654321' status: 1 date_added: '2025-01-15 10:30:00' items: type: object properties: customer_id: type: integer example: 1 email: type: string example: customer@example.com firstname: type: string example: Juan lastname: type: string example: Pérez telephone: type: string example: '1234567890' status: type: integer example: 1 date_added: type: string example: '2025-01-15 10:30:00' meta: type: object properties: current_page: type: integer example: 1 from: type: integer example: 1 last_page: type: integer example: 5 links: type: array example: - url: null label: '« Previous' active: false - url: 'https://api.example.com/external/v1/customers?page=1' label: '1' active: true - url: 'https://api.example.com/external/v1/customers?page=2' label: '2' active: false - url: 'https://api.example.com/external/v1/customers?page=2' label: 'Next »' active: false items: type: object properties: url: type: string example: null label: type: string example: '« Previous' active: type: boolean example: false path: type: string example: 'https://api.example.com/external/v1/customers' per_page: type: integer example: 15 to: type: integer example: 15 total: type: integer example: 78 tags: - Customers /external/v1/products: get: summary: 'Display a listing of the products.' operationId: displayAListingOfTheProducts description: '' parameters: - in: query name: page description: 'Optional. Page number for pagination. Default: 1.' example: 2 required: false schema: type: integer description: 'Optional. Page number for pagination. Default: 1.' example: 2 - in: query name: limit description: 'Optional. Number of results per page. Default: 12.' example: 24 required: false schema: type: integer description: 'Optional. Number of results per page. Default: 12.' example: 24 - in: query name: 'filter[search]' description: 'Search by text.' example: tractor required: false schema: type: string description: 'Search by text.' example: tractor - in: query name: 'filter[category]' description: 'Filter by category.' example: 1 required: false schema: type: integer description: 'Filter by category.' example: 1 - in: query name: 'filter[variants]' description: 'Filter by variants.' example: 'color:red' required: false schema: type: string description: 'Filter by variants.' example: 'color:red' - in: query name: 'filter[tags]' description: 'Filter by tags.' example: oferta required: false schema: type: string description: 'Filter by tags.' example: oferta - in: query name: sort description: "Sort results.\nAllowed values: sort_order, -sort_order, price, -price, date_added, -date_added, name, -name." example: price required: false schema: type: string description: "Sort results.\nAllowed values: sort_order, -sort_order, price, -price, date_added, -date_added, name, -name." example: price responses: 200: description: '' content: text/plain: schema: type: string example: "{\n \"data\": [\n {\n \"id\": 1837,\n \"product_id\": 1837,\n \"name\": \"Tornillos para strap de talones (pack x 5)\",\n \"price\": 18793,\n \"order_price\": 18793,\n \"sku\": \"\",\n \"special\": null,\n \"hasDiscount\": false,\n \"min_price\": 18793,\n \"max_price\": 18793,\n \"count_variants\": 0,\n \"id_first_variant\": null,\n \"image\": \"host1/b69b712f7bd6757ddcda59959c89a2b1//img/products/\",\n \"date_added\": \"2025-09-10 13:39:36\",\n \"url\": \"demos-2./tornillos-para-strap-de-talones-(pack-x-5)\",\n \"status\": 1,\n \"currency_code\": \"ARS\"\n },\n {\n\t \"id\": 1838,\n\t \"product_id\": 1838,\n\t\t\"name\": \"Tornillos para strap de dedos (pack x 5) (copia)\",\n\t\t\"price\": 18793,\n\t\t\"order_price\": 18793,\n\t\t\"sku\": \"\",\n\t\t\"special\": null,\n\t\t\"hasDiscount\": false,\n\t\t\"min_price\": 18793,\n\t\t\"max_price\": 18793,\n\t\t\"count_variants\": 0,\n\t\t\"id_first_variant\": null,\n\t\t\"image\": \"host1/b69b712f7bd6757ddcda59959c89a2b1//img/products/\",\n\t\t\"date_added\": \"2025-09-10 13:39:36\",\n\t\t\"url\": \"demos-2./tornillos-para-strap-de-dedos-(pack-x-5)-(copia)\",\n\t\t\"status\": 1,\n\t\t\"currency_code\": \"ARS\"\n\t}\n ],\n\"meta\": {\n\"current_page\": 1,\n\t\"from\": 1,\n\t\"last_page\": 10,\n\t\"links\": [\n\t\t{\n\t\t\t\"url\": null,\n\t\t\t\"label\": \"« Previous\",\n\t\t\t\"active\": false\n\t\t},\n\t{\n\t\t\t\"url\": \"https://api-ecomm.llujan.t2.newss.beer/external/v1/products?page=1\",\n\t\t\t\"label\": \"1\",\n\t\t\t\"active\": true\n\t\t},\n\t\t{\n\t\t\t\"url\": \"https://api-ecomm.llujan.t2.newss.beer/external/v1/products?page=2\",\n\t\t\t\"label\": \"2\",\n\t\t\t\"active\": false\n\t\t}\n\t\t{\n\t\t\t\"url\": \"https://api-ecomm.llujan.t2.newss.beer/external/v1/products?page=2\",\n\t\t\t\"label\": \"Next »\",\n\t\t\t\"active\": false\n\t\t}\n\t],\n\t\"path\": \"https://api-ecomm.llujan.t2.newss.beer/external/v1/products\",\n\t\"per_page\": 10,\n\"to\": 10,\n\t\"total\": 99\n}\n}" tags: - Products post: summary: "Create a new product with variants. When providing variants, all possible combinations of attributes must be included.\nFor example, if you specify one color (azul) and two sizes (s, l), you must provide both combinations (azul-s, azul-l)." operationId: createANewProductWithVariantsWhenProvidingVariantsAllPossibleCombinationsOfAttributesMustBeIncludedForExampleIfYouSpecifyOneColorazulAndTwoSizessLYouMustProvideBothCombinationsazulSAzulL description: '' parameters: [] responses: 201: description: '' content: application/json: schema: type: object example: data: product_id: 123 name: 'Remera Deportiva' sku: REM-DEPO-001 properties: data: type: object properties: product_id: type: integer example: 123 name: type: string example: 'Remera Deportiva' sku: type: string example: REM-DEPO-001 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: variants: - 'Incomplete variant set. Expected 2 variants but got 1. Missing combinations: color=azul, talle=l. Please provide all 2 possible combinations.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: variants: type: array example: - 'Incomplete variant set. Expected 2 variants but got 1. Missing combinations: color=azul, talle=l. Please provide all 2 possible combinations.' items: type: string tags: - Products requestBody: required: true content: application/vnd.api+json: schema: type: object properties: name: type: string description: 'Product name.' example: 'Remera Deportiva' description: type: string description: 'Product description.' example: 'Remera 100% algodón' status: type: boolean description: 'Product status.' example: true video: type: string description: 'Video URL.' example: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ' product_type: type: string description: 'Product type.' example: '1' digital_product_url: type: string description: 'Digital product URL.' example: null price: type: number description: 'Product price.' example: 100.0 has_discount: type: boolean description: 'Has discount.' example: false special_price: type: number description: 'Special price.' example: null control_stock: type: boolean description: 'Control stock.' example: true quantity: type: integer description: Quantity. example: 25 sku: type: string description: SKU. example: REM-DEPO-001 width: type: number description: Width. example: 30.0 height: type: number description: Height. example: 40.0 length: type: number description: Length. example: 10.0 weight: type: number description: Weight. example: 0.25 tag: type: string description: Tags. example: 'algodon,deporte' product_category: type: integer description: 'Category ID.' example: 5 variants: type: array description: 'Array of variant combinations. All combinations of attribute values must be included.' example: - attributes: color: azul talle: s quantity: 10 price: 100 sku: REM-AZUL-S - attributes: color: azul talle: l quantity: 15 price: 100 sku: REM-AZUL-L items: type: object properties: attributes: type: object description: 'Variant attributes as key-value pairs.' example: color: azul talle: s properties: { } status: type: boolean description: 'Variant status.' example: true price: type: number description: 'Variant price.' example: 100.0 has_discount: type: boolean description: 'Variant has discount.' example: false special_price: type: number description: 'Variant special price.' example: null control_stock: type: boolean description: 'Variant control stock.' example: true quantity: type: integer description: 'Variant quantity.' example: 10 sku: type: string description: 'Variant SKU.' example: REM-AZUL-S required: - attributes required: - name - variants patch: summary: "Update multiple products and their variants in a single request. Update stock, prices, discounts and status. Each product is processed independently - failures won't affect other products. Variants are identified by their attributes (e.g., color, size)." operationId: updateMultipleProductsAndTheirVariantsInASingleRequestUpdateStockPricesDiscountsAndStatusEachProductIsProcessedIndependentlyFailuresWontAffectOtherProductsVariantsAreIdentifiedByTheirAttributesegColorSize description: '' parameters: [] responses: 200: description: '' content: application/json: schema: type: object example: data: - type: product id: '1837' success: true attributes: quantity: 100 price: 18793.5 status: true - type: product id: '1838' success: true attributes: variants_updated: 1 - type: product id: '9999' success: false errors: - status: '422' source: pointer: /data/2/id title: 'Update failed' detail: 'No query results for model [App\Models\Site\Ecommerce\Product] 9999' meta: total: 3 successful: 2 failed: 1 version: 1.0.0 processed_at: '2025-10-07T14:30:00+00:00' properties: data: type: array example: - type: product id: '1837' success: true attributes: quantity: 100 price: 18793.5 status: true - type: product id: '1838' success: true attributes: variants_updated: 1 - type: product id: '9999' success: false items: type: object properties: type: type: string example: product id: type: string example: '1837' success: type: boolean example: true attributes: type: object properties: quantity: type: integer example: 100 price: type: number example: 18793.5 status: type: boolean example: true errors: type: array example: - status: '422' source: pointer: /data/2/id title: 'Update failed' detail: 'No query results for model [App\Models\Site\Ecommerce\Product] 9999' items: type: object properties: status: type: string example: '422' source: type: object properties: pointer: type: string example: /data/2/id title: type: string example: 'Update failed' detail: type: string example: 'No query results for model [App\Models\Site\Ecommerce\Product] 9999' meta: type: object properties: total: type: integer example: 3 successful: type: integer example: 2 failed: type: integer example: 1 version: type: string example: 1.0.0 processed_at: type: string example: '2025-10-07T14:30:00+00:00' 422: description: '' content: application/json: schema: type: object example: message: 'The given data was invalid.' errors: products: - 'Debe proporcionar al menos un producto para actualizar.' properties: message: type: string example: 'The given data was invalid.' errors: type: object properties: products: type: array example: - 'Debe proporcionar al menos un producto para actualizar.' items: type: string tags: - Products requestBody: required: true content: application/vnd.api+json: schema: type: object properties: products: type: array description: 'Array of products to update (minimum 1, maximum 100).' example: - product_id: 1837 quantity: 100 price: 18793.5 has_discount: true special_price: 15000.0 status: true variants: - attributes: color: blanco talle: xl quantity: 50 price: 19000.0 has_discount: false special_price: 18000.0 - product_id: 1838 quantity: 50 price: 12500.0 status: false items: type: object properties: product_id: type: integer description: 'Product ID to update.' example: 1837 quantity: type: integer description: 'Product stock quantity.' example: 100 price: type: number description: 'Product price.' example: 18793.5 has_discount: type: boolean description: 'Indicates if the product has an active discount.' example: true special_price: type: number description: 'Product discounted price.' example: 15000.0 status: type: boolean description: 'Product status: true (active) or false (inactive).' example: true variants: type: array description: 'Array of product variants to update.' example: - attributes: color: blanco talle: xl quantity: 50 price: 19000.0 items: type: object properties: attributes: type: object description: 'Attributes that identify the variant as a key-value object.' example: color: blanco talle: xl properties: { } quantity: type: integer description: 'Variant stock quantity.' example: 50 price: type: number description: 'Variant price.' example: 19000.0 has_discount: type: boolean description: 'Indicates if the variant has an active discount.' example: false special_price: type: number description: 'Variant discounted price.' example: 18000.0 required: - attributes required: - product_id required: - products '/external/v1/products/{id}': get: summary: 'Display a single product by ID with its variants, images, and related data.' operationId: displayASingleProductByIDWithItsVariantsImagesAndRelatedData description: '' parameters: - in: query name: include description: "Optional relationships to include. Comma-separated values.\nAllowed: productDescription, categories, tags, productOptions, productSpecial, images." example: 'productDescription,productOptions' required: false schema: type: string description: "Optional relationships to include. Comma-separated values.\nAllowed: productDescription, categories, tags, productOptions, productSpecial, images." example: 'productDescription,productOptions' responses: 200: description: '' content: application/json: schema: type: object example: data: id: 1837 product_id: 1837 name: 'Remera Deportiva' price: 18793 order_price: 18793 sku: REM-001 special: null hasDiscount: false min_price: 18793 max_price: 18793 count_variants: 2 id_first_variant: 1 image: host1/b69b712f7bd6757ddcda59959c89a2b1//img/products/remera.jpg date_added: '2025-09-10 13:39:36' url: remera-deportiva status: 1 currency_code: ARS properties: data: type: object properties: id: type: integer example: 1837 product_id: type: integer example: 1837 name: type: string example: 'Remera Deportiva' price: type: integer example: 18793 order_price: type: integer example: 18793 sku: type: string example: REM-001 special: type: string example: null hasDiscount: type: boolean example: false min_price: type: integer example: 18793 max_price: type: integer example: 18793 count_variants: type: integer example: 2 id_first_variant: type: integer example: 1 image: type: string example: host1/b69b712f7bd6757ddcda59959c89a2b1//img/products/remera.jpg date_added: type: string example: '2025-09-10 13:39:36' url: type: string example: remera-deportiva status: type: integer example: 1 currency_code: type: string example: ARS 404: description: '' content: application/json: schema: type: object example: message: 'Product not found' properties: message: type: string example: 'Product not found' tags: - Products parameters: - in: path name: id description: 'Product ID.' example: 1837 required: true schema: type: integer tags: - name: Customers description: '' - name: Products description: '' components: securitySchemes: default: type: http scheme: bearer description: 'The access token is obtained by generating it from the administration panel.' security: - default: []