V1 API Adjusted Endpoints for suppliers, taxClasses, Sellers¶
Standard JSON:API endpoints for products, variants, and related resources.
Base URL: https://app.aico.swiss/{workspaceId}/api/v1
Authentication: All endpoints require a Bearer Token Auth header
Content Type: Accept: application/vnd.api+json
Table of Contents¶
- Products
- List Products
- Get Product
- Product Relationships
- Assign Suppliers to Product
- Assign Sellers to Product
- Assign Tax Classes to Product
- Product Prices
- Product Category Sets
- Product Nutritional Values
- Product Scheduled Prices
- Product Custom Fields
- Product Shopify Sync
- Tax Classes
- Product Tax Classes
- Sellers
- B2B / Suppliers
- List B2Bs (filter by customer group)
- Create B2B / Supplier
- Bulk Product Import
- Submit Bulk Import
- List Imports
- Get Import Status
- Download Error Report
- Real-time Updates (WebSocket)
- User Notifications
- List User Notifications
Products¶
Resource Type: products
Endpoint: GET /api/v1/products
Standard JSON:API resource for products with support for includes, filtering, and pagination.
List Products¶
Endpoint: GET /api/v1/products
Query Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
page[number] |
int | 1 | Page number |
page[size] |
int | 15 | Items per page |
include |
string | - | Comma-separated list of relationships |
filter[sku] |
string | - | Filter by SKU |
filter[id] |
string | - | Filter by ID(s) |
Available Includes¶
| Include | Description |
|---|---|
category |
Product category |
brand |
Product brand |
tags |
Product tags |
collections |
Product collections |
variationOptions |
Variation options |
variants |
Product variants |
metafields |
Product metafields |
productPrices |
Product prices with currency |
productVatValues |
VAT values per country |
productTaxClasses |
Tax classes with tax area and current rate |
sellers |
Associated sellers |
suppliers |
Associated suppliers (B2B companies) |
Response Fields¶
| Field | Type | Description |
|---|---|---|
id |
int | Product ID |
sku |
string | Product SKU |
barcode |
string | Product barcode |
name |
string | Product name (translated) |
webName |
string | Web name (translated) |
description |
string | Description (translated) |
image |
string | Product image URL |
weightValue |
float | Weight value |
weightUnit |
string | Weight unit |
provenance |
string | Provenance/origin |
hsCode |
string | HS code |
pageTitle |
string | SEO page title |
metaDescription |
string | SEO meta description |
urlHandle |
string | URL handle/slug |
hasSkuTracking |
boolean | Has SKU tracking enabled |
manufacturerSku |
string | Manufacturer SKU |
createdAt |
datetime | Creation date |
updatedAt |
datetime | Last update date |
Example Requests¶
# Basic request
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# With includes
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products?include=productTaxClasses,sellers,suppliers,productPrices" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# With pagination
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products?page[number]=1&page[size]=25" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# Filter by SKU
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products?filter[sku]=PRD-001" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Get Product¶
Endpoint: GET /api/v1/products/{id}
Get a single product by ID.
Example Request¶
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products/123?include=productTaxClasses,sellers,suppliers" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Product Relationships¶
The following relationships can be accessed directly:
| Endpoint | Description |
|---|---|
GET /api/v1/products/{id}/category |
Get product category |
GET /api/v1/products/{id}/brand |
Get product brand |
GET /api/v1/products/{id}/tags |
Get product tags |
GET /api/v1/products/{id}/collections |
Get product collections |
GET /api/v1/products/{id}/variants |
Get product variants |
GET /api/v1/products/{id}/productPrices |
Get product prices |
GET /api/v1/products/{id}/productVatValues |
Get VAT values |
GET /api/v1/products/{id}/productTaxClasses |
Get tax classes |
GET /api/v1/products/{id}/sellers |
Get associated sellers |
GET /api/v1/products/{id}/suppliers |
Get associated suppliers (B2B) |
Assign Suppliers to Product¶
Endpoint: POST /api/v1/products/{id}/relationships/suppliers
Attach suppliers (B2B companies) to a product.
Request Body¶
Example Request¶
curl --globoff -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/397/relationships/suppliers" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"data":[{"type":"b2bs","id":"10141"}]}'
Remove Suppliers¶
Endpoint: DELETE /api/v1/products/{id}/relationships/suppliers
curl --globoff -X DELETE "https://app.aico.swiss/{workspaceId}/api/v1/products/397/relationships/suppliers" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"data":[{"type":"b2bs","id":"10141"}]}'
Assign Sellers to Product¶
Endpoint: POST /api/v1/products/{id}/relationships/sellers
Attach sellers to a product.
Request Body¶
Example Request¶
curl --globoff -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/397/relationships/sellers" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"data":[{"type":"sellers","id":"3"}]}'
Remove Sellers¶
Endpoint: DELETE /api/v1/products/{id}/relationships/sellers
curl --globoff -X DELETE "https://app.aico.swiss/{workspaceId}/api/v1/products/397/relationships/sellers" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"data":[{"type":"sellers","id":"3"}]}'
Assign Tax Classes to Product¶
Endpoint: POST /api/v1/products/{id}/tax-classes
Create a new ProductTaxClass by specifying the tax class ID and tax area ID directly. This endpoint creates the association between a product, tax class, and tax area.
If a ProductTaxClass already exists for the given product and tax area, it will be updated with the new tax class ID.
Request Body¶
Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
taxClassId |
int | Yes | The ID of the tax class to apply |
taxAreaId |
int | Yes | The ID of the tax area (country/region) |
Response¶
Returns the created/updated ProductTaxClass with related data:
{
"data": {
"id": 123,
"productId": 22767,
"taxClassId": 5,
"taxAreaId": 1,
"taxClassName": "Standard Rate",
"taxCode": "UN81",
"taxAreaName": "Switzerland",
"message": "Tax class added to product successfully"
}
}
Example Request¶
curl --globoff -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/22767/tax-classes" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"data":{"taxClassId":5,"taxAreaId":1}}'
Product Prices¶
Get Product Prices¶
Endpoint: GET /api/v1/products/{id}/all-prices
Get all prices for a product including both base prices and scheduled prices.
Response¶
Returns product prices and variant prices with all price types (BASE, SCHEDULED).
{
"data": {
"id": 397,
"type": "product-prices",
"attributes": {
"productPrices": [
{
"id": 385,
"value": 5.46,
"buyingPrice": 1.29,
"estimatedBuyingPrice": null,
"discountPrice": null,
"unitPrice": null,
"measurementUnit": null,
"measurementUnitValue": null,
"hasMonthlyFees": false,
"hasAnnualFees": false,
"isClassicPrice": true,
"isFree": false,
"priceType": "BASE",
"activeFrom": null,
"activeUntil": null,
"isActive": true,
"calculatedPrice": null,
"calculatedBuyingPrice": null,
"calculatedDiscountPrice": null,
"createdAt": "2022-11-17 15:35:56",
"updatedAt": "2025-12-31 04:27:53",
"currency": {
"id": 1,
"name": "CHF"
}
}
],
"variantPrices": []
}
}
}
Price Fields¶
| Field | Type | Description |
|---|---|---|
id |
int | Price ID |
value |
float | Selling price |
buyingPrice |
float | Purchase/cost price |
discountPrice |
float | Discounted price |
priceType |
string | Price type: BASE or SCHEDULED |
activeFrom |
datetime | Start date for scheduled prices |
activeUntil |
datetime | End date for scheduled prices |
isActive |
boolean | Whether this price is currently active |
currency |
object | Currency info with id and name |
Example Request¶
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products/397/all-prices" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Save Product Prices¶
Endpoint: POST /api/v1/products/{id}/prices
Save prices for a product and its variants in a single request. Supports multiple currencies.
Request Body¶
{
"data": [
{
"currencyId": 1,
"productPrice": {
"value": 29.90,
"buyingPrice": 15.00,
"discountPrice": 24.90
},
"productVariantPrices": [
{
"sku": "VARIANT-001",
"value": 34.90,
"buyingPrice": 18.00,
"discountPrice": 29.90
}
]
}
]
}
Fields¶
| Field | Type | Description |
|---|---|---|
currencyId |
int | Currency ID (1=CHF, 2=EUR, 3=USD, etc.) |
productPrice.value |
float | Selling price |
productPrice.buyingPrice |
float | Purchase/cost price |
productPrice.discountPrice |
float | Discounted price |
productVariantPrices |
array | Array of variant prices |
productVariantPrices[].sku |
string | Variant SKU |
productVariantPrices[].value |
float | Variant selling price |
productVariantPrices[].buyingPrice |
float | Variant purchase price |
productVariantPrices[].discountPrice |
float | Variant discounted price |
Example Request¶
curl --globoff -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/397/prices" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"data": [
{
"currencyId": 1,
"productPrice": {
"value": 5.90,
"buyingPrice": 1.50,
"discountPrice": 0
}
}
]
}'
Product Category Sets¶
List All Category Sets¶
Endpoint: GET /api/v1/products/category-sets
Get category sets for all products. Requires pagination.
Query Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
page[number] |
int | Yes | Page number |
page[size] |
int | Yes | Items per page |
Example Request¶
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products/category-sets?page[number]=1&page[size]=10" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Example Response¶
{
"meta": {
"currentPage": 1,
"lastPage": 123,
"perPage": 10,
"total": 614
},
"data": [
{
"productId": 397,
"categorySets": [
{
"isMainCategorySet": true,
"category": {
"id": 20742,
"translations": [
{ "locale": "de_CH", "name": "Fanwelt", "urlHandle": "fanwelt" }
]
},
"subcategory": {
"id": 20762,
"translations": [
{ "locale": "de_CH", "name": "Accessoires", "urlHandle": "accessoires" }
]
},
"subSubcategory": {
"id": 20877,
"translations": [
{ "locale": "de_CH", "name": "Pins", "urlHandle": "pins" }
]
}
}
]
}
]
}
Save Category Sets for Product¶
Endpoint: POST /api/v1/products/{id}/category-sets
Assign category sets to a product.
Request Body¶
{
"data": [
{
"categoryId": 20742,
"subcategoryId": 20762,
"subSubcategoryId": 20877,
"isMainCategorySet": true
}
]
}
Example Request¶
curl --globoff -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/397/category-sets" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"data": [
{
"categoryId": 20742,
"subcategoryId": 20762,
"subSubcategoryId": 20877,
"isMainCategorySet": true
}
]
}'
Product Nutritional Values¶
Manage nutritional values for products (e.g., for food products).
Get Nutritional Values¶
Endpoint: GET /api/v1/products/{sku}/nutritional-values
Get nutritional values for a product by SKU.
Example Request¶
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products/85/nutritional-values" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Create Nutritional Value¶
Endpoint: POST /api/v1/products/{sku}/nutritional-values
Create a nutritional value for a product.
Request Body¶
{
"data": {
"value": "100",
"unit": "g",
"translations": [
{ "locale": "de_CH", "text": "Energie / Brennwert" },
{ "locale": "en_US", "text": "Energy" }
]
}
}
Example Request¶
curl --globoff -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/85/nutritional-values" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"data": {
"value": "100",
"unit": "kcal",
"translations": [
{ "locale": "de_CH", "text": "Kalorien" }
]
}
}'
Update Nutritional Value¶
Endpoint: PATCH /api/v1/products/{nutritionalValueId}/nutritional-values
Update a nutritional value by its ID.
Request Body¶
{
"data": {
"value": "150",
"unit": "kcal",
"translations": [
{ "locale": "de_CH", "text": "Kalorien (aktualisiert)" }
]
}
}
Delete Nutritional Value¶
Endpoint: DELETE /api/v1/products/{nutritionalValueId}/nutritional-values
Delete a nutritional value by its ID.
curl --globoff -X DELETE "https://app.aico.swiss/{workspaceId}/api/v1/products/123/nutritional-values" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Product Scheduled Prices¶
Manage time-based scheduled prices for products and variants. Scheduled prices automatically activate during their defined time window.
Create Scheduled Prices¶
Endpoint: POST /api/v1/products/scheduled-prices
Create scheduled prices for products or variants with country-specific pricing and VAT handling.
Request Body¶
{
"data": {
"products": [
{
"sku": "F25026",
"isSinglePriceForVariants": true,
"prices": [
{
"currency": "CHF",
"value": 69.9,
"discountPrice": 1,
"activeFrom": "2025-07-23",
"activeUntil": "2038-01-19",
"countryCode": "CH",
"isVatIncluded": true
}
]
}
]
}
}
Product Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
sku |
string | Yes | Product SKU |
isSinglePriceForVariants |
boolean | No | If true, applies this price to all variants of the product |
prices |
array | Yes | Array of price entries for the product |
Price Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
currency |
string | Yes | Currency code (e.g., CHF, EUR, USD) |
value |
float | Yes | Scheduled selling price |
discountPrice |
float | No | Scheduled discount price |
buyingPrice |
float | No | Scheduled buying/cost price |
activeFrom |
datetime | Yes | Start date/time of price validity (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS) |
activeUntil |
datetime | Yes | End date/time of price validity (YYYY-MM-DD or YYYY-MM-DD HH:MM:SS) |
countryCode |
string | No | ISO country code for country-specific pricing (e.g., CH, DE) |
isVatIncluded |
boolean | No | Whether the value includes VAT (default: false) |
Example Requests¶
Single product with one currency (date only):
curl --globoff -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/scheduled-prices" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"data": {
"products": [
{
"sku": "F25026",
"isSinglePriceForVariants": true,
"prices": [
{
"currency": "CHF",
"value": 69.9,
"discountPrice": 59.9,
"activeFrom": "2025-07-23",
"activeUntil": "2038-01-19",
"countryCode": "CH",
"isVatIncluded": true
}
]
}
]
}
}'
Single product with specific time range:
curl --globoff -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/scheduled-prices" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"data": {
"products": [
{
"sku": "85",
"prices": [
{
"currency": "CHF",
"value": 49.90,
"activeFrom": "2026-01-16 08:00:00",
"activeUntil": "2026-01-16 23:59:59"
}
]
}
]
}
}'
Multiple products with multiple currencies:
curl --globoff -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/scheduled-prices" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"data": {
"products": [
{
"sku": "PROD-001",
"isSinglePriceForVariants": false,
"prices": [
{
"currency": "CHF",
"value": 99.90,
"activeFrom": "2025-01-01",
"activeUntil": "2025-12-31",
"countryCode": "CH",
"isVatIncluded": true
},
{
"currency": "EUR",
"value": 89.90,
"activeFrom": "2025-01-01",
"activeUntil": "2025-12-31",
"countryCode": "DE",
"isVatIncluded": true
}
]
},
{
"sku": "PROD-002",
"prices": [
{
"currency": "CHF",
"value": 49.90,
"discountPrice": 39.90,
"activeFrom": "2025-06-01",
"activeUntil": "2025-06-30"
}
]
}
]
}
}'
Response¶
Success (200 OK):
{
"message": "Scheduled prices created successfully",
"data": {
"created": 3,
"skipped": 0,
"errors": []
}
}
Partial Success (200 OK with errors):
{
"message": "Scheduled prices created with some errors",
"data": {
"created": 2,
"skipped": 1,
"errors": [
{
"sku": "INVALID-SKU",
"error": "Product not found"
}
]
}
}
Notes¶
- If
isSinglePriceForVariantsistrue, the scheduled price applies to the product and all its variants - When
countryCodeis provided, the price is specific to that country's tax configuration - When
isVatIncludedistrue, the system calculates the net price based on the product's tax class for the specified country - Multiple price entries for the same product allow different prices per currency/country combination
- Overlapping date ranges for the same product/currency combination will create multiple scheduled prices
Delete Scheduled Prices¶
Endpoint: DELETE /api/v1/products/scheduled-prices
Delete scheduled prices for products or variants.
Request Body¶
{
"data": {
"productPrices": [
{
"sku": "85",
"activeFrom": "2026-02-01T00:00:00Z",
"activeUntil": "2026-02-28T23:59:59Z"
}
],
"productVariantPrices": [
{
"sku": "VARIANT-001",
"activeFrom": "2026-02-01T00:00:00Z",
"activeUntil": "2026-02-28T23:59:59Z"
}
]
}
}
Example Request¶
curl --globoff -X DELETE "https://app.aico.swiss/{workspaceId}/api/v1/products/scheduled-prices" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"data": {
"productPrices": [
{
"sku": "85",
"activeFrom": "2026-02-01T00:00:00Z",
"activeUntil": "2026-02-28T23:59:59Z"
}
]
}
}'
Product Custom Fields¶
Custom fields allow storing additional data on products beyond the standard fields.
Get Custom Fields for Product¶
Endpoint: GET /api/v1/products/{id}/custom-fields
Get custom field values for a specific product.
Example Request¶
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products/397/custom-fields" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Example Response¶
[
{
"locale": "de_CH",
"name": "Spielername:",
"value": "Müller",
"default_value": null,
"type": "Text"
},
{
"locale": "de_CH",
"name": "Waschanleitung",
"value": "30° waschen",
"default_value": null,
"type": "Longtext"
}
]
Get Available Custom Fields¶
Endpoint: GET /api/v1/products/custom-fields
Get all available custom fields defined for products.
Example Request¶
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products/custom-fields" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Get Product with Custom Fields¶
Endpoint: GET /api/v1/products/{id}/with-custom-fields
Get a single product with all its custom fields included.
Example Request¶
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products/397/with-custom-fields" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
List Products with Custom Fields¶
Endpoint: GET /api/v1/products/with-custom-fields
Get paginated list of products with custom fields.
Query Parameters¶
| Parameter | Type | Description |
|---|---|---|
page[number] |
int | Page number |
page[size] |
int | Items per page |
Example Request¶
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/products/with-custom-fields?page[number]=1&page[size]=10" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Creating/Updating Products with Custom Fields¶
When creating or updating products via POST /api/v1/products, you can include custom fields in the request body.
Request Body (with custom fields)¶
{
"data": {
"sku": "NEW-PRODUCT-001",
"name": "New Product",
"customFields": [
{
"name": "Spielername:",
"type": "Text",
"value": "Example Value"
},
{
"name": "Waschanleitung",
"type": "Longtext",
"value": "30° waschen, nicht bleichen",
"translations": [
{ "locale": "de_CH", "value": "30° waschen" },
{ "locale": "en_US", "value": "Wash at 30°" }
]
}
]
}
}
Custom Field Types¶
| Type | Description |
|---|---|
Text |
Single-line text |
Longtext |
Multi-line text |
Number |
Numeric value |
Checkbox |
Boolean (true/false) |
Dropdown |
Selection from predefined options |
Product Shopify Sync¶
Endpoints for triggering Shopify synchronization for products.
Trigger Product Shopify Sync¶
Endpoint: POST /api/v1/products/{id}/shopify-sync
Triggers a Shopify sync for a single product across all connected Shopify shops. The sync job is queued asynchronously.
Request Body (Optional)¶
Parameters¶
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
force |
boolean | No | false | Force sync even if no changes detected |
Example Request¶
curl -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/123/shopify-sync" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"force": true}'
Response (200 OK)¶
Notes¶
- The sync job is queued asynchronously on the
shopify-sync-singlequeue - The product will be synced to all Shopify shops it is connected to
- Use
force: trueto re-sync even if no changes are detected
Trigger Bulk Shopify Sync¶
Endpoint: POST /api/v1/products/bulk-shopify-sync
Triggers a bulk Shopify sync for all products across all connected Shopify shops. This queues a sync job for each shop.
Request Body¶
None required.
Example Request¶
curl -X POST "https://app.aico.swiss/{workspaceId}/api/v1/products/bulk-shopify-sync" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Response (200 OK)¶
Notes¶
- The sync jobs are queued asynchronously on the
shopify-sync-bulkqueue - One job is dispatched per Shopify shop
- The
shopCountindicates how many shops will be synced
Tax Classes¶
Resource Type: tax-classes
Endpoint: GET /api/v1/tax-classes
List available tax classes. Only returns active tax classes. Filter by taxAreaId to get tax classes for a specific country/tax area. The response includes the current tax rate based on today's date.
Query Parameters¶
| Parameter | Type | Description |
|---|---|---|
page[number] |
int | Page number |
page[size] |
int | Items per page |
filter[taxAreaId] |
int | Filter by tax area ID |
filter[id] |
string | Filter by ID(s) |
Fields¶
| Field | Type | Description |
|---|---|---|
id |
int | Tax class ID |
name |
string | Tax class name |
taxCode |
string | Tax code |
taxNumber |
string | Tax number |
taxType |
string | Tax type (e.g., VAT_DUE_SALES_TAX) |
documentText |
string | Text for documents |
isDefault |
boolean | Is default tax class |
isForExport |
boolean | Is for export |
isActive |
boolean | Is active |
taxAreaId |
int | Tax area ID |
taxArea |
object | Tax area details (id, state, countryId, countryName) |
currentTaxRate |
float | Current applicable tax rate (%) |
currentTaxRateValidFrom |
datetime | Valid from date of current rate |
createdAt |
datetime | Creation date |
updatedAt |
datetime | Last update date |
Example Requests¶
# List all active tax classes
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/tax-classes" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# Filter by tax area (country)
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/tax-classes?filter[taxAreaId]=1" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# With pagination
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/tax-classes?page[size]=10" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Example Response¶
{
"data": [
{
"type": "tax-classes",
"id": "1",
"attributes": {
"name": "Umsatz 8.1 (NS)",
"taxCode": "UN81",
"taxNumber": "303",
"taxType": "VAT_DUE_SALES_TAX",
"documentText": "inkl. MwSt 8.1%",
"isDefault": true,
"isForExport": false,
"isActive": true,
"taxAreaId": 1,
"taxArea": {
"id": 1,
"state": null,
"countryId": 216,
"countryName": "Switzerland"
},
"currentTaxRate": 8.1,
"currentTaxRateValidFrom": "2023-06-30 22:00:00",
"createdAt": "2023-01-06T11:52:30.000000Z",
"updatedAt": "2025-09-22T12:58:01.000000Z"
}
}
]
}
Product Tax Classes¶
Resource Type: product-tax-classes
Links products to tax classes for different tax areas.
Fields¶
| Field | Type | Description |
|---|---|---|
id |
int | Product tax class ID |
productId |
int | Product ID |
taxAreaId |
int | Tax area ID |
taxClassId |
int | Tax class ID |
taxClassName |
string | Tax class name |
taxCode |
string | Tax code |
taxAreaName |
string | Tax area name |
currentTaxRate |
float | Current applicable tax rate (%) |
createdAt |
datetime | Creation date |
updatedAt |
datetime | Last update date |
Example Response (included in product)¶
{
"data": {
"id": "123",
"type": "products",
"attributes": {
"sku": "PRD-001",
"name": "Example Product"
},
"relationships": {
"productTaxClasses": {
"data": [
{ "type": "product-tax-classes", "id": "1" },
{ "type": "product-tax-classes", "id": "2" }
]
}
}
},
"included": [
{
"id": "1",
"type": "product-tax-classes",
"attributes": {
"productId": 123,
"taxAreaId": 1,
"taxClassId": 5,
"taxClassName": "Standard Rate",
"taxCode": "VAT_STD",
"taxAreaName": "Switzerland",
"currentTaxRate": 8.1,
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
},
{
"id": "2",
"type": "product-tax-classes",
"attributes": {
"productId": 123,
"taxAreaId": 2,
"taxClassId": 8,
"taxClassName": "Reduced Rate",
"taxCode": "VAT_RED",
"taxAreaName": "Germany",
"currentTaxRate": 7.0,
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
}
]
}
Sellers¶
Resource Type: sellers
Endpoint: GET /api/v1/sellers
List all available sellers. Sellers can be associated with products.
Query Parameters¶
| Parameter | Type | Description |
|---|---|---|
page[number] |
int | Page number |
page[size] |
int | Items per page |
Fields¶
| Field | Type | Description |
|---|---|---|
id |
int | Seller ID |
name |
string | Seller name |
logo |
string | Logo image path |
website |
string | Website URL |
address |
object | Address details |
createdAt |
datetime | Creation date |
updatedAt |
datetime | Last update date |
Example Request¶
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/sellers" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Example Response (included in product)¶
{
"data": {
"id": "123",
"type": "products",
"attributes": {
"sku": "PRD-001",
"name": "Example Product"
},
"relationships": {
"sellers": {
"data": [
{ "type": "sellers", "id": "1" },
{ "type": "sellers", "id": "2" }
]
}
}
},
"included": [
{
"id": "1",
"type": "sellers",
"attributes": {
"name": "Main Seller",
"createdAt": "2023-06-01T08:00:00Z",
"updatedAt": "2024-01-10T14:30:00Z"
}
},
{
"id": "2",
"type": "sellers",
"attributes": {
"name": "Secondary Seller",
"createdAt": "2023-08-15T09:00:00Z",
"updatedAt": "2024-01-12T11:00:00Z"
}
}
]
}
B2B / Suppliers¶
Resource Type: b2bs
B2B companies including suppliers. Use the customerGroupId filter to find suppliers (customer group "Lieferanten").
List B2Bs (filter by customer group)¶
Endpoint: GET /api/v1/b2bs
List B2B companies. Filter by customerGroupId to get suppliers only.
Query Parameters¶
| Parameter | Type | Description |
|---|---|---|
page[number] |
int | Page number |
page[size] |
int | Items per page |
filter[customerGroupId] |
int | Filter by customer group ID (e.g., 2 for "Lieferanten"/Suppliers) |
Fields¶
| Field | Type | Description |
|---|---|---|
id |
int | B2B ID |
company |
string | Company name |
firstName |
string | Contact first name |
lastName |
string | Contact last name |
email |
string | Email address |
telephoneNumber |
string | Phone number |
address |
string | Street address |
addressSupplement |
string | Address supplement |
plz |
string | Postal code |
location |
string | City/location |
customerNumber |
int | Customer number |
customerReferenceNumber |
string | Customer reference number |
isSupplier |
boolean | Is supplier flag |
isActive |
boolean | Is active |
customerGroups |
array | Associated customer groups |
country |
object | Country details |
createdAt |
datetime | Creation date |
updatedAt |
datetime | Last update date |
Example Requests¶
# List all B2Bs
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/b2bs" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# Filter by customer group (Suppliers = customerGroupId 2)
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/b2bs?filter[customerGroupId]=2&page[size]=10" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Create B2B / Supplier¶
Endpoint: POST /api/v1/b2bs
Create a new B2B company (supplier).
Request Body¶
{
"data": {
"type": "b2bs",
"attributes": {
"company": "New Supplier GmbH",
"isSupplier": true,
"firstName": "John",
"lastName": "Doe",
"email": "contact@newsupplier.com",
"telephoneNumber": "+41 12 345 67 89",
"address": "Main Street",
"addressSupplement": "123",
"plz": "8000",
"location": "Zurich"
}
}
}
Required Fields¶
| Field | Type | Description |
|---|---|---|
isSupplier |
boolean | Required - set to true for suppliers |
Optional Fields¶
| Field | Type | Description |
|---|---|---|
company |
string | Company name |
firstName |
string | Contact first name |
lastName |
string | Contact last name |
email |
string | Email address |
telephoneNumber |
string | Phone number |
address |
string | Street address |
addressSupplement |
string | Address supplement (house number) |
plz |
string | Postal code |
location |
string | City/location |
Example Request¶
curl --globoff -X POST "https://app.aico.swiss/{workspaceId}/api/v1/b2bs" \
-H "Accept: application/vnd.api+json" \
-H "Content-Type: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{
"data": {
"type": "b2bs",
"attributes": {
"company": "New Supplier GmbH",
"isSupplier": true
}
}
}'
Example Response¶
{
"jsonapi": { "version": "1.0" },
"links": {
"self": "https://app.aico.swiss/{workspaceId}/api/v1/b2bs/11262"
},
"data": {
"type": "b2bs",
"id": "11262",
"attributes": {
"id": "11262",
"company": "New Supplier GmbH",
"customerNumber": 1246070,
"isSupplier": 0,
"isActive": 1,
"createdAt": "2026-01-06T13:25:46.000000Z",
"updatedAt": "2026-01-06T13:25:46.000000Z"
}
}
}
Example Response (included in product)¶
{
"data": {
"id": "397",
"type": "products",
"attributes": {
"sku": "85",
"name": "Logo-Pin"
},
"relationships": {
"suppliers": {
"data": [
{ "type": "b2bs", "id": "10141" }
]
}
}
},
"included": [
{
"id": "10141",
"type": "b2bs",
"attributes": {
"company": "Am Ball Com GmbH",
"firstName": "Frauke",
"lastName": "Niederhoff",
"address": "Oberfohringer Strasse",
"plz": "81925",
"location": "München",
"customerNumber": 1244949,
"isSupplier": false,
"createdAt": "2025-09-18T07:35:50.000000Z",
"updatedAt": "2025-09-22T11:54:41.000000Z"
}
}
]
}
Response Format¶
All V1 endpoints return JSON:API compliant responses:
{
"data": [
{
"id": "123",
"type": "products",
"attributes": {
"sku": "PRD-001",
"name": "Product Name",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
},
"relationships": {
"category": {
"data": { "type": "categories", "id": "5" }
},
"productTaxClasses": {
"data": [
{ "type": "product-tax-classes", "id": "1" }
]
},
"sellers": {
"data": [
{ "type": "sellers", "id": "1" }
]
}
}
}
],
"included": [...],
"meta": {
"page": {
"currentPage": 1,
"from": 1,
"lastPage": 10,
"perPage": 15,
"to": 15,
"total": 150
}
},
"links": {
"first": "http://example.com/api/v1/products?page[number]=1",
"last": "http://example.com/api/v1/products?page[number]=10",
"prev": null,
"next": "http://example.com/api/v1/products?page[number]=2"
}
}
Bulk Product Import¶
Resource Type: bulk-product-imports
Bulk import endpoint for creating or updating multiple products in a single request. Supports translations, options, variants, prices, stock, and images.
Endpoints¶
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/v1/products/bulk |
Submit a bulk import |
GET |
/api/v1/products/bulk |
List user's imports |
GET |
/api/v1/products/bulk/{id} |
Get import status |
GET |
/api/v1/products/bulk/{id}/errors |
Download error report |
Submit Bulk Import¶
Endpoint: POST /api/v1/products/bulk
Submit a JSON file containing multiple products. The file is streamed to disk and processed asynchronously via a queue.
Request¶
- Content-Type:
multipart/form-data - Body: File upload with field name
payload - Max size: 200 MB
- Supported formats:
.json,.json.gz(gzipped)
Payload Schema¶
{
"data": {
"type": "bulk-product-import",
"attributes": {
"products": [
{
"sku": "TSHIRT-001",
"barcode": "1234567890123",
"manufacturerSku": "MFG-001",
"hasSkuTracking": true,
"weightValue": 0.5,
"weightUnit": "KILOGRAMS",
"provenance": "CH",
"hsCode": "6109.10",
"translations": [
{
"locale": "de_CH",
"name": "T-Shirt Rot",
"webName": "Premium T-Shirt Rot",
"description": "Hochwertiges Baumwoll-T-Shirt",
"smallDescription": "Baumwoll T-Shirt"
},
{
"locale": "en_US",
"name": "Red T-Shirt",
"webName": "Premium Red T-Shirt",
"description": "High-quality cotton t-shirt"
}
],
"category": { "name": "Clothing" },
"subCategory": { "name": "T-Shirts" },
"brand": { "name": "MyBrand" },
"tags": [{ "name": "Summer" }, { "name": "Cotton" }],
"options": [
{
"name": "Size",
"isInVariants": true,
"values": [
{ "value": "S" },
{ "value": "M" },
{ "value": "L" }
]
},
{
"name": "Color",
"isInVariants": true,
"isColorOption": true,
"values": [
{ "value": "Red", "hexCode": "#FF0000" },
{ "value": "Blue", "hexCode": "#0000FF" }
]
}
],
"variants": [
{
"sku": "TSHIRT-001-S-RED",
"name": "T-Shirt Small Red",
"barcode": "1234567890124",
"options": [
{ "name": "Size", "value": "S" },
{ "name": "Color", "value": "Red" }
]
},
{
"sku": "TSHIRT-001-M-BLUE",
"name": "T-Shirt Medium Blue",
"options": [
{ "name": "Size", "value": "M" },
{ "name": "Color", "value": "Blue" }
]
}
],
"prices": [
{ "currencyId": 1, "value": 29.90, "buyingPrice": 15.00, "discountPrice": 24.90 },
{ "currencyId": 1, "variantSku": "TSHIRT-001-S-RED", "value": 29.90, "buyingPrice": 15.00 },
{ "currencyId": 1, "variantSku": "TSHIRT-001-M-BLUE", "value": 34.90, "buyingPrice": 18.00 }
],
"stock": [
{ "warehouseId": 1, "amount": 100 },
{ "warehouseId": 1, "variantSku": "TSHIRT-001-S-RED", "amount": 50 },
{ "warehouseId": 1, "variantSku": "TSHIRT-001-M-BLUE", "amount": 50 }
],
"images": [
{
"url": "https://example.com/images/tshirt-front.jpg",
"isMain": true,
"translations": [
{
"locale": "de_CH",
"fileUrl": "https://example.com/images/tshirt-front.jpg",
"name": "T-Shirt Vorderseite",
"altTitle": "T-Shirt Rot Vorderseite"
}
]
}
],
"sellerIds": [1, 2]
}
]
}
}
}
Product Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
sku |
string | Yes | Unique product SKU |
translations |
array | Yes | Product translations (at least one locale) |
barcode |
string | No | Product barcode |
manufacturerSku |
string | No | Manufacturer SKU |
hasSkuTracking |
boolean | No | Enable stock tracking (default: false) |
weightValue |
number | No | Weight value |
weightUnit |
string | No | Weight unit (GRAMS, KILOGRAMS, OUNCES, POUNDS) |
provenance |
string | No | Country of origin code |
hsCode |
string | No | HS tariff code |
category |
object | No | Category by name or ID |
subCategory |
object | No | Subcategory by name or ID |
brand |
object | No | Brand by name or ID |
tags |
array | No | Tags by name or ID |
options |
array | No | Variation options (e.g., Size, Color) |
variants |
array | No | Product variants |
prices |
array | No | Product/variant prices |
stock |
array | No | Initial stock amounts |
images |
array | No | Product images |
sellerIds |
array | No | Seller IDs to associate |
Response (202 Accepted)¶
{
"data": {
"id": 1,
"type": "bulk-product-imports",
"attributes": {
"status": "pending",
"progress": {
"total": 2,
"processed": 0,
"succeeded": 0,
"failed": 0
},
"createdAt": "2026-01-07T08:00:00+01:00"
}
},
"message": "Bulk import queued for processing."
}
Example Request¶
curl -X POST "http://127.0.0.1/api/v1/products/bulk" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "payload=@products.json"
List Imports¶
Endpoint: GET /api/v1/products/bulk
List all imports for the authenticated user.
Query Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
per_page |
int | 15 | Items per page |
Response¶
{
"data": [
{
"id": 1,
"type": "bulk-product-imports",
"attributes": {
"status": "completed",
"progress": {
"total": 100,
"processed": 100,
"succeeded": 98,
"failed": 2
},
"createdAt": "2026-01-07T08:00:00+01:00",
"updatedAt": "2026-01-07T08:05:00+01:00",
"startedAt": "2026-01-07T08:00:30+01:00",
"completedAt": "2026-01-07T08:05:00+01:00"
}
}
],
"meta": {
"currentPage": 1,
"lastPage": 1,
"perPage": 15,
"total": 1
}
}
Get Import Status¶
Endpoint: GET /api/v1/products/bulk/{id}
Get detailed status of a specific import, including inline errors (first 50).
Response¶
{
"data": {
"id": 1,
"type": "bulk-product-imports",
"attributes": {
"status": "completed",
"progress": {
"total": 100,
"processed": 100,
"succeeded": 98,
"failed": 2
},
"errors": [
{
"sku": "INVALID-SKU",
"index": 12,
"field": "variants[2].prices[0].currencyId",
"code": "INVALID_CURRENCY",
"message": "Currency with ID 999 not found",
"provided": 999,
"expected": "Valid currency ID (e.g., 1, 2, 3)"
}
],
"errorReportUrl": "http://example.com/api/v1/products/bulk/1/errors",
"createdAt": "2026-01-07T08:00:00+01:00",
"updatedAt": "2026-01-07T08:05:00+01:00",
"startedAt": "2026-01-07T08:00:30+01:00",
"completedAt": "2026-01-07T08:05:00+01:00"
}
}
}
Status Values¶
| Status | Description |
|---|---|
pending |
Import queued, waiting to be processed |
processing |
Import is currently being processed |
completed |
Import finished (may have some failures) |
failed |
Import completely failed (0 successes) |
Download Error Report¶
Endpoint: GET /api/v1/products/bulk/{id}/errors
Download a complete error report for offline analysis.
Query Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
format |
string | json | Response format (json or csv) |
Error Object Structure¶
| Field | Type | Description |
|---|---|---|
sku |
string | Product SKU that failed |
index |
int | Index in the products array |
field |
string | JSON path of the field that caused the error |
code |
string | Error code (VALIDATION_ERROR, DATABASE_ERROR, etc.) |
message |
string | Human-readable error message |
provided |
mixed | The value that was provided |
expected |
string | Description of expected value |
Example Requests¶
# JSON format
curl -X GET "http://127.0.0.1/api/v1/products/bulk/1/errors" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# CSV format
curl -X GET "http://127.0.0.1/api/v1/products/bulk/1/errors?format=csv" \
-H "Authorization: Bearer YOUR_TOKEN" \
-o errors.csv
Real-time Updates (WebSocket)¶
For real-time progress updates, listen to the private channel bulk-imports.{userId}.
Event: BulkProductImportUpdated¶
{
"importId": 1,
"status": "processing",
"progress": {
"total": 100,
"processed": 50,
"succeeded": 48,
"failed": 2
}
}
Laravel Echo Example¶
Echo.private(`bulk-imports.${userId}`)
.listen('BulkProductImportUpdated', (e) => {
console.log('Import progress:', e.progress);
});
User Notifications¶
Resource Type: user-notifications
Get paginated notifications for a user by email, with enriched task data including chat messages.
List User Notifications¶
Endpoint: GET /api/v1/user-notifications
Query Parameters¶
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
filter[email] |
string | Yes | - | User email to filter notifications by |
filter[unread] |
boolean | No | false | If true, only return unread notifications |
filter[type] |
string | No | IMPORTANT | Notification type: IMPORTANT, OTHER, CLEARED, SNOOZED |
page[number] |
int | No | 1 | Page number |
page[size] |
int | No | 15 | Items per page |
chatMessagesLimit |
int | No | 20 | Number of recent chat messages to include per task |
Notes: - Notifications are grouped by task - only the latest notification per task is returned - Notifications that have a triage entry are automatically excluded
Response Fields¶
| Field | Type | Description |
|---|---|---|
id |
uuid | Notification ID |
type |
string | Always "user-notifications" |
attributes.createdAt |
datetime | Notification creation date |
attributes.readAt |
datetime | When notification was read (null if unread) |
attributes.notificationType |
string | Type: IMPORTANT, OTHER, CLEARED, SNOOZED |
attributes.message |
object | Original notification message data |
attributes.task |
object | Task details (null if not a task notification) |
attributes.task.id |
int | Task ID |
attributes.task.title |
string | Task title |
attributes.task.description |
string | Task description |
attributes.task.dueDate |
date | Task due date |
attributes.task.deadline |
date | Task deadline |
attributes.task.fullUrl |
string | Full URL to the task |
attributes.task.mainAssignee |
object | Main assignee details |
attributes.task.mainAssignee.id |
int | Assignee user ID |
attributes.task.mainAssignee.email |
string | Assignee email |
attributes.task.mainAssignee.fullName |
string | Assignee full name |
attributes.task.mainAssignee.profilePhotoUrl |
string | Assignee profile photo URL |
attributes.task.chat |
array | Recent chat messages (limited by chatMessagesLimit) |
attributes.task.chat[].id |
int | Message ID |
attributes.task.chat[].text |
string | Message content |
attributes.task.chat[].author |
object | Message author details |
attributes.task.chat[].createdAt |
datetime | Message creation date |
Example Requests¶
# Get notifications for a user
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/user-notifications?filter[email]=user@example.com" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# With pagination
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/user-notifications?filter[email]=user@example.com&page[number]=1&page[size]=10" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# Limit chat messages
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/user-notifications?filter[email]=user@example.com&chatMessagesLimit=5" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
# Get only unread notifications
curl --globoff -X GET "https://app.aico.swiss/{workspaceId}/api/v1/user-notifications?filter[email]=user@example.com&filter[unread]=true" \
-H "Accept: application/vnd.api+json" \
-H "Authorization: Bearer YOUR_TOKEN"
Example Response¶
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"type": "user-notifications",
"attributes": {
"createdAt": "2026-01-09T10:00:00+01:00",
"readAt": null,
"notificationType": "IMPORTANT",
"message": {
"url": "https://app.aico.swiss/19839/tasks?t=abc123",
"message": {
"en": "New comment on your task",
"de": "Neuer Kommentar zu Ihrer Aufgabe"
},
"status": "info"
},
"task": {
"id": 123,
"title": "Review quarterly report",
"description": "Please review and approve the Q4 report",
"dueDate": "2026-01-15",
"deadline": "2026-01-20",
"fullUrl": "https://app.aico.swiss/19839/tasks?t=abc123",
"mainAssignee": {
"id": 1,
"email": "john.doe@example.com",
"fullName": "John Doe",
"profilePhotoUrl": "https://ui-avatars.com/api/?name=J+D"
},
"chat": [
{
"id": 456,
"text": "I've completed the first section",
"author": {
"id": 2,
"fullName": "Jane Smith",
"profilePhotoUrl": "https://ui-avatars.com/api/?name=J+S"
},
"createdAt": "2026-01-09T09:30:00"
}
]
}
}
}
],
"meta": {
"page": {
"currentPage": 1,
"lastPage": 5,
"perPage": 15,
"total": 75
}
}
}
Error Responses¶
422 Validation Error - Missing email filter:
{
"errors": [
{
"status": "422",
"title": "Validation Error",
"detail": "The filter[email] parameter is required."
}
]
}
404 Not Found - User not found:
{
"errors": [
{
"status": "404",
"title": "Not Found",
"detail": "User with the specified email not found."
}
]
}
Notes¶
- Authentication: All endpoints require a bearer token
- Content Type: Always include
Accept: application/vnd.api+jsonheader - Includes: Use comma-separated values for multiple includes (e.g.,
include=productTaxClasses,sellers,suppliers,productPrices)