Skip to content

Products API

🤖 Explain with AI

The Products API is designed to manage product data efficiently within an e-commerce environment. It supports product creation, modification, and deletion while handling pricing details, stock information, recurrence settings, taxes, and image management.

The API ensures clear and consistent responses, including detailed error handling and support for multiple currencies with proper precision validation.

Create a product

Endpoint

POST /v1/products/

This endpoint allows creating a new product in the system by sending a POST request with the product details — such as name, description, price, currency, stock, taxes, images, and recurrence settings.

Query Parameters:

Parameter Description Type Required
test Indicates if the product is in test mode boolean false

Request Body Fields:

Parameter Description Type Required
name Product name (max 50 characters) string true
short_description Brief product description (max 100 characters) string false
description Detailed product description (max 300 characters) string false
price Product price (validated by currency) decimal true
currency Currency code (USD, EUR, CRC, etc.) string false
stock Number of items in stock integer false
is_physical Whether product is physical (true/false) boolean false
bar_code Product barcode string false
sku Stock keeping unit string false
taxes Comma-separated tax IDs string false
recurrence Recurrence settings (JSON object) object false

Recurrence Object Format:

{
  "recurrence": "period",           // or "specific_billing_day"
  "duration_period": 1              // Valid: 1, 2, 3, 4, 6, 12 (months)
}

Or:

{
  "recurrence": "specific_billing_day",
  "payday": 15                       // Valid: 1-28
}

File Upload Parameters:

Parameter Description Type Required
image_default Default product image (file) file false
images Additional product images (max 4) file false

Request:

curl -X POST 'http://127.0.0.1:8000/v1/products/?test=false' \
     -u 'sk_test_51O62xYzAbcDef123:' \
     -F 'name=Premium Widget' \
     -F 'description=This is a premium widget product' \
     -F 'price=99.99' \
     -F 'currency=USD' \
     -F 'stock=50' \
     -F 'is_physical=true' \
     -F 'taxes=1,3' \
     -F 'sku=PREMIUM-WIDGET-001' \
     -F 'image_default=@/path/to/image.jpg' \
     -F 'recurrence={"recurrence":"period","duration_period":3}'

Response (201 Created):

{
  "code": 201,
  "title": "Complete registration",
  "content": "The registration was successfully completed.",
  "type": "success",
  "data": {
    "id": "d36a4a5c-9fa9-4d55-b47f-4f1d50f2a180"
  }
}

Get all products

Endpoint

GET /v1/products/

This endpoint retrieves a paginated list of all products with advanced filtering support. Supports pagination, search, filtering by type, price range, and stock levels.

Query Parameters:

Parameter Description Type Required
page The page number to retrieve (default: 1) integer false
page_size Products per page (default: 10, max: 100) integer false
test Filter by test mode (true/false) boolean false
search Search by name or SKU string false
type Filter by type (physical/digital) string false
stock_min Minimum stock level integer false
stock_max Maximum stock level integer false
price_min Minimum price (in product currency) decimal false
price_max Maximum price (in product currency) decimal false

Request:

curl -X GET 'http://127.0.0.1:8000/v1/products/?page=1&page_size=10&test=false' \
     -u 'sk_test_51O62xYzAbcDef123:'

Request (With Filters):

curl -X GET 'http://127.0.0.1:8000/v1/products/?page=1&search=widget&type=physical&price_min=10&price_max=100&stock_min=5' \
     -u 'sk_test_51O62xYzAbcDef123:'

Response (200 OK):

{
  "count": 25,
  "current_page": 1,
  "total_pages": 3,
  "results": [
    {
      "id": "a232cccc-956a-44ca-a2e8-d763afddc89f",
      "name": "Premium Widget",
      "short_description": "High-quality widget",
      "description": "This is a premium widget product with advanced features",
      "stock": 50,
      "price": "99.99",
      "currency": "USD",
      "total_price": "109.99",
      "is_physical": true,
      "bar_code": "123456789012",
      "sku": "PREMIUM-WIDGET-001",
      "recurrence": {
        "recurrence": "period",
        "duration_period": 3
      },
      "images": {
        "default": "https://storage.googleapis.com/bucket/image-default.jpg",
        "additional_images": [
          {"image": "https://storage.googleapis.com/bucket/image-1.jpg"},
          {"image": "https://storage.googleapis.com/bucket/image-2.jpg"}
        ]
      },
      "payment_link": false,
      "created_on": "2025-12-04T10:30:00Z",
      "test": false,
      "taxes": [
        {"id": 1, "name": "VAT", "value": 10.0}
      ]
    }
  ]
}

Get a specific product

Endpoint

GET /v1/products/{id}/

This endpoint retrieves complete details of a specific product by its unique ID.

Path Parameters:

Parameter Description Type Required
id The unique identifier of a product (UUID) string true

Query Parameters:

Parameter Description Type Required
test Filter by test mode (true/false) boolean false

Request:

curl -X GET 'http://127.0.0.1:8000/v1/products/f9b77185-a62e-4da9-a056-3c7b812ca334/?test=false' \
     -u 'sk_test_51O62xYzAbcDef123:'

Response (200 OK):

{
  "id": "f9b77185-a62e-4da9-a056-3c7b812ca334",
  "name": "Premium Widget",
  "short_description": "High-quality widget",
  "description": "This is a premium widget product with advanced features",
  "stock": 50,
  "price": "99.99",
  "currency": "USD",
  "total_price": "109.99",
  "is_physical": true,
  "bar_code": "123456789012",
  "sku": "PREMIUM-WIDGET-001",
  "recurrence": {
    "recurrence": "period",
    "duration_period": 3
  },
  "images": {
    "default": "https://storage.googleapis.com/bucket/image-default.jpg",
    "additional_images": [
      {"image": "https://storage.googleapis.com/bucket/image-1.jpg"},
      {"image": "https://storage.googleapis.com/bucket/image-2.jpg"}
    ]
  },
  "payment_link": false,
  "created_on": "2025-12-04T10:30:00Z",
  "test": false,
  "taxes": [
    {"id": 1, "name": "VAT", "value": 10.0}
  ]
}

Update a product

Endpoint

PUT /v1/products/{id}/

Updates an existing product with new details. You can update individual fields without affecting others.

Path Parameters:

Parameter Description Type Required
id The unique identifier of a product (UUID) string true

Query Parameters:

Parameter Description Type Required
test Filter by test mode (true/false) boolean false

Request Body Fields (all optional):

Parameter Description Type
name Product name (max 50 characters) string
short_description Brief product description (max 100 characters) string
description Detailed product description (max 300 characters) string
price Product price (validated by currency) decimal
currency Currency code (USD, EUR, CRC, etc.) string
stock Number of items in stock integer
is_physical Whether product is physical (true/false) boolean
bar_code Product barcode string
sku Stock keeping unit string
taxes Comma-separated tax IDs string
payment_link Enable as payment link boolean

Image Management Flags:

Parameter Value Action
default -1 Keep existing default image
default -remove- Remove default image
default <file> Replace with new image
additional_images -1 Keep existing additional images
additional_images -remove- Remove all additional images
additional_images <files> Replace with new images (max 4)

Request:

curl -X PUT 'http://127.0.0.1:8000/v1/products/f9b77185-a62e-4da9-a056-3c7b812ca334/?test=false' \
     -u 'sk_test_51O62xYzAbcDef123:' \
     -F 'name=Updated Widget Name' \
     -F 'description=Updated description' \
     -F 'price=79.99' \
     -F 'stock=100' \
     -F 'default=-1'

Response (200 OK):

{
  "code": 200,
  "title": "Updated product",
  "content": "The product was successfully updated.",
  "type": "success",
  "data": {
    "id": "f9b77185-a62e-4da9-a056-3c7b812ca334",
    "name": "Updated Widget Name",
    "description": "Updated description",
    "price": "79.99",
    "stock": 100,
    "total_price": "87.99"
  }
}

Delete a product

Endpoint

DELETE /v1/products/{id}/

Permanently deletes a product and deactivates it in Stripe.

Path Parameters:

Parameter Description Type Required
id The unique identifier of a product (UUID) string true

Query Parameters:

Parameter Description Type Required
test Filter by test mode (true/false) boolean false

Request:

curl -X DELETE 'http://127.0.0.1:8000/v1/products/f9b77185-a62e-4da9-a056-3c7b812ca334/?test=false' \
     -u 'sk_test_51O62xYzAbcDef123:'

Response (200 OK):

{
  "code": 200,
  "title": "Product deleted",
  "content": "The product was successfully deleted.",
  "type": "success"
}

Error Handling

The API returns standard HTTP status codes to indicate the success or failure of a request. Below are common errors specific to products:

400 Bad Request

Occurs when the request is malformed or has invalid data.

Scenarios:

Scenario Error Message Solution
Invalid price format "Price validation error: {message}" Verify price precision for currency (e.g., JPY uses 0 decimals)
Invalid recurrence JSON "Please check the format of recurrence, remember that it is a JSON object." Ensure recurrence is valid JSON format
Invalid duration period "The duration_period can contain only the following values 1, 2, 3, 4, 6, 12" Use valid month durations: 1, 2, 3, 4, 6, or 12
Invalid payday "The payday has to be greater than 0 and less than or equal to 28." Use day between 1-28

Example Error Response:

{
  "code": 400,
  "title": "Invalid price format",
  "content": "Price validation error: JPY requires 0 decimal places. Please adjust the price according to the currency requirements.",
  "type": "danger"
}

401 Unauthorized

Authentication failed. API Key is invalid, missing, or malformed.

Example:

{
  "detail": "Authentication credentials were not provided."
}

Solution: - Verify you included the -u 'sk_test_...: parameter or Authorization: Basic header - Ensure your API Key is correct and active - Test with Postman using Basic Auth

404 Not Found

The requested product does not exist.

Example:

{
  "code": 404,
  "title": "Product does not exist",
  "content": "The id 'f9b77185-a62e-4da9-a056-3c7b812ca334' does not correspond to any product",
  "type": "danger"
}

Solution: - Verify the product ID exists - Use the list endpoint to find the correct product ID - Ensure the product belongs to your developer account

406 Not Acceptable

The request violates business rules or validation constraints.

Example:

{
  "code": 406,
  "title": "Product registration failure",
  "content": "Failed to register the product, please check: Invalid field values",
  "type": "danger"
}

Important Notes

Price Validation

  • Prices are validated based on currency decimal places
  • JPY, CLP, and similar currencies use 0 decimal places
  • USD, EUR, GBP use 2 decimal places
  • KWD and similar currencies use 3 decimal places

Image Management

  • Default image: Displayed as primary product image
  • Additional images: Up to 4 supplementary images supported
  • Supported formats: JPEG, PNG
  • Maximum file size: 10MB per image
  • Use special flags (-1, -remove-) to manage existing images

Taxes

  • Products can have multiple taxes applied
  • Total price includes tax calculations
  • Taxes are linked by their IDs
  • Send comma-separated tax IDs: "taxes": "1,3,5"

Recurrence Settings

  • period: Fixed monthly recurrence (1, 2, 3, 4, 6, or 12 months)
  • specific_billing_day: Monthly on a specific day (1-28)
  • These settings apply when product is used in subscriptions

Test vs Production

  • Use your Test Key (sk_test_...) for development and testing
  • Use your Live Key (sk_live_...) for real transactions
  • Query parameter ?test=true or ?test=false controls the mode
  • The system automatically detects the mode based on the API Key used

Best Practices

  1. Validate prices carefully - Ensure prices match currency decimal place requirements
  2. Use descriptive names - Help customers understand products clearly
  3. Set accurate stock - Keep inventory counts updated
  4. Add images - Product images increase conversion rates
  5. Use SKUs - Unique SKUs help with inventory management
  6. Apply taxes correctly - Include all applicable tax IDs
  7. Test before production - Use test mode with test API keys for validation
  8. Use recurrence wisely - Only set recurrence for subscription-eligible products

Troubleshooting

Problem: “Price validation error: JPY requires 0 decimal places”

Cause: Using decimal places not supported by currency
Solution: - JPY: Use whole numbers (no decimals) - USD/EUR: Use 2 decimal places (99.99) - KWD: Use 3 decimal places (99.999)

Problem: “The duration_period can contain only the following values 1, 2, 3, 4, 6, 12”

Cause: Invalid recurrence period provided
Solution: - Use only: 1 (monthly), 2 (bimonthly), 3 (quarterly), 4 (4-monthly), 6 (semi-annual), or 12 (annual)

Problem: “The payday has to be greater than 0 and less than or equal to 28”

Cause: Invalid billing day provided
Solution: - Payday must be between 1 and 28 - Days 29-31 not supported to ensure monthly consistency

Problem: “Product does not exist”

Cause: Product ID doesn’t exist or belongs to different developer account
Solution: - Verify the product ID using the list endpoint - Ensure you’re using the correct API Key - Check the product hasn’t been deleted

Problem: “The specified state is invalid”

Cause: Invalid product type or filter value
Solution: - Use valid type values: “physical” or “digital” - Ensure filter parameters are properly formatted


FAQ

Q: Can I update only specific fields without affecting others?
A: Yes, send only the fields you want to update. Omitted fields retain their current values.

Q: How many images can I add to a product?
A: You can have 1 default image and up to 4 additional images (5 total).

Q: What currencies are supported?
A: Any currency supported by Stripe (USD, EUR, GBP, CRC, JPY, KWD, etc.). Verify decimal place requirements per currency.

Q: Can I apply multiple taxes to a product?
A: Yes, provide comma-separated tax IDs to apply multiple taxes.

Q: What happens when I delete a product?
A: The product is soft-deleted in our system and deactivated in Stripe. Historical payment links referencing it remain available.

Q: How do I use products with payment links?
A: Create the product first, then reference its ID when creating payment links. The product price and details are used for the transaction.

Q: Can I change a product’s currency after creation?
A: Yes, you can update the currency. Prices will be validated against the new currency’s decimal place requirements.

Q: What are recurrence settings used for?
A: Recurrence settings define how products are billed if used in subscriptions. They’re not required for one-time purchases.