Vatly
Api Reference

One-off Products

On this page, we'll dive into the different one-off product endpoints you can use to query your products programmatically.

A one-off product is a digital product that can be bought once. Products can be created via the API or in the Vatly dashboard, and added to checkouts.

Looking for subscription plans? See the Subscription Plans API instead.

The one-off product model

Below you'll find all properties for the Vatly One-off Product API resource.

Properties

NameTypeDescription
idstringUnique identifier for the product (starts with one_off_product_).
resourcestringThe resource type. Always one_off_product.
testmodebooleanWhether this product is in test mode.
namestringDisplay name of the product.
descriptionstringDetailed description of the product.
basePriceMoneyDefault price of the product (can be overridden in checkout). A Money object with value (decimal string) and currency (ISO 4217 code). Interpretation depends on taxBehavior: when exclusive, basePrice is the net amount and tax is added at checkout; when inclusive, basePrice already includes tax.
taxBehaviorstringWhether basePrice is tax-exclusive (exclusive, B2B convention; tax added on top at checkout) or tax-inclusive (inclusive, B2C convention; price already includes tax). Immutable after product creation. A checkout may not mix products with different taxBehavior values.
productTypestringTax product classification. One of saas (software supplied as a service) or ebook (an electronic publication supplied as a download or stream).
statusstringCurrent status of the product. Can be active (product is active and can be purchased), pending (awaiting approval), or rejected (has been rejected).
archivedAtstring | nullWhen this product was archived (ISO 8601), or null while it is on sale. Always present. An archived product is hidden from GET /v1/one-off-products and refused by POST /v1/checkouts.
pendingUpdatesobject | nullThe changes that will take effect once a submitted update is approved, or null when there is no pending update. Only the fields that differ from the live product are present.
updateStatusstring | nullLifecycle of a pending update, or null when there is none. Can be pending (an update was submitted and is awaiting review) or reviewing (the update is being reviewed).
createdAtstringWhen this product was created (ISO 8601 format).
linksobjectHATEOAS links to related resources. Contains self link.

List all one-off products

GET /v1/one-off-products

This endpoint retrieves a paginated list of all one-off products.

Only products with active status can be used in checkouts. Archived products are excluded unless includeArchived=true is passed.

Optional parameters

NameTypeDescription
limitintegerThe number of products to return (default: 10, max: 100).
startingAfterstringA cursor for use in pagination. Returns results after this product ID.
endingBeforestringA cursor for use in pagination. Returns results before this product ID.
includeArchivedbooleanInclude archived products in the listing (default: false). Tell them apart by the non-null archivedAt.
curl -G https://api.vatly.com/v1/one-off-products \
  -H "Authorization: Bearer live_your_api_key_here" \
  -d limit=10

Create a one-off product

POST /v1/one-off-products

Creates a new one-off product for the authenticated merchant, in the testmode determined from the API token.

A product created with a live_ token starts in pending status and must be approved by Vatly before it can be used in checkouts — the same review that applies to products created in the dashboard. A product created with a test_ token is auto-approved (active) so you can trial checkout immediately.

Required attributes

NameTypeDescription
namestringDisplay name of the product (3–255 characters).
descriptionstringDetailed description of the product.
basePriceMoneyPrice of the product. A Money object with value (decimal string) and currency (ISO 4217 code).
productTypestringTax product classification. One of saas (Software as a Service) or ebook (electronic book).

Optional attributes

NameTypeDescription
taxBehaviorstringWhether basePrice is tax-exclusive (exclusive, B2B convention) or tax-inclusive (inclusive, B2C convention). Defaults to exclusive. Immutable after product creation.
curl https://api.vatly.com/v1/one-off-products \
  -H "Authorization: Bearer live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Premium License",
    "description": "Lifetime access to all premium features",
    "basePrice": { "value": "299.00", "currency": "EUR" },
    "productType": "saas"
  }'

Get a specific one-off product

GET /v1/one-off-products/:oneOffProductId

This endpoint retrieves a specific one-off product by its ID.

Parameters

NameTypeDescription
oneOffProductIdstringThe ID of the one-off product to retrieve.
curl https://api.vatly.com/v1/one-off-products/one_off_product_Vr8kQdFhSrG4Y3DnfsdqH \
  -H "Authorization: Bearer live_your_api_key_here"

Request an update to a one-off product

PATCH /v1/one-off-products/:oneOffProductId

Submits an update to a live one-off product. Because products drive VAT-bearing sales, the change is held as a pending update and reviewed by Vatly before it takes effect (updateStatus moves pendingreviewing → applied). In test mode the update is approved automatically.

Each request is the complete set of changes relative to the current live product. Fields equal to the live value are ignored, and a request that nets to no change clears any pending update. A new request replaces the not-yet-reviewed one; while an update is being reviewed, further requests return 409.

Parameters

NameTypeDescription
oneOffProductIdstringThe ID of the one-off product to update.

Optional attributes

At least one attribute must be provided. taxBehavior is immutable and cannot be changed here.

NameTypeDescription
namestringNew display name of the product (3–255 characters).
descriptionstringNew description of the product.
basePriceMoneyNew price of the product. A Money object with value (decimal string) and currency (ISO 4217 code).
productTypestringNew tax product classification. One of saas or ebook.
curl -X PATCH https://api.vatly.com/v1/one-off-products/one_off_product_Vr8kQdFhSrG4Y3DnfsdqH \
  -H "Authorization: Bearer live_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Premium License v2",
    "basePrice": { "value": "349.00", "currency": "EUR" }
  }'

Archive a one-off product

POST /v1/one-off-products/:oneOffProductId/archive

Archives the product so it can no longer be sold. It is hidden from GET /v1/one-off-products (unless includeArchived=true) and refused by POST /v1/checkouts; existing orders and refunds are untouched.

Archiving applies to new checkouts only. A checkout created before the product was archived snapshots its product data at creation time and can still be completed — the same window that applies when a product is rejected after a checkout was opened.

Nothing is deleted — the product remains readable by ID, now carrying a non-null archivedAt. Archiving is not queued behind Vatly's product review, and leaves any pending update in place. Repeating the request is a no-op that returns 204 and does not move archivedAt. Reverse it with DELETE /v1/one-off-products/:oneOffProductId/archive.

Parameters

NameTypeDescription
oneOffProductIdstringThe ID of the one-off product to archive.
curl -X POST https://api.vatly.com/v1/one-off-products/one_off_product_Vr8kQdFhSrG4Y3DnfsdqH/archive \
  -H "Authorization: Bearer live_your_api_key_here"

Returns 204 No Content on success (or when the product is already archived).


Unarchive a one-off product

DELETE /v1/one-off-products/:oneOffProductId/archive

Puts an archived product back on sale: it reappears in GET /v1/one-off-products and can be added to checkouts again. Calling it on a product that is not archived is a no-op.

Parameters

NameTypeDescription
oneOffProductIdstringThe ID of the one-off product to unarchive.
curl -X DELETE https://api.vatly.com/v1/one-off-products/one_off_product_Vr8kQdFhSrG4Y3DnfsdqH/archive \
  -H "Authorization: Bearer live_your_api_key_here"
Copyright © 2026