Product resources are used to model a class of individual items, and as such should contain information common to all instances of that product. For example, a product resource could be used to describe a particular SKU or model of a physical product with specific characteristics including size, weight, color, market, GS1 identifiers etc.
Once created, each Thng that represents an individual instance of that product class is associated with the product resource containing the common information via its product
field. Products are useful to store properties or other data items that are common to a set of Thngs (so you don't need to replicate the model name or weight for thousands of Thngs that are individual instances of the same product).
Like Thngs, products can have properties and actions associated with them. In addition to specifying a product in a generic action request, it is also possible to create an action through the product itself using aliased actions.
Products can be referenced by their evrythng Id or their custom identifier value.
API Status
General Availability:
/products
/products/:productId
/products/:productIdentifier
/products/:productId/actions/:actionType
/products/:productId/properties
ProductDocument Data Model
Create a Product
Read a Product
Read all Products
Update a Product
Update Multiple Products
Delete a Product
Create a Product's Redirection
Read a Product's Redirection
Update a Product's Redirection
Delete a Product's Redirection
ProductDocument Data Model
An object representing a platform product.
.name (string, required)
Friendly name of this resource.
.id (string, read-only)
The ID of this resource.
.color (string)
Color of the product itself
.createdAt (integer, read-only)
Timestamp when the resource was created.
.updatedAt (integer, read-only)
Timestamp when the resource was updated.
.activatedAt (integer, read-only)
Timestamp when the product was activated.
.description (string)
Friendly description of this resource.
.type (string)
Type of this resource. Can be unset with an empty string.
.categories (array of string)
An array of product categories as strings.
.photos (array of string)
An array of product photo URLs as strings.
.url (string)
The URL linking to the product information.
.identifiers (IdentifiersDocument)
Various identifiers (EPC, GTIN, etc.) as a JSON object with
one or more key-value pairs. Identifiers which have keys
mentioned in account unique identifiers configuration will
be concatenated and used as unique identifier for a given
product which means that user will not be able to create
two products with the same unique identifiers.
.properties (object)
A JSON object with key-value pairs describing properties of
the product.
.tags (array of string)
Array of string tags associated with this resource.
.customFields (CustomFieldsDocument)
Object of case-sensititve key-value pairs of custom fields
associated with the resource.
.fn (string, read-only)
Friendly name of the product.
.brand (string)
The product's brand name.
.scopes (ScopesDocument)
Project and user scopes arrays.
.targetMarketCountries (array of string)
Array of 2-digit country codes (ISO 3166-1 2-digit).
{
"additionalProperties": false,
"type": "object",
"description": "An object representing a platform product.",
"required": ["name"],
"properties": {
"name": {
"type": "string",
"description": "Friendly name of this resource."
},
"id": {
"type": "string",
"description": "The ID of this resource.",
"pattern": "^[abcdefghkmnpqrstwxyABCDEFGHKMNPQRSTUVWXY0123456789]{24}$",
"readOnly": true
},
"color": {
"type": "string",
"description": "Color of the product itself"
},
"createdAt": {
"type": "integer",
"description": "Timestamp when the resource was created.",
"readOnly": true,
"minimum": 0
},
"updatedAt": {
"type": "integer",
"description": "Timestamp when the resource was updated.",
"readOnly": true,
"minimum": 0
},
"activatedAt": {
"type": "integer",
"description": "Timestamp when the product was activated.",
"readOnly": true
},
"description": {
"type": "string",
"description": "Friendly description of this resource."
},
"type": {
"type": "string",
"description": "Type of this resource. Can be unset with an empty string.",
"maxLength": 256
},
"categories": {
"description": "An array of product categories as strings.",
"type": "array",
"items": { "type": "string" }
},
"photos": {
"description": "An array of product photo URLs as strings.",
"type": "array",
"items": { "type": "string" }
},
"url": {
"type": "string",
"description": "The URL linking to the product information."
},
"identifiers": {
"type": "object",
"description": "Various identifiers (EPC, GTIN, etc.) as a JSON object with one or more key-value pairs. Identifiers which have keys mentioned in account unique identifiers configuration will be concatenated and used as unique identifier for a given product which means that user will not be able to create two products with the same unique identifiers."
},
"properties": {
"type": "object",
"description": "A JSON object with key-value pairs describing properties of the product."
},
"tags": {
"type": "array",
"description": "Array of string tags associated with this resource.",
"items": {
"type": "string",
"maxLength": 60
}
},
"customFields": {
"type": "object",
"description": "Object of case-sensititve key-value pairs of custom fields associated with the resource."
},
"fn": {
"type": "string",
"description": "Friendly name of the product.",
"readOnly": true
},
"brand": {
"type": "string",
"description": "The product's brand name."
},
"scopes": {
"additionalProperties": false,
"type": "object",
"description": "Project and user scopes arrays.",
"required": ["users", "projects"],
"properties": {
"users": {
"type": "array",
"description": "An array of Application User IDs this resource is scoped to.",
"items": { "type": "string" }
},
"projects": {
"type": "array",
"description": "An array of project IDs this resource is scoped to.",
"items": {
"type": "string",
"description": "The ID of this resource.",
"pattern": "^[abcdefghkmnpqrstwxyABCDEFGHKMNPQRSTUVWXY0123456789]{24}$",
"readOnly": true
}
}
}
}
},
"targetMarketCountries": {
"type": "array",
"description": "Array of 2-digit country codes (ISO 3166-1 2-digit).",
"items": {
"type": "string"
}
},
"x-filterable-fields": [
{
"name": "name",
"type": "string",
"operators": ["="]
},
{
"name": "identifiers.<key>",
"type": "string",
"operators": ["="]
},
{
"name": "tags",
"type": "list of string",
"operators": ["="]
}
]
}
{
"name":"T-shirt",
"identifiers": {
"gs1:01":"00995031756029",
"gs1:22":"00117765745435"
},
"targetMarketCountries": ["GB"]
}
See also: ScopesDocument
Filterable Fields
This resource type can be filtered using the following fields and operators.
Field | Type | Operators |
---|---|---|
name | String | = |
identifiers.<key> | String | = |
tags | List of string | = |
Create a Product
POST /products
Content-Type: application/json
Authorization: $OPERATOR_API_KEY
ProductDocument
curl -i -H "Content-Type: application/json" \
-H "Authorization: $OPERATOR_API_KEY" \
-X POST 'https://$EVT_API_DOMAIN/products' \
-d '{
"tags": [
"example",
"product"
],
"brand": "AS Garments Ltd.",
"name": "Soft Blue Tee",
"description": "An example product resource",
"photos": [
"https://upload.wikimedia.org/wikipedia/commons/8/84/Example.svg"
],
"identifiers": {
"gs1:01": "00043834898332"
}
}'
const payload = {
tags: [
'example',
'product'
],
brand: 'AS Garments Ltd.',
name: 'Soft Blue Tee',
description: 'An example product resource',
photos: [
'https://upload.wikimedia.org/wikipedia/commons/8/84/Example.svg'
],
identifiers: {
'gs1:01': '00043834898332'
}
};
operator.product().create(payload)
.then(console.log);
Product product = new Product();
product.setName("DLP-46EX");
product.setDescription("Example Product");
apiManager.productService().productCreator(product).execute();
HTTP/1.1 201 Created
Content-Type: application/json
Location: https://$EVT_API_DOMAIN/products/UrahkCNHqc8p9bwRwmrfBe3t
{
"id": "UrahkCNHqc8p9bwRwmrfBe3t",
"createdAt": 1560774106285,
"tags": [
"example",
"product"
],
"updatedAt": 1560774106285,
"brand": "AS Garments Ltd.",
"description": "An example product resource",
"fn": "Soft Blue Tee",
"name": "Soft Blue Tee",
"photos": [
"https://upload.wikimedia.org/wikipedia/commons/8/84/Example.svg"
],
"identifiers": {
"gs1:01": "00043834898332"
}
}
Read a Product
When provided a productId
, the Platform will return a single product document corresponding to that ID, if it exists.
GET /products/:productId
Authorization: $OPERATOR_API_KEY
curl -H "Authorization: $OPERATOR_API_KEY" \
-X GET 'https://$EVT_API_DOMAIN/products/UrahkCNHqc8p9bwRwmrfBe3t'
const productId = 'UrahkCNHqc8p9bwRwmrfBe3t';
app.product(productId).read()
.then(console.log);
String productId = "UrahkCNHqc8p9bwRwmrfBe3t";
Product product = apiManager.productService().productReader(productId).execute();
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "UrahkCNHqc8p9bwRwmrfBe3t",
"createdAt": 1560774106285,
"tags": [
"example",
"product"
],
"updatedAt": 1560774106285,
"brand": "AS Garments Ltd.",
"description": "An example product resource",
"fn": "Soft Blue Tee",
"name": "Soft Blue Tee",
"photos": [
"https://upload.wikimedia.org/wikipedia/commons/8/84/Example.svg"
],
"identifiers": {
"gs1:01": "00043834898332"
}
}
You can also specify a valid custom identifier instead; such as reading the product with identifier gtin
value 12345678901234
:
GET /products/gtin:12345678901234
Authorization: $OPERATOR_API_KEY
Read all Products
Read all products in scope of the authenticating API key. The result may be paginated if there are more than 30 items.
GET /products
Authorization: $OPERATOR_API_KEY
curl -H "Authorization: $OPERATOR_API_KEY" \
-X GET 'https://$EVT_API_DOMAIN/products'
// List products in the App's Project context
app.product().read()
.then(console.log);
// List products managed/visible to the user
user.product.read()
.then(console.log);
Iterator<PVector<Product>> products = apiManager.productService().iterator().perPage(10).execute();
while(products.hasNext()) {
PVector<Product> page = products.next();
for(Product product : page) {
System.out.println("Product: " + product.getName());
}
}
HTTP/1.1 200 OK
Content-Type: application/json
[
{
"id": "UrahkCNHqc8p9bwRwmrfBe3t",
"createdAt": 1560774106285,
"tags": [
"example",
"product"
],
"updatedAt": 1560774106285,
"brand": "AS Garments Ltd.",
"description": "An example product resource",
"fn": "Soft Blue Tee",
"name": "Soft Blue Tee",
"photos": [
"https://upload.wikimedia.org/wikipedia/commons/8/84/Example.svg"
],
"identifiers": {
"gs1:01": "00043834898332"
}
}
]
Update a Product
Update a single product by ID.
PUT /products/:productId
Content-Type: application/json
Authorization: $OPERATOR_API_KEY
ProductDocument (subset)
curl -i -H "Content-type: application/json" \
-H "Authorization: $OPERATOR_API_KEY" \
-X PUT 'https://$EVT_API_DOMAIN/products/UXGmadd2EwqQkXe3F5Gg4hbg' \
-d '{
"name": "New Product Name"
}'
const productId = 'UXGmadd2EwqQkXe3F5Gg4hbg';
const payload = {
name: 'New Product Name',
};
user.product(productId).update(payload)
.then(console.log);
String productId = "UXGmadd2EwqQkXe3F5Gg4hbg";
Product product = apiManager.productService().productReader(productId).execute();
product.setName("New Product Name");
product.setDescription("Updated product description");
apiManager.productService().productUpdater(productId, product).execute();
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "UrahkCNHqc8p9bwRwmrfBe3t",
"createdAt": 1560774106285,
"tags": [
"example",
"product"
],
"updatedAt": 1560774106285,
"brand": "AS Garments Ltd.",
"description": "An example product resource",
"fn": "New Product Name",
"name": "New Product Name",
"photos": [
"https://upload.wikimedia.org/wikipedia/commons/8/84/Example.svg"
],
"identifiers": {
"gs1:01": "00043834898332"
}
}
Delete a Product
Danger!
Deleting a product resource will remove its
product
reference from all Thngs that point to it. This action cannot be reversed!
DELETE /products/:productId
Authorization: $OPERATOR_API_KEY
curl -H "Authorization: $OPERATOR_API_KEY" \
-X DELETE 'https://$EVT_API_DOMAIN/products/UEqs3aV3NyYGVRxhmnphVGdh'
const productId = 'UEqs3aV3NyYGVRxhmnphVGdh';
operator.product(productId)
.delete()
.then(() => console.log('Deleted!'));
String productId = "UEqs3aV3NyYGVRxhmnphVGdh";
apiManager.productService().productDeleter(productId).execute();
HTTP/1.1 200 OK
Update Multiple Products
Using a suitable filter, it is possible to apply (PUT
) an updated ProductDocument
to multiple products, providing they match the filter
query parameter. For example, all products that begin with "Test"
to contain the 'test' tag.
PUT /products?filter=name%3DSmart*
Content-Type: application/json
Authorization: $OPERATOR_API_KEY
{
"tags": ["shipped"]
}
curl -H "Content-Type: application/json" \
-H "Authorization: $OPERATOR_API_KEY" \
-X PUT 'https://$EVT_API_DOMAIN/products?filter=name%3DSmart*' \
-d '{
"tags": ["shipped"]
}'
const payload = { tags: ['shipped'] };
const params = { filter: 'name=Test*' };
operator.product().update(payload, { params })
.then(console.log);
The update will be applied asynchronously, and the response will be 204 'No Content'.
HTTP/1.1 204 No Content
Create a Product's Redirection
Use the appropriate short domain API to create a product redirection. This example uses tn.gg
.
POST https://<short domain>/redirections
Content-Type: application/json
Accept: application/json
Authorization: $OPERATOR_API_KEY
RedirectionDocument
curl -H "Content-Type: application/json" \
-H "Authorization: $OPERATOR_API_KEY" \
-H "Accept: application/json" \
-X POST 'https://tn.gg/redirections' \
-d '{
"type": "product",
"evrythngId": "Uk6qwgSReXPat5awagfNpHsk",
"defaultRedirectUrl": "https://www.example.com?product={productId}"
}'
const productId = 'Uk6qwgSReXPat5awagfNpHsk';
// 'type' and 'evrythngId' are handled by the SDK
const payload = {
defaultRedirectUrl: 'https://www.example.com?product={productId}'
};
operator.product(productId).redirection('tn.gg')
.create(payload)
.then(console.log);
HTTP/1.1 201 Created
Content-Type: application/json
{
"createdAt": 1496668317836,
"updatedAt": 1496668348257,
"defaultRedirectUrl": "https://www.example.com?product=Uk6qwgSReXPat5awagfNpHsk",
"evrythngUrl": "https://api.evrythng.com/products/Uk6qwgSReXPat5awagfNpHsk",
"shortDomain": "tn.gg",
"shortId": "799yeEi4qp",
"hits": 0
}
Response format
By default, you will get a binary containing the QR code for the redirection in the response. To retrieve the JSON object, include an
Accept: application/json
header.
Read a Product's Redirection
Use the appropriate short domain redirection API to read a product redirection.
GET https://<short domain>/redirections?evrythngId=:productId
Authorization: $OPERATOR_API_KEY
Accept: application/json
curl -H "Authorization: $OPERATOR_API_KEY" \
-H "Accept: application/json" \
-X GET 'https://tn.gg/redirections?evrythngId=Uk6qwgSReXPat5awagfNpHsk'
const productId = 'Uk6qwgSReXPat5awagfNpHsk';
operator.product(productId).redirection('tn.gg')
.read()
.then(console.log);
HTTP/1.1 200 OK
Content-Type: application/json
{
"createdAt": 1496664729327,
"updatedAt": 1496664729327,
"defaultRedirectUrl": "https://www.example.com?product=Uk6qwgSReXPat5awagfNpHsk",
"evrythngUrl": "https://api.evrythng.com/products/Uk6qwgSReXPat5awagfNpHsk",
"shortDomain": "tn.gg",
"shortId": "799yeEi4qp",
"hits": 0
}
Update a Product's Redirection
Use the appropriate short domain redirection API and short ID to update a product redirection.
PUT https://<short domain>/redirections/:shortId
Content-Type: application/json
Authorization: $OPERATOR_API_KEY
RedirectionDocument
curl -H "Content-Type: application/json" \
-H "Authorization: $OPERATOR_API_KEY" \
-X PUT 'https://tn.gg/redirections/799yeEi4qp' \
-d '{
"defaultRedirectUrl": "https://www.brand.com?product={productId}"
}'
const productId = 'Uk6qwgSReXPat5awagfNpHsk';
const payload = {
defaultRedirectUrl: 'https://www.brand.com?product={productId}'
};
operator.product(productId).redirection('tn.gg')
.update(payload)
.then(console.log);
HTTP/1.1 201 Created
Content-Type: application/json
{
"createdAt": 1496668317836,
"updatedAt": 1496668348257,
"defaultRedirectUrl": "https://www.brand.com?product=Uk6qwgSReXPat5awagfNpHsk",
"evrythngUrl": "https://api.evrythng.com/products/Uk6qwgSReXPat5awagfNpHsk",
"shortDomain": "tn.gg",
"shortId": "799yeEi4qp",
"hits": 0
}
Delete a Product's Redirection
DELETE https://<short domain>/redirections/:shortId
Authorization: $OPERATOR_API_KEY
curl -H "Authorization: $OPERATOR_API_KEY" \
-X DELETE 'https://tn.gg/redirections/799yeEi4qp'
const productId = 'Uk6qwgSReXPat5awagfNpHsk';
operator.product(productId).redirection('tn.gg')
.delete();
HTTP/1.1 200 OK
Content-Type: application/json