MENU navbar-image

Introduction

InCheck API for Solution Providers

External API for Approved Solution Providers (Level 1) to integrate with the ZDHC Sandbox platform for chemical inventory reporting.

ID Format

ZDHC Sandbox uses a structured ID format: {prefix}-XXXXXXX-Z

Prefix Entity Type Example
01 Organisation 01-XXXXXXX-Z
20 Product 20-XXXXXXX-Z
40 InCheck Report 40-XXXXXXX-Z

Error Model

All non-2xx responses use a consistent error structure:

{
    "error": {
        "code": "string",
        "message": "string",
        "details": {}
    }
}

Authenticating requests

To authenticate requests, include an Authorization header with the value "Bearer {YOUR_AUTH_KEY}".

All authenticated endpoints are marked with a requires authentication badge in the documentation below.

Retrieve a token by calling the /auth/login endpoint.

Chemical

Inventory

Bulk Store

requires authentication

Store a new chemical inventory bulk

Example request:
curl --request POST \
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/bulk/store" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"inventories\": [
        {
            \"year\": 11,
            \"month\": 11,
            \"submit\": false,
            \"products\": [
                {
                    \"chemical_product_id\": 3,
                    \"formulator_name\": \"dad\",
                    \"name\": \"quo\",
                    \"weight\": 60
                }
            ]
        }
    ]
}"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/bulk/store"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "inventories": [
        {
            "year": 11,
            "month": 11,
            "submit": false,
            "products": [
                {
                    "chemical_product_id": 3,
                    "formulator_name": "dad",
                    "name": "quo",
                    "weight": 60
                }
            ]
        }
    ]
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/organisation/{organisation_reference_id}/chemical/inventory/bulk/store

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_reference_id   integer     

The ID of the organisation reference. Example: 1

Body Parameters

inventories   object[]     
year   integer     

Must be at least 2000. Must not be greater than 2100. Example: 11

month   integer     

Must be at least 1. Must not be greater than 12. Example: 11

submit   boolean  optional    

Example: false

products   object[]  optional    
chemical_product_id   integer  optional    

This field is required when name is not present. The id of an existing record in the chemical_products table. Example: 3

formulator_name   string     

Must not be greater than 255 characters. Example: dad

name   string  optional    

This field is required when chemical_product_id is not present. Example: quo

weight   number     

Must be at least 0. Example: 60

Update

requires authentication

Update an existing chemical inventory

Example request:
curl --request PUT \
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"year\": 6,
    \"month\": 7,
    \"submit\": true
}"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "year": 6,
    "month": 7,
    "submit": true
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

PUT api/organisation/{organisation_reference_id}/chemical/inventory/{id}

PATCH api/organisation/{organisation_reference_id}/chemical/inventory/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_reference_id   integer     

The ID of the organisation reference. Example: 1

id   integer     

The ID of the inventory. Example: 1

Body Parameters

year   integer     

Must be at least 2000. Must not be greater than 2100. Example: 6

month   integer     

Must be at least 1. Must not be greater than 12. Example: 7

submit   boolean  optional    

Example: true

Decline

requires authentication

Decline a chemical inventory

Example request:
curl --request POST \
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/1/decline" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"reason\": \"Duplicate submission\",
    \"additional_info\": \"sequi\"
}"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/1/decline"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "reason": "Duplicate submission",
    "additional_info": "sequi"
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/organisation/{organisation_reference_id}/chemical/inventory/{inventory_id}/decline

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_reference_id   integer     

The ID of the organisation reference. Example: 1

inventory_id   integer     

The ID of the inventory. Example: 1

Body Parameters

reason   string     

Example: Duplicate submission

Must be one of:
  • Data inaccuracy detected
  • Incomplete product information
  • Non-compliance with MRSL requirements
  • Missing supporting documentation
  • Duplicate submission
  • Out of reporting period scope
  • Other (please specify below)
additional_info   string  optional    

Example: sequi

Publish

requires authentication

Publish a chemical inventory. Only one report can be published per month. Higher-level reports can upgrade (replace) lower-level published reports.

Example request:
curl --request POST \
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/1/publish" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/1/publish"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "POST",
    headers,
}).then(response => response.json());

Request      

POST api/organisation/{organisation_reference_id}/chemical/inventory/{inventory_id}/publish

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_reference_id   integer     

The ID of the organisation reference. Example: 1

inventory_id   integer     

The ID of the inventory. Example: 1

Inventory Product

Index

requires authentication

List all products of a given inventory

Example request:
curl --request GET \
    --get "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/dolorem/product?per_page=3&search=quis&page=1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/dolorem/product"
);

const params = {
    "per_page": "3",
    "search": "quis",
    "page": "1",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (401):

Show headers
access-control-expose-headers: WWW-Authenticate
www-authenticate: Bearer realm="Token not found"
cache-control: no-cache, private
content-type: application/json
vary: Precognition, Origin
 

{
    "message": "Token not found"
}
 

Request      

GET api/organisation/{organisation_reference_id}/chemical/inventory/{supplier_inventory_id}/product

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_reference_id   integer     

The ID of the organisation reference. Example: 1

supplier_inventory_id   string     

The ID of the supplier inventory. Example: dolorem

Query Parameters

per_page   integer  optional    

Number of items to show per page. Defaults to 50 Example: 3

search   string  optional    

Search in all of these columns: name Example: quis

page   integer  optional    

the page number to show. Example: 1

Store

requires authentication

Store a custom product

Example request:
curl --request POST \
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/aperiam/product" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"chemical_product_id\": 19,
    \"formulator_name\": \"mhmomk\",
    \"name\": \"quo\",
    \"weight\": 70
}"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/aperiam/product"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "chemical_product_id": 19,
    "formulator_name": "mhmomk",
    "name": "quo",
    "weight": 70
};

fetch(url, {
    method: "POST",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

POST api/organisation/{organisation_reference_id}/chemical/inventory/{supplier_inventory_id}/product

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_reference_id   integer     

The ID of the organisation reference. Example: 1

supplier_inventory_id   string     

The ID of the supplier inventory. Example: aperiam

Body Parameters

chemical_product_id   integer  optional    

This field is required when name is not present. The id of an existing record in the chemical_products table. Example: 19

formulator_name   string     

Must not be greater than 255 characters. Example: mhmomk

name   string  optional    

This field is required when chemical_product_id is not present. Example: quo

weight   number     

Must be at least 0. Example: 70

Update

requires authentication

Update a custom product

Example request:
curl --request PUT \
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/autem/product/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json" \
    --data "{
    \"chemical_product_id\": 9,
    \"formulator_name\": \"fiq\",
    \"name\": \"voluptas\",
    \"weight\": 49
}"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/autem/product/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};

let body = {
    "chemical_product_id": 9,
    "formulator_name": "fiq",
    "name": "voluptas",
    "weight": 49
};

fetch(url, {
    method: "PUT",
    headers,
    body: JSON.stringify(body),
}).then(response => response.json());

Request      

PUT api/organisation/{organisation_reference_id}/chemical/inventory/{supplier_inventory_id}/product/{id}

PATCH api/organisation/{organisation_reference_id}/chemical/inventory/{supplier_inventory_id}/product/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_reference_id   integer     

The ID of the organisation reference. Example: 1

supplier_inventory_id   string     

The ID of the supplier inventory. Example: autem

id   integer     

The ID of the product. Example: 1

Body Parameters

chemical_product_id   integer  optional    

This field is required when name is not present. The id of an existing record in the chemical_products table. Example: 9

formulator_name   string     

Must not be greater than 255 characters. Example: fiq

name   string  optional    

This field is required when chemical_product_id is not present. Example: voluptas

weight   number     

Must be at least 0. Example: 49

Destroy

requires authentication

Destroy a custom product

Example request:
curl --request DELETE \
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/cumque/product/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/inventory/cumque/product/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "DELETE",
    headers,
}).then(response => response.json());

Request      

DELETE api/organisation/{organisation_reference_id}/chemical/inventory/{supplier_inventory_id}/product/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_reference_id   integer     

The ID of the organisation reference. Example: 1

supplier_inventory_id   string     

The ID of the supplier inventory. Example: cumque

id   integer     

The ID of the product. Example: 1

Product

Index

requires authentication

Get Products

Example request:
curl --request GET \
    --get "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/product?per_page=9&page=1&filter%5Bconformance_level_id%5D=2&filter%5Bctz_level_id%5D=5&search=corporis&sort=chemical_products.id%2Cchemical_products.name%2Cchemical_products.version%2Cchemical_products.status%2Cchemical_products.zdhc_pid%2Cconformance_level_name%2Cctz_level_name%2Cchemical_products.created_at%2Cchemical_products.updated_at&column=chemical_products.id" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/product"
);

const params = {
    "per_page": "9",
    "page": "1",
    "filter[conformance_level_id]": "2",
    "filter[ctz_level_id]": "5",
    "search": "corporis",
    "sort": "chemical_products.id,chemical_products.name,chemical_products.version,chemical_products.status,chemical_products.zdhc_pid,conformance_level_name,ctz_level_name,chemical_products.created_at,chemical_products.updated_at",
    "column": "chemical_products.id",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": [
        {
            "id": 1,
            "reference_id": "20-NTNRYDE6A32E-I",
            "organisation_id": 5,
            "zdhc_pid": null,
            "name": "sed",
            "version": 1,
            "description": null,
            "alternate_names": null,
            "created_at": "2025-11-14T09:43:25.000000Z",
            "updated_at": "2026-03-05T14:31:28.000000Z",
            "conformance_level_id": null,
            "ctz_level_id": null,
            "status": "DRAFT",
            "technical_data_sheet_url": "",
            "conformance_level": null,
            "ctz_level": null
        },
        {
            "id": 1,
            "reference_id": "20-NTNRYDE6A32E-I",
            "organisation_id": 5,
            "zdhc_pid": null,
            "name": "sed",
            "version": 1,
            "description": null,
            "alternate_names": null,
            "created_at": "2025-11-14T09:43:25.000000Z",
            "updated_at": "2026-03-05T14:31:28.000000Z",
            "conformance_level_id": null,
            "ctz_level_id": null,
            "status": "DRAFT",
            "technical_data_sheet_url": "",
            "conformance_level": null,
            "ctz_level": null
        }
    ]
}
 

Request      

GET api/organisation/{organisation_id}/chemical/product

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_id   integer     

The ID of the organisation. Example: 1

Query Parameters

per_page   integer  optional    

Number of items to show per page. Defaults to 100 Example: 9

page   integer  optional    

the page number to show. Example: 1

filter[chemical_products.name]   string  optional    

Filter column chemical_products.name by any accepted value. Filter by name Example: tenetur

filter[chemical_products.zdhc_pid]   integer  optional    

Filter column chemical_products.zdhc_pid by any accepted value. Filter by ZDHC PID Example: 3

filter[chemical_products.status]   string  optional    

Filter column chemical_products.status by any accepted value. Filter by status Example: beatae

filter[conformance_level_id]   integer  optional    

Filter column conformance_level_id by any accepted value. Filter by conformance level IDs Example: 2

filter[ctz_level_id]   integer  optional    

Filter column ctz_level_id by any accepted value. Filter by CTZ level IDs Example: 5

filter[chemical_products.created_at]   datetime  optional    

Filter column chemical_products.created_at by any accepted value. Filter by created date Example: temporibus

filter[chemical_products.updated_at]   datetime  optional    

Filter column chemical_products.updated_at by any accepted value. Filter by updated date Example: rerum

filter[product_use_types.id]   integer  optional    

Filter column product_use_types.id by any accepted value. Filter by use type ID (multiple selection allowed) Example: 14

filter[product_categories.id]   integer  optional    

Filter column product_categories.id by any accepted value. Filter by use type category ID (multiple selection allowed) Example: 2

search   string  optional    

Search in all of these columns: chemical_products.name, chemical_products.alternate_names, chemical_products.zdhc_pid Example: corporis

sort   string  optional    

sort by any accepted column: chemical_products.id,chemical_products.name,chemical_products.version,chemical_products.status,chemical_products.zdhc_pid,conformance_level_name,ctz_level_name,chemical_products.created_at,chemical_products.updated_at. prefix a "-" before the column name to sort in descending order Example: chemical_products.id,chemical_products.name,chemical_products.version,chemical_products.status,chemical_products.zdhc_pid,conformance_level_name,ctz_level_name,chemical_products.created_at,chemical_products.updated_at

column   string  optional    

get a distinct list of filterable values for any of the columns: chemical_products.id, chemical_products.name, chemical_products.version, chemical_products.status, ctz_level_name, conformance_level_name, chemical_products.created_at, chemical_products.updated_at. Example: chemical_products.id

Show

requires authentication

Show a product

Example request:
curl --request GET \
    --get "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/product/1" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/chemical/product/1"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": {
        "id": 1,
        "reference_id": "20-NTNRYDE6A32E-I",
        "organisation_id": 5,
        "zdhc_pid": null,
        "name": "sed",
        "version": 1,
        "description": null,
        "alternate_names": null,
        "created_at": "2025-11-14T09:43:25.000000Z",
        "updated_at": "2026-03-05T14:31:28.000000Z",
        "conformance_level_id": null,
        "ctz_level_id": null,
        "status": "DRAFT",
        "technical_data_sheet_url": "",
        "organisation": {
            "id": 5,
            "reference_id": "01-9YKA6G6TQSUTU-T",
            "type_id": 6,
            "name": "test-Chemical formulator System",
            "address_1": "85608 Bridie Highway",
            "address_2": "Apt. 403",
            "city": "Port Eloisa",
            "state": "Louisiana",
            "location": "SY",
            "zip": "69515",
            "phone": "+13345405228",
            "email": "goyette.diamond@schulist.com",
            "website": "http://www.torp.com/",
            "avatar_url": null,
            "location_name": "Syria"
        },
        "conformance_level": null,
        "ctz_level": null,
        "highest_mrsl_certification": null,
        "highest_ctz_certification": null,
        "certification_body_assignments": [],
        "safety_data_sheets": [],
        "certified_safety_data_sheets": [],
        "use_types": [],
        "activity_logs": []
    }
}
 

Request      

GET api/organisation/{organisation_id}/chemical/product/{id}

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_id   integer     

The ID of the organisation. Example: 1

id   integer     

The ID of the product. Example: 1

InCheck

Inventory

Eligable Suppliers

requires authentication

Show all eligable suppliers for a given Solution Provider

Example request:
curl --request GET \
    --get "https://staging-api.vm400.consulting1x1.info/api/inventory/eligable-suppliers?page=1&per_page=9" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/inventory/eligable-suppliers"
);

const params = {
    "page": "1",
    "per_page": "9",
};
Object.keys(params)
    .forEach(key => url.searchParams.append(key, params[key]));

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


{
    "data": {
        "id": 1,
        "reference_id": "01-CR698383XMWJ2-P",
        "name": "test-Supplier System"
    }
}
 

Request      

GET api/inventory/eligable-suppliers

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

Query Parameters

page   integer  optional    

the page number to show. Example: 1

per_page   integer  optional    

Number of items to show per page. Defaults to 50 Example: 9

Verified InCheck Report PDF

Show

requires authentication

Show the verified incheck report as a pdf

Example request:
curl --request GET \
    --get "https://staging-api.vm400.consulting1x1.info/api/organisation/1/incheck/reports/eos/verified-incheck-report-pdf" \
    --header "Authorization: Bearer {YOUR_AUTH_KEY}" \
    --header "Content-Type: application/json" \
    --header "Accept: application/json"
const url = new URL(
    "https://staging-api.vm400.consulting1x1.info/api/organisation/1/incheck/reports/eos/verified-incheck-report-pdf"
);

const headers = {
    "Authorization": "Bearer {YOUR_AUTH_KEY}",
    "Content-Type": "application/json",
    "Accept": "application/json",
};


fetch(url, {
    method: "GET",
    headers,
}).then(response => response.json());

Example response (200):


content of the pdf
 

Request      

GET api/organisation/{organisation_reference_id}/incheck/reports/{report_reference_id}/verified-incheck-report-pdf

Headers

Authorization        

Example: Bearer {YOUR_AUTH_KEY}

Content-Type        

Example: application/json

Accept        

Example: application/json

URL Parameters

organisation_reference_id   integer     

The ID of the organisation reference. Example: 1

report_reference_id   string     

The ID of the report reference. Example: eos