Nuvemshop Product Variants API
Manage the variants (size, color, and other option combinations) owned by a product, including per-variant pricing and stock, bulk collection replacement, and a dedicated stock-update endpoint.
Manage the variants (size, color, and other option combinations) owned by a product, including per-variant pricing and stock, bulk collection replacement, and a dedicated stock-update endpoint.
openapi: 3.0.3
info:
title: Nuvemshop / Tiendanube Admin API
description: >-
Store-scoped REST Admin API for the Nuvemshop (Tiendanube) e-commerce
platform. This document models a grounded, representative subset of the
public API - products, product variants, product images, categories,
orders, customers, coupons, webhooks, scripts, and store - as documented at
https://tiendanube.github.io/api-documentation/.
Every path is relative to a per-store base that embeds the store id, for
example `https://api.tiendanube.com/2025-03/{store_id}`. The Brazilian
mirror `https://api.nuvemshop.com.br/2025-03/{store_id}` serves the same
API, and the long-standing `v1` path
(`https://api.tiendanube.com/v1/{store_id}`) remains available as the legacy
equivalent.
Authentication is OAuth 2 (authorization code grant). The resulting
non-expiring access token is sent in a NON-STANDARD header named
`Authentication` with a lowercase `bearer` prefix
(`Authentication: bearer ACCESS_TOKEN`) - using `Authorization` or a
different case returns 401. Every request must also send a descriptive
`User-Agent` header identifying the app and a contact (name/email or URL);
omitting it returns 400.
NOTE ON MODELING: endpoint paths, methods, and the auth/header/rate-limit
behavior below are grounded in the live documentation. Request and response
body schemas are simplified representative models (marked with
additionalProperties) rather than the provider's full field-level schema.
version: '2025-03'
contact:
name: Nuvemshop / Tiendanube Developers
url: https://tiendanube.github.io/api-documentation/
license:
name: MIT (documentation)
url: https://github.com/TiendaNube
servers:
- url: https://api.tiendanube.com/2025-03/{store_id}
description: Tiendanube (Spanish-speaking markets)
variables:
store_id:
default: '0'
description: The numeric store id (user_id) returned during OAuth authorization.
- url: https://api.nuvemshop.com.br/2025-03/{store_id}
description: Nuvemshop (Brazil)
variables:
store_id:
default: '0'
description: The numeric store id (user_id) returned during OAuth authorization.
security:
- authenticationHeader: []
tags:
- name: Products
description: Items for sale in the store.
- name: Product Variants
description: Option combinations (size, color, etc.) owned by a product.
- name: Product Images
description: Images attached to a product.
- name: Categories
description: Hierarchical catalog categories.
- name: Orders
description: Customer purchases and their lifecycle.
- name: Customers
description: Registered customer accounts.
- name: Coupons
description: Discount coupons.
- name: Webhooks
description: Event notification subscriptions.
- name: Scripts
description: Custom JavaScript injected into the storefront.
- name: Store
description: Store settings and metadata.
paths:
/products:
get:
operationId: listProducts
tags: [Products]
summary: List products
description: Receive a paginated list of all products in the store.
parameters:
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/PerPage'
- name: q
in: query
required: false
description: Filter products by a free-text search term.
schema:
type: string
- name: fields
in: query
required: false
description: Comma-separated list of fields to return.
schema:
type: string
responses:
'200':
description: A list of products.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Product'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
post:
operationId: createProduct
tags: [Products]
summary: Create a product
description: Create a new product in the store.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductInput'
responses:
'201':
description: The created product.
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/ValidationError'
'429':
$ref: '#/components/responses/RateLimited'
/products/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getProduct
tags: [Products]
summary: Get a product
description: Receive a single product by its id.
responses:
'200':
description: The requested product.
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateProduct
tags: [Products]
summary: Update a product
description: Modify an existing product.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ProductInput'
responses:
'200':
description: The updated product.
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
'422':
$ref: '#/components/responses/ValidationError'
delete:
operationId: deleteProduct
tags: [Products]
summary: Delete a product
description: Remove a product from the store.
responses:
'200':
description: Deletion confirmation (empty object).
content:
application/json:
schema:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/products/sku/{sku}:
parameters:
- name: sku
in: path
required: true
description: The SKU of a product variant.
schema:
type: string
get:
operationId: getProductBySku
tags: [Products]
summary: Get a product by variant SKU
description: Receive the product that owns the variant with the given SKU.
responses:
'200':
description: The requested product.
content:
application/json:
schema:
$ref: '#/components/schemas/Product'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/products/stock-price:
patch:
operationId: updateProductsStockPrice
tags: [Products]
summary: Bulk update stock and price
description: Update stock and/or price for multiple products and variants in one request.
requestBody:
required: true
content:
application/json:
schema:
type: array
items:
type: object
description: Array of product/variant stock and price update objects.
responses:
'200':
description: Bulk update result.
content:
application/json:
schema:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/ValidationError'
/products/{product_id}/variants:
parameters:
- $ref: '#/components/parameters/ProductId'
get:
operationId: listProductVariants
tags: [Product Variants]
summary: List product variants
description: Receive a list of all variants for a given product.
responses:
'200':
description: A list of variants.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Variant'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createProductVariant
tags: [Product Variants]
summary: Create a product variant
description: Create a new variant for a product.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/VariantInput'
responses:
'201':
description: The created variant.
content:
application/json:
schema:
$ref: '#/components/schemas/Variant'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/ValidationError'
put:
operationId: replaceProductVariants
tags: [Product Variants]
summary: Replace the variant collection
description: Update the entire variant collection owned by a specific product.
requestBody:
required: true
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/VariantInput'
responses:
'200':
description: The updated variant collection.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Variant'
'401':
$ref: '#/components/responses/Unauthorized'
patch:
operationId: patchProductVariants
tags: [Product Variants]
summary: Partially update the variant collection
description: Partially update a product's variant collection.
requestBody:
required: true
content:
application/json:
schema:
type: array
items:
type: object
responses:
'200':
description: The updated variant collection.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Variant'
'401':
$ref: '#/components/responses/Unauthorized'
/products/{product_id}/variants/{id}:
parameters:
- $ref: '#/components/parameters/ProductId'
- $ref: '#/components/parameters/Id'
get:
operationId: getProductVariant
tags: [Product Variants]
summary: Get a product variant
description: Receive a single variant of a product.
responses:
'200':
description: The requested variant.
content:
application/json:
schema:
$ref: '#/components/schemas/Variant'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateProductVariant
tags: [Product Variants]
summary: Update a product variant
description: Modify an existing variant.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/VariantInput'
responses:
'200':
description: The updated variant.
content:
application/json:
schema:
$ref: '#/components/schemas/Variant'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteProductVariant
tags: [Product Variants]
summary: Delete a product variant
description: Remove a variant from a product.
responses:
'200':
description: Deletion confirmation (empty object).
content:
application/json:
schema:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/products/{product_id}/variants/stock:
parameters:
- $ref: '#/components/parameters/ProductId'
post:
operationId: updateVariantStock
tags: [Product Variants]
summary: Update variant stock
description: Update the stock for one or all variants of a product.
requestBody:
required: true
content:
application/json:
schema:
type: object
additionalProperties: true
responses:
'200':
description: Stock update result.
content:
application/json:
schema:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
/products/{product_id}/images:
parameters:
- $ref: '#/components/parameters/ProductId'
get:
operationId: listProductImages
tags: [Product Images]
summary: List product images
description: Receive a list of all images for a given product.
responses:
'200':
description: A list of images.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Image'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createProductImage
tags: [Product Images]
summary: Create a product image
description: Attach a new image to a product, by URL or base64 attachment.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ImageInput'
responses:
'201':
description: The created image.
content:
application/json:
schema:
$ref: '#/components/schemas/Image'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/ValidationError'
/products/{product_id}/images/{id}:
parameters:
- $ref: '#/components/parameters/ProductId'
- $ref: '#/components/parameters/Id'
get:
operationId: getProductImage
tags: [Product Images]
summary: Get a product image
description: Receive a single product image.
responses:
'200':
description: The requested image.
content:
application/json:
schema:
$ref: '#/components/schemas/Image'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateProductImage
tags: [Product Images]
summary: Update a product image
description: Modify an existing product image.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/ImageInput'
responses:
'200':
description: The updated image.
content:
application/json:
schema:
$ref: '#/components/schemas/Image'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteProductImage
tags: [Product Images]
summary: Delete a product image
description: Remove an image from a product.
responses:
'200':
description: Deletion confirmation (empty object).
content:
application/json:
schema:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/categories:
get:
operationId: listCategories
tags: [Categories]
summary: List categories
description: Receive a list of all categories.
responses:
'200':
description: A list of categories.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Category'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createCategory
tags: [Categories]
summary: Create a category
description: Create a new category.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CategoryInput'
responses:
'201':
description: The created category.
content:
application/json:
schema:
$ref: '#/components/schemas/Category'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/ValidationError'
/categories/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getCategory
tags: [Categories]
summary: Get a category
description: Receive a single category.
responses:
'200':
description: The requested category.
content:
application/json:
schema:
$ref: '#/components/schemas/Category'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateCategory
tags: [Categories]
summary: Update a category
description: Modify an existing category.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CategoryInput'
responses:
'200':
description: The updated category.
content:
application/json:
schema:
$ref: '#/components/schemas/Category'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteCategory
tags: [Categories]
summary: Delete a category
description: Remove a category.
responses:
'200':
description: Deletion confirmation (empty object).
content:
application/json:
schema:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/orders:
get:
operationId: listOrders
tags: [Orders]
summary: List orders
description: Receive a paginated list of all orders.
parameters:
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/PerPage'
- name: status
in: query
required: false
description: Filter by order status (e.g. open, closed, cancelled, any).
schema:
type: string
responses:
'200':
description: A list of orders.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Order'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
post:
operationId: createOrder
tags: [Orders]
summary: Create an order
description: Create a new order.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OrderInput'
responses:
'201':
description: The created order.
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/ValidationError'
/orders/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getOrder
tags: [Orders]
summary: Get an order
description: Receive a single order by its id.
responses:
'200':
description: The requested order.
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateOrder
tags: [Orders]
summary: Update an order
description: Change order attributes and/or update status.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/OrderInput'
responses:
'200':
description: The updated order.
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/orders/{id}/history/values:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getOrderValueHistory
tags: [Orders]
summary: Get order value history
description: Receive the value-alteration history of an order.
responses:
'200':
description: The order value history.
content:
application/json:
schema:
type: array
items:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/orders/{id}/history/editions:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getOrderEditionHistory
tags: [Orders]
summary: Get order edition history
description: Receive the edition history of an order.
responses:
'200':
description: The order edition history.
content:
application/json:
schema:
type: array
items:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/orders/{id}/subscriptions:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getOrderSubscriptions
tags: [Orders]
summary: Get order subscriptions
description: Receive the subscriptions associated with an order.
responses:
'200':
description: The order subscriptions.
content:
application/json:
schema:
type: array
items:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/orders/{id}/close:
parameters:
- $ref: '#/components/parameters/Id'
post:
operationId: closeOrder
tags: [Orders]
summary: Close an order
description: Close an order.
responses:
'200':
description: The closed order.
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/orders/{id}/open:
parameters:
- $ref: '#/components/parameters/Id'
post:
operationId: openOrder
tags: [Orders]
summary: Re-open an order
description: Re-open a previously closed order.
responses:
'200':
description: The re-opened order.
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/orders/{id}/cancel:
parameters:
- $ref: '#/components/parameters/Id'
post:
operationId: cancelOrder
tags: [Orders]
summary: Cancel an order
description: Cancel an order.
responses:
'200':
description: The cancelled order.
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/customers:
get:
operationId: listCustomers
tags: [Customers]
summary: List customers
description: Receive a list of all customers.
parameters:
- $ref: '#/components/parameters/Page'
- $ref: '#/components/parameters/PerPage'
responses:
'200':
description: A list of customers.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Customer'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createCustomer
tags: [Customers]
summary: Create a customer
description: Create a new customer.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerInput'
responses:
'201':
description: The created customer.
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/ValidationError'
/customers/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getCustomer
tags: [Customers]
summary: Get a customer
description: Receive a single customer.
responses:
'200':
description: The requested customer.
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateCustomer
tags: [Customers]
summary: Update a customer
description: Modify an existing customer.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerInput'
responses:
'200':
description: The updated customer.
content:
application/json:
schema:
$ref: '#/components/schemas/Customer'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteCustomer
tags: [Customers]
summary: Delete a customer
description: Delete a customer.
responses:
'200':
description: Deletion confirmation (empty object).
content:
application/json:
schema:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/coupons:
get:
operationId: listCoupons
tags: [Coupons]
summary: List coupons
description: Retrieve the list of all coupons.
responses:
'200':
description: A list of coupons.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Coupon'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createCoupon
tags: [Coupons]
summary: Create a coupon
description: Create a new coupon.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CouponInput'
responses:
'201':
description: The created coupon.
content:
application/json:
schema:
$ref: '#/components/schemas/Coupon'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/ValidationError'
/coupons/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getCoupon
tags: [Coupons]
summary: Get a coupon
description: Retrieve a single coupon.
responses:
'200':
description: The requested coupon.
content:
application/json:
schema:
$ref: '#/components/schemas/Coupon'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
put:
operationId: updateCoupon
tags: [Coupons]
summary: Update a coupon
description: Modify an existing coupon.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CouponInput'
responses:
'200':
description: The updated coupon.
content:
application/json:
schema:
$ref: '#/components/schemas/Coupon'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
delete:
operationId: deleteCoupon
tags: [Coupons]
summary: Delete a coupon
description: Delete an existing coupon.
responses:
'200':
description: Deletion confirmation (empty object).
content:
application/json:
schema:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
'404':
$ref: '#/components/responses/NotFound'
/webhooks:
get:
operationId: listWebhooks
tags: [Webhooks]
summary: List webhooks
description: Receive a list of all webhook subscriptions.
responses:
'200':
description: A list of webhooks.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Webhook'
'401':
$ref: '#/components/responses/Unauthorized'
post:
operationId: createWebhook
tags: [Webhooks]
summary: Create a webhook
description: >-
Subscribe to an event. The `event` field accepts values such as
order/created, order/paid, order/cancelled, product/created,
product/updated, product/deleted, customer/created, category/updated,
app/uninstalled, and many more (see the Webhook documentation).
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/WebhookInput'
responses:
'201':
description: The created webhook.
content:
application/json:
schema:
$ref: '#/components/schemas/Webhook'
'401':
$ref: '#/components/responses/Unauthorized'
'422':
$ref: '#/components/responses/ValidationError'
/webhooks/{id}:
parameters:
- $ref: '#/components/parameters/Id'
get:
operationId: getWebhook
tags: [Webhooks]
summary: Get a webho
# --- truncated at 32 KB (47 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/nuvemshop/refs/heads/main/openapi/nuvemshop-openapi.yml