This notebook contains key functionalities of the CRIPT API V1
To facilitate the execution and comprehension of the following code, we will use a global project uuid variable.
The uuid is a unique identifier of a node within CRIPT. It applies to projects, materials, citations, properties, etc.
PROJECT_UUID = "" # Insert your project uuid here. You can get it by opening the project on the browser and copying the CRIPT ID
Getting Started¶
To get started with the CRIPT API in Python, you will need to import the library below
import requests # For interacting with the API
To send request through the API, you will need to get the bearer_token and storage_key from the CRIPT website. Click on your profile picture and hit Security Settings. This will take you to a page where you can copy your API Token (beared_token) and Storage Token (storage_key).
Then, add these values to the headers variable.
Keep in mind that these tokens expire, so make sure to update these variables every once in a while.
# Base URL
base_url = "https://api.criptapp.org/api/v1"
# Keys
bearer_token = "" # You API Token goes here
storage_key = "" # Your Storage Token goes here
# Headers
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {bearer_token}",
"X-Storage-Key": storage_key
}
Now you are ready to start using the API! The sections below contain examples of actions that can be done with it. They will mention the following node types:
Project:represents a group of experiments and collections that embody the works of a research group.Material:represents the identifiers and properties of a chemical, mixture, or substance.Property:represents qualities or traits of a material or process node.Condition:represents environmental variables, equipment settings, states of the system, or influencing factors.Reference:contains metadata for a literature publication, book, or anything external to CRIPT.Citation:provides links to papers, books, or other scholarly work and allows users to specify in what way the work relates to the data.
All node types are passed to the API through JSON files. For example, a project node is represented as:
And nodes can be nested within other nodes, such as:
Project nodes¶
Creating project nodes¶
To create a project, execute the POST request below, passing the project name. Keep in mind that project names are unique, so if you try to create a project with an existing name it will fail.
Be careful: ff you execute the cell below the code will create a project that can be accessed in My CRIPT
# Project name
node_name = "API Test Project - 2" # Add your project name here
# Project end point
url = f"{base_url}/project"
# Define JSON that will be passed to the API with node type and name
data_json = {
"node": ["Project"],
"name": node_name,
}
# Make request
response = requests.post(url, json=data_json, headers=headers)
# See the result
if response.status_code == 200:
# Get the data
data = response.json()
# Project uuid
uuid = data["data"]["result"][0]["uuid"]
print(f"Project `{node_name}` successfully created. UUID: {uuid}")
else:
print(f"Could not create project {node_name}")
Project `API Test Project - 2` successfully created. UUID: c7909738-d41d-419e-baff-4efbffa6f20e
Searching for project nodes by name¶
When you create a project, it is important to save the project uuid in order to easily interact with it later. You can manually see the uuid through the user interface (CRIPT website) upon opening you project. It will be below the project name and referred as CRIPT ID.
If you’d like to search a project by name, just run the cell below.
# Project name
node_name = "API Test Project" # Add your project name here
# Project end point
url = f"{base_url}/search/project?q={node_name}"
# Execute GET request
response = requests.get(url, headers=headers)
# See the result
if response.status_code == 200:
# Get the data
data = response.json()
# If there is not any project in the response, print nothing
if data["data"]["count"] == 0:
print("Project not found")
# If there is a project, print it
else:
uuid = data["data"]["result"][0]["uuid"]
print(f"Project found. UUID: {uuid}")
else:
print("Project not found")
Project found. UUID: 256b6550-087d-4d64-bfc7-19d322430564
Material nodes¶
Create a material node¶
You may only create materials directly into an existing project. For this reason, you need to pass the material name and the project uuid to a PATCH request. Hence, you will update the project with a new material.
Material names are unique across the entire database, so the code below will fail if you use an existing material name.
# Project uuid
project_uuid = PROJECT_UUID # Add project uuid here
# Material name
material_name = "Test - Material - 2" # Add your material name here
# Define the endpoint for updating a specific project (with its uuid)
url = f"{base_url}/project/{project_uuid}"
# Define JSON that specifies the name and type of the material node that will be created, as well as the project
data_json = {
"node": ["Project"], # This says that we will update a project node
"material": [ # This says we are adding a new material to this project
{ # Every element of this list is a new material. We could add multiple materials at the same time by adding elements to this list
"node": ["Material"], # This says that this element is a material node
"name": material_name, # This indicates the name of the new material node
"bigsmiles": "{[][$]CC[$][]}" # This is the BigSMILES of the material. For SMILES, add the parameter "smiles"
}
]
}
# Make request
response = requests.patch(url, json=data_json, headers=headers)
# See results
if response.status_code == 200:
# Get the data
data = response.json()
# New material uuid
material_uuid = data["data"]["result"][0]["uuid"]
print(f"Successfully created material node {material_name}! UUID: {material_uuid}")
else:
print(f"Could not create material node {material_name}")
Successfully created material node Test - Material - 2! UUID: 778f419d-3120-41e6-b0ae-fd46d2b51ae2
You can use the material uuidto add properties to the material later on. Keep in mind that material names are unique, so if you try to create a material with an existing name it will fail.
Creating a material node with properties¶
You can simultaneously create material nodes and pass their properties. In the example below, material 3 has a Tg of 300 K.
# Project uuid
project_uuid = PROJECT_UUID # Add project uuid here
# Material name
material_name = "Test - Material - 3" # Add your material name here
# Define the endpoint for updating a specific project (with its uuid)
url = f"{base_url}/project/{project_uuid}"
# Define JSON that specifies the name and properties of the material node that will be created, as well as the project
data_json = {
"node": ["Project"], # This says that we will update a project node
"material": [ # This says we are adding a new material to this project
{ # Every element of this list is a new material. We could add multiple materials at the same time by adding elements to this list
"node": ["Material"], # This says that this element is a material node
"name": material_name, # This indicates the name of the new material node
"property" : [ # This says we are including material properties
{
"node": ["Property"], # This says that this element is a property node
"key": "temp_glass", # This is the controlled vocabulary that refers to Tg
"type": "number", # This is the type of the value
"unit": "K", # This is the unit: Kelvin
"value": 300, # This is the value
}
]
}
]
}
# Make request
response = requests.patch(url, json=data_json, headers=headers)
# See results
if response.status_code == 200:
# Get the data
data = response.json()
# New material uuid
material_uuid = data["data"]["result"][0]["uuid"]
print(f"Successfully created material node {material_name}! UUID: {material_uuid}")
else:
print(f"Could not create material node {material_name}")
Successfully created material node Test - Material - 3! UUID: 6e51c5da-23a8-4ad7-bf47-54d6213b491a
Creating material nodes that represent mixtures¶
Mixtures of materials are represented as material nodes with multiple components. Pass the uuid of the components to components and, if you would like to specify concentrations or fractions, you can add them as properties
# Project uuid
project_uuid = PROJECT_UUID # Add project uuid here
# Material name
material_name = "Test - Material - 4 - Mixture" # Add your material name here
# uuids of the components
component1_uuid = "778f419d-3120-41e6-b0ae-fd46d2b51ae2" # Add the uuid of a component here
component2_uuid = "6e51c5da-23a8-4ad7-bf47-54d6213b491a" # Add the uuid of a component here
# Define the endpoint for updating a specific project (with its uuid)
url = f"{base_url}/project/{project_uuid}"
# Define JSON that specifies the name and properties of the material node that will be created, as well as the project
data_json = {
"node": ["Project"], # This says that we will update a project node
"material": [ # This says we are adding a new material to this project
{ # Every element of this list is a new material. We could add multiple materials at the same time by adding elements to this list
"node": ["Material"], # This says that this element is a material node
"name": material_name, # This indicates the name of the new material node
"component": [ # This says we are adding components to the material node
# These are the uuids of the components
{"uuid": component1_uuid},
{"uuid": component2_uuid}
],
"property" : [ # This says we are including material properties. In this example, mass fractions
{
"node": ["Property"], # This says that this element is a property node
"key": "conc_mass_fraction", # This is the controlled vocabulary that refers to mass fraction
"type": "number", # This is the type of the value
"unit": "", # This is the unit: None
"value": 0.6, # This is the mass fraction value
"component": [{"uuid": component1_uuid}] # This is the uuuid of the component
},
{
"node": ["Property"], # This says that this element is a property node
"key": "conc_mass_fraction", # This is the controlled vocabulary that refers to mass fraction
"type": "number", # This is the type of the value
"unit": "", # This is the unit: None
"value": 0.4, # This is the mass fraction value
"component": [{"uuid": component2_uuid}] # This is the uuuid of the component
},
]
}
]
}
# Make request
response = requests.patch(url, json=data_json, headers=headers)
# See results
if response.status_code == 200:
# Get the data
data = response.json()
# New material uuid
material_uuid = data["data"]["result"][0]["uuid"]
print(f"Successfully created material node {material_name}! UUID: {material_uuid}")
else:
print(f"Could not create material node {material_name}")
Successfully created material node Test - Material - 4 - Mixture! UUID: 878cacb0-9536-4cdd-9be7-7914587816ca
Creating properties with conditions and citations¶
When you are creating a material with properties, you can also add property conditions. For example, the temperature at which density was measured is a density condition.
# Project uuid
project_uuid = PROJECT_UUID # Add project uuid here
# Material name
material_name = "Test - Material - 6" # Add your material name here
# Define the endpoint for updating a specific project (with its uuid)
url = f"{base_url}/project/{project_uuid}"
# Define JSON that specifies the name and propeties of the material node that will be created, as well as the project
data_json = {
"node": ["Project"], # This says that we will update a project node
"material": [ # This says we are adding a new material to this project
{ # Every element of this list is a new material.
"node": ["Material"], # This says that this element is a material node
"name": material_name, # This indicates the name of the new material node
"property" : [ # This says we are including material properties
{
"node": ["Property"], # This says that this element is a property node
"key": "density", # This is the controlled vocabulary that refers to density
"type": "number", # This is the type of the value
"unit": "kg/m**3", # This is the unit of measurement
"value": 10, # This is the density value
"condition": [ # This is where conditions are listed for this density measurement
{
"node": ["Condition"], # This says that this element is a condition node
"key": "temperature", # This says we are setting the temperature
"type": "number", # This is the type of the value
"value": 100, # This is the temperature value
"unit": "degC" # This is the temperature unit of measurement
}
]
}
]
}
]
}
# Make request
response = requests.patch(url, json=data_json, headers=headers)
# See results
if response.status_code == 200:
# Get the data
data = response.json()
# New material uuid
material_uuid = data["data"]["result"][0]["uuid"]
print(f"Successfully created material node {material_name}! UUID: {material_uuid}")
else:
print(f"Could not create material node {material_name}")
Successfully created material node Test - Material - 6! UUID: 2fb33d46-f024-48db-85da-288764882d32
References can also be added by specifying citation within the property.
# Project uuid
project_uuid = PROJECT_UUID # Add project uuid here
# Material name
material_name = "Test - Material - 7" # Add your material name here
# Define the endpoint for updating a specific project (with its uuid)
url = f"{base_url}/project/{project_uuid}"
# Define JSON that specifies the name and properties of the material node that will be created, as well as the project
data_json = {
"node": ["Project"], # This says that we will update a project node
"material": [ # This says we are adding a new material to this project
{ # Every element of this list is a new material.
"node": ["Material"], # This says that this element is a material node
"name": material_name, # This indicates the name of the new material node
"property" : [ # This says we are including material properties
{
"node": ["Property"], # This says that this element is a property node
"key": "density", # This is the controlled vocabulary that refers to density
"type": "number", # This is the type of the value
"unit": "kg/m**3", # This is the unit of measurement
"value": 10, # This is the density value
"condition": [ # This is where conditions are listed for this density measurement
{
"node": ["Condition"], # This says that this element is a condition node
"key": "temperature", # This says we are setting the temperature
"type": "number", # This is the type of the value
"value": 100, # This is the temperature value
"unit": "degC" # This is the temperature unit of measurement
}
],
"citation": [ # This is where the citations are listed
{
"node": ["Citation"], # This indicates that this element is a citation node
"type": "extracted_by_human", # The type refers to how it was extracted. In this example, the data was extracted by a human
"reference": { # This is where the citation information is listed
"node": ["Reference"], # This indicates it is a reference node
# Indicates if it is a paper, thesis, book, etc
"type": "journal_article",
# DOI of the citation
"doi": "https://doi.org/10.1021/acscentsci.3c00011",
# Title of the citation
"title": "Community Resource for Innovation in Polymer Technology (CRIPT): A Scalable Polymer Material Data Structure",
}
}
]
}
]
}
]
}
# Make request
response = requests.patch(url, json=data_json, headers=headers)
# See results
if response.status_code == 200:
# Get the data
data = response.json()
# New material uuid
material_uuid = data["data"]["result"][0]["uuid"]
print(f"Successfully created material node {material_name}! UUID: {material_uuid}")
else:
print(f"Could not create material node {material_name}")
Successfully created material node Test - Material - 7! UUID: d91f3fe6-2acf-40de-b44e-593a86e43030
To summarize, the hierarchy is the one that follows:
Project
Material
Property
- Citation
- Condition
Adding properties to existing materials¶
You can add properties to existing materials by executing a PATCH request directly onto the material node. To do so, the material uuid is required.
Note that the response contains the uuid of the new property node.
# Material uuid
material_uuid = "d91f3fe6-2acf-40de-b44e-593a86e43030" # Add your material uuid here
# Define the endpoint for updating a specific material (with its uuid)
url = f"{base_url}/material/{material_uuid}"
# Define JSON that specifies the properties that will be added
data_json = {
"node": ["Material"], # This says that this element is a material node
"property" : [ # This says we are including new propertiy nodes
{
"node": ["Property"], # This says that this element is a property node
"key": "density", # This is the controlled vocabulary that refers to density
"type": "number", # This is the type of the value
"unit": "kg/m**3", # This is the unit of measurement
"value": 30, # This is the density value
}
]
}
# Make request
response = requests.patch(url, json=data_json, headers=headers)
# See results
if response.status_code == 200:
# Get the data
data = response.json()
# New property uuid
property_uuid = data["data"]["result"][0]["uuid"]
print(f"Successfully added property to material node! UUID: {property_uuid}")
else:
print(f"Could not add property to material node")
Successfully added property to material node! UUID: 78c7df95-6d8d-4b1f-b2d6-e87c60819b6d
Getting all properties from a material node¶
To get properties from a material node, it is required to execute a GET request passing the material uuid. The response is a list of property nodes containing their values, units, conditions, citations, etc.
# Material uuid
material_uuid = "d91f3fe6-2acf-40de-b44e-593a86e43030" # Add your material uuid here
# Define the endpoint for getting the properties of a specific material (with its uuid)
url = f"{base_url}/material/{material_uuid}/Property"
# Make request
response = requests.get(url, headers=headers)
# See results
if response.status_code == 200:
# Get the data
data = response.json()
# List of properties
properties = data["data"]["result"]
print(f"Successfully got {len(properties)} properties from material node! \n {properties}")
else:
print(f"Could not get properties from material node")
Successfully got 2 properties from material node!
[{'citation': [{'node': ['Citation'], 'reference': {'doi': 'https://doi.org/10.1021/acscentsci.3c00011', 'node': ['Reference'], 'title': 'Community Resource for Innovation in Polymer Technology (CRIPT): A Scalable Polymer Material Data Structure', 'type': 'journal_article'}, 'type': 'extracted_by_human', 'uuid': 'c6766019-cba6-411d-8e7e-7b20353c9b82'}], 'citation_count': 1, 'component_count': 0, 'computation_count': 0, 'condition': [{'data_count': 0, 'key': 'temperature', 'model_version': '1.0.1', 'node': ['Condition'], 'type': 'number', 'unit': 'degC', 'uuid': 'df85d5a6-981f-44d5-82ce-fbd18579b42c', 'value': '100'}], 'condition_count': 1, 'created_at': '2025-10-23T17:27:55.872848Z', 'data_count': 0, 'key': 'density', 'material': [{'name': 'Test - Material - 7', 'node': ['Material'], 'uuid': 'd91f3fe6-2acf-40de-b44e-593a86e43030'}], 'model_version': '1.0.1', 'node': ['Property'], 'process': [{'name': 'Test - Material - 7', 'node': ['Material'], 'uuid': 'd91f3fe6-2acf-40de-b44e-593a86e43030'}], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'kg/m**3', 'updated_at': '2025-10-23T17:27:55.872849Z', 'uuid': '6de9c4a7-b03a-4e8e-a358-374e46654ae6', 'value': '10'}, {'citation_count': 0, 'component_count': 0, 'computation_count': 0, 'condition_count': 0, 'created_at': '2025-10-23T18:53:19.080616Z', 'data_count': 0, 'key': 'density', 'material': [{'name': 'Test - Material - 7', 'node': ['Material'], 'uuid': 'd91f3fe6-2acf-40de-b44e-593a86e43030'}], 'model_version': '1.0.1', 'node': ['Property'], 'process': [{'name': 'Test - Material - 7', 'node': ['Material'], 'uuid': 'd91f3fe6-2acf-40de-b44e-593a86e43030'}], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'kg/m**3', 'updated_at': '2025-10-23T18:53:19.080625Z', 'uuid': '78c7df95-6d8d-4b1f-b2d6-e87c60819b6d', 'value': '30'}]
The current version of the API retrieves 10 nodes at a time. In order to get all properties from a material node, it is required to execute a GET request with page numbers.
# Material uuid
material_uuid = "d91f3fe6-2acf-40de-b44e-593a86e43030" # Add your material uuid here
# Initialize list of properties, page and temporary variable that takes the response of the request
all_properties = []
page = 0
request_properties = None
# Execute GET request untill there is no more data to be fetched
while request_properties != []:
# Define the endpoint for getting the properties of a specific material (with its uuid)
url = f"{base_url}/material/{material_uuid}/Property?page={page}"
# Make request
response = requests.get(url, headers=headers)
# See results
if response.status_code == 200:
# Get the data
data = response.json()
# List of properties
request_properties = data["data"]["result"]
# Add to list of properties
all_properties += request_properties
# Update page
page += 1
print(f"Successfully got {len(all_properties)} properties from material node! \n {all_properties}")
Successfully got 2 properties from material node!
[{'citation': [{'node': ['Citation'], 'reference': {'doi': 'https://doi.org/10.1021/acscentsci.3c00011', 'node': ['Reference'], 'title': 'Community Resource for Innovation in Polymer Technology (CRIPT): A Scalable Polymer Material Data Structure', 'type': 'journal_article'}, 'type': 'extracted_by_human', 'uuid': 'c6766019-cba6-411d-8e7e-7b20353c9b82'}], 'citation_count': 1, 'component_count': 0, 'computation_count': 0, 'condition': [{'data_count': 0, 'key': 'temperature', 'model_version': '1.0.1', 'node': ['Condition'], 'type': 'number', 'unit': 'degC', 'uuid': 'df85d5a6-981f-44d5-82ce-fbd18579b42c', 'value': '100'}], 'condition_count': 1, 'created_at': '2025-10-23T17:27:55.872848Z', 'data_count': 0, 'key': 'density', 'material': [{'name': 'Test - Material - 7', 'node': ['Material'], 'uuid': 'd91f3fe6-2acf-40de-b44e-593a86e43030'}], 'model_version': '1.0.1', 'node': ['Property'], 'process': [{'name': 'Test - Material - 7', 'node': ['Material'], 'uuid': 'd91f3fe6-2acf-40de-b44e-593a86e43030'}], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'kg/m**3', 'updated_at': '2025-10-23T17:27:55.872849Z', 'uuid': '6de9c4a7-b03a-4e8e-a358-374e46654ae6', 'value': '10'}, {'citation_count': 0, 'component_count': 0, 'computation_count': 0, 'condition_count': 0, 'created_at': '2025-10-23T18:53:19.080616Z', 'data_count': 0, 'key': 'density', 'material': [{'name': 'Test - Material - 7', 'node': ['Material'], 'uuid': 'd91f3fe6-2acf-40de-b44e-593a86e43030'}], 'model_version': '1.0.1', 'node': ['Property'], 'process': [{'name': 'Test - Material - 7', 'node': ['Material'], 'uuid': 'd91f3fe6-2acf-40de-b44e-593a86e43030'}], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'kg/m**3', 'updated_at': '2025-10-23T18:53:19.080625Z', 'uuid': '78c7df95-6d8d-4b1f-b2d6-e87c60819b6d', 'value': '30'}]
Getting all materials in a project node¶
Like in the case of getting properties from a material node, to get the materials of a project node it is required to make a GET request. If the project has more than 10 materials, it is required to add the page as a parameter
# Project uuid
project_uuid = "256b6550-087d-4d64-bfc7-19d322430564" # Add your project uuid here
# Define the endpoint for getting the materials of a specific project (with its uuid)
url = f"{base_url}/project/{project_uuid}/Material"
# Make request
response = requests.get(url, headers=headers)
# See results
if response.status_code == 200:
# Get the data
data = response.json()
# List of materials
materials = data["data"]["result"]
print(f"Successfully got {len(materials)} materials from project node! \n {materials}")
else:
print(f"Could not get materials from project node")
Successfully got 5 materials from project node!
[{'component_count': 0, 'computational_forcefield_count': 0, 'created_at': '2025-10-21T20:43:02.741093Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 2', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property_count': 0, 'public': False, 'updated_at': '2025-10-21T20:43:02.741102Z', 'uuid': '778f419d-3120-41e6-b0ae-fd46d2b51ae2'}, {'component_count': 0, 'computational_forcefield_count': 0, 'created_at': '2025-10-23T15:03:21.738563Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 3', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property': [{'citation_count': 0, 'component_count': 0, 'computation_count': 0, 'condition_count': 0, 'created_at': '2025-10-23T15:03:21.738516Z', 'data_count': 0, 'key': 'temp_glass', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'K', 'updated_at': '2025-10-23T15:03:21.738526Z', 'uuid': '179e4f9f-f10d-4d4b-9478-64b86461bac6', 'value': '300'}], 'property_count': 1, 'public': False, 'updated_at': '2025-10-23T15:03:21.738565Z', 'uuid': '6e51c5da-23a8-4ad7-bf47-54d6213b491a'}, {'component': [{'created_at': '2025-10-21T20:43:02.741093Z', 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 2', 'node': ['Material'], 'public': False, 'updated_at': '2025-10-21T20:43:02.741102Z', 'uuid': '778f419d-3120-41e6-b0ae-fd46d2b51ae2'}, {'created_at': '2025-10-23T15:03:21.738563Z', 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 3', 'node': ['Material'], 'public': False, 'updated_at': '2025-10-23T15:03:21.738565Z', 'uuid': '6e51c5da-23a8-4ad7-bf47-54d6213b491a'}], 'component_count': 2, 'computational_forcefield_count': 0, 'created_at': '2025-10-23T15:15:59.069496Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 4 - Mixture', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property': [{'citation_count': 0, 'component': [{'created_at': '2025-10-21T20:43:02.741093Z', 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 2', 'node': ['Material'], 'public': False, 'updated_at': '2025-10-21T20:43:02.741102Z', 'uuid': '778f419d-3120-41e6-b0ae-fd46d2b51ae2'}], 'component_count': 1, 'computation_count': 0, 'condition_count': 0, 'created_at': '2025-10-23T15:15:59.069434Z', 'data_count': 0, 'key': 'conc_mass_fraction', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': '', 'updated_at': '2025-10-23T15:15:59.069443Z', 'uuid': '878cacb0-9536-4cdd-9be7-7914587816ca', 'value': '0.6'}, {'citation_count': 0, 'component': [{'created_at': '2025-10-23T15:03:21.738563Z', 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 3', 'node': ['Material'], 'public': False, 'updated_at': '2025-10-23T15:03:21.738565Z', 'uuid': '6e51c5da-23a8-4ad7-bf47-54d6213b491a'}], 'component_count': 1, 'computation_count': 0, 'condition_count': 0, 'created_at': '2025-10-23T15:15:59.069463Z', 'data_count': 0, 'key': 'conc_mass_fraction', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': '', 'updated_at': '2025-10-23T15:15:59.069464Z', 'uuid': '43953773-e521-4536-bae3-7071cdfc6fa3', 'value': '0.4'}], 'property_count': 2, 'public': False, 'updated_at': '2025-10-23T15:15:59.069498Z', 'uuid': 'ad61e0df-4c8f-457a-bc64-98227e63c888'}, {'component_count': 0, 'computational_forcefield_count': 0, 'created_at': '2025-10-23T17:26:37.728812Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 6', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property': [{'citation_count': 0, 'component_count': 0, 'computation_count': 0, 'condition': [{'data_count': 0, 'key': 'temperature', 'model_version': '1.0.1', 'node': ['Condition'], 'type': 'number', 'unit': 'degC', 'uuid': '6c51689b-8f30-4a47-a04a-cdfe048db171', 'value': '100'}], 'condition_count': 1, 'created_at': '2025-10-23T17:26:37.728776Z', 'data_count': 0, 'key': 'density', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'kg/m**3', 'updated_at': '2025-10-23T17:26:37.728777Z', 'uuid': 'f15236c7-973d-49ae-a774-bf8280a7d0ab', 'value': '10'}], 'property_count': 1, 'public': False, 'updated_at': '2025-10-23T17:26:37.728813Z', 'uuid': '2fb33d46-f024-48db-85da-288764882d32'}, {'component_count': 0, 'computational_forcefield_count': 0, 'created_at': '2025-10-23T17:27:55.872878Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 7', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property': [{'citation': [{'node': ['Citation'], 'reference': {'doi': 'https://doi.org/10.1021/acscentsci.3c00011', 'node': ['Reference'], 'title': 'Community Resource for Innovation in Polymer Technology (CRIPT): A Scalable Polymer Material Data Structure', 'type': 'journal_article'}, 'type': 'extracted_by_human', 'uuid': 'c6766019-cba6-411d-8e7e-7b20353c9b82'}], 'citation_count': 1, 'component_count': 0, 'computation_count': 0, 'condition': [{'data_count': 0, 'key': 'temperature', 'model_version': '1.0.1', 'node': ['Condition'], 'type': 'number', 'unit': 'degC', 'uuid': 'df85d5a6-981f-44d5-82ce-fbd18579b42c', 'value': '100'}], 'condition_count': 1, 'created_at': '2025-10-23T17:27:55.872848Z', 'data_count': 0, 'key': 'density', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'kg/m**3', 'updated_at': '2025-10-23T17:27:55.872849Z', 'uuid': '6de9c4a7-b03a-4e8e-a358-374e46654ae6', 'value': '10'}, {'citation_count': 0, 'component_count': 0, 'computation_count': 0, 'condition_count': 0, 'created_at': '2025-10-23T18:53:19.080616Z', 'data_count': 0, 'key': 'density', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'kg/m**3', 'updated_at': '2025-10-23T18:53:19.080625Z', 'uuid': '78c7df95-6d8d-4b1f-b2d6-e87c60819b6d', 'value': '30'}], 'property_count': 2, 'public': False, 'updated_at': '2025-10-23T18:53:19.080635Z', 'uuid': 'd91f3fe6-2acf-40de-b44e-593a86e43030'}]
# Project uuid
project_uuid = "256b6550-087d-4d64-bfc7-19d322430564" # Add your project uuid here
# Initialize list of materials, page and temporary variable that takes the response of the request
all_materials = []
page = 0
request_materials = None
# Execute GET request untill there is no more data to be fetched
while request_materials != []:
# Define the endpoint for getting the materials of a specific project (with its uuid)
url = f"{base_url}/project/{project_uuid}/Material?page={page}"
# Make request
response = requests.get(url, headers=headers)
# See results
if response.status_code == 200:
# Get the data
data = response.json()
# List of materials
request_materials = data["data"]["result"]
# Add to list of materials
all_materials += request_materials
# Update page
page += 1
print(f"Successfully got {len(all_materials)} materials from project node! \n {all_materials}")
Successfully got 5 materials from project node!
[{'component_count': 0, 'computational_forcefield_count': 0, 'created_at': '2025-10-21T20:43:02.741093Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 2', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property_count': 0, 'public': False, 'updated_at': '2025-10-21T20:43:02.741102Z', 'uuid': '778f419d-3120-41e6-b0ae-fd46d2b51ae2'}, {'component_count': 0, 'computational_forcefield_count': 0, 'created_at': '2025-10-23T15:03:21.738563Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 3', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property': [{'citation_count': 0, 'component_count': 0, 'computation_count': 0, 'condition_count': 0, 'created_at': '2025-10-23T15:03:21.738516Z', 'data_count': 0, 'key': 'temp_glass', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'K', 'updated_at': '2025-10-23T15:03:21.738526Z', 'uuid': '179e4f9f-f10d-4d4b-9478-64b86461bac6', 'value': '300'}], 'property_count': 1, 'public': False, 'updated_at': '2025-10-23T15:03:21.738565Z', 'uuid': '6e51c5da-23a8-4ad7-bf47-54d6213b491a'}, {'component': [{'created_at': '2025-10-21T20:43:02.741093Z', 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 2', 'node': ['Material'], 'public': False, 'updated_at': '2025-10-21T20:43:02.741102Z', 'uuid': '778f419d-3120-41e6-b0ae-fd46d2b51ae2'}, {'created_at': '2025-10-23T15:03:21.738563Z', 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 3', 'node': ['Material'], 'public': False, 'updated_at': '2025-10-23T15:03:21.738565Z', 'uuid': '6e51c5da-23a8-4ad7-bf47-54d6213b491a'}], 'component_count': 2, 'computational_forcefield_count': 0, 'created_at': '2025-10-23T15:15:59.069496Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 4 - Mixture', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property': [{'citation_count': 0, 'component': [{'created_at': '2025-10-21T20:43:02.741093Z', 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 2', 'node': ['Material'], 'public': False, 'updated_at': '2025-10-21T20:43:02.741102Z', 'uuid': '778f419d-3120-41e6-b0ae-fd46d2b51ae2'}], 'component_count': 1, 'computation_count': 0, 'condition_count': 0, 'created_at': '2025-10-23T15:15:59.069434Z', 'data_count': 0, 'key': 'conc_mass_fraction', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': '', 'updated_at': '2025-10-23T15:15:59.069443Z', 'uuid': '878cacb0-9536-4cdd-9be7-7914587816ca', 'value': '0.6'}, {'citation_count': 0, 'component': [{'created_at': '2025-10-23T15:03:21.738563Z', 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 3', 'node': ['Material'], 'public': False, 'updated_at': '2025-10-23T15:03:21.738565Z', 'uuid': '6e51c5da-23a8-4ad7-bf47-54d6213b491a'}], 'component_count': 1, 'computation_count': 0, 'condition_count': 0, 'created_at': '2025-10-23T15:15:59.069463Z', 'data_count': 0, 'key': 'conc_mass_fraction', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': '', 'updated_at': '2025-10-23T15:15:59.069464Z', 'uuid': '43953773-e521-4536-bae3-7071cdfc6fa3', 'value': '0.4'}], 'property_count': 2, 'public': False, 'updated_at': '2025-10-23T15:15:59.069498Z', 'uuid': 'ad61e0df-4c8f-457a-bc64-98227e63c888'}, {'component_count': 0, 'computational_forcefield_count': 0, 'created_at': '2025-10-23T17:26:37.728812Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 6', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property': [{'citation_count': 0, 'component_count': 0, 'computation_count': 0, 'condition': [{'data_count': 0, 'key': 'temperature', 'model_version': '1.0.1', 'node': ['Condition'], 'type': 'number', 'unit': 'degC', 'uuid': '6c51689b-8f30-4a47-a04a-cdfe048db171', 'value': '100'}], 'condition_count': 1, 'created_at': '2025-10-23T17:26:37.728776Z', 'data_count': 0, 'key': 'density', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'kg/m**3', 'updated_at': '2025-10-23T17:26:37.728777Z', 'uuid': 'f15236c7-973d-49ae-a774-bf8280a7d0ab', 'value': '10'}], 'property_count': 1, 'public': False, 'updated_at': '2025-10-23T17:26:37.728813Z', 'uuid': '2fb33d46-f024-48db-85da-288764882d32'}, {'component_count': 0, 'computational_forcefield_count': 0, 'created_at': '2025-10-23T17:27:55.872878Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 7', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property': [{'citation': [{'node': ['Citation'], 'reference': {'doi': 'https://doi.org/10.1021/acscentsci.3c00011', 'node': ['Reference'], 'title': 'Community Resource for Innovation in Polymer Technology (CRIPT): A Scalable Polymer Material Data Structure', 'type': 'journal_article'}, 'type': 'extracted_by_human', 'uuid': 'c6766019-cba6-411d-8e7e-7b20353c9b82'}], 'citation_count': 1, 'component_count': 0, 'computation_count': 0, 'condition': [{'data_count': 0, 'key': 'temperature', 'model_version': '1.0.1', 'node': ['Condition'], 'type': 'number', 'unit': 'degC', 'uuid': 'df85d5a6-981f-44d5-82ce-fbd18579b42c', 'value': '100'}], 'condition_count': 1, 'created_at': '2025-10-23T17:27:55.872848Z', 'data_count': 0, 'key': 'density', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'kg/m**3', 'updated_at': '2025-10-23T17:27:55.872849Z', 'uuid': '6de9c4a7-b03a-4e8e-a358-374e46654ae6', 'value': '10'}, {'citation_count': 0, 'component_count': 0, 'computation_count': 0, 'condition_count': 0, 'created_at': '2025-10-23T18:53:19.080616Z', 'data_count': 0, 'key': 'density', 'model_version': '1.0.1', 'node': ['Property'], 'sample_preparation_count': 0, 'type': 'number', 'unit': 'kg/m**3', 'updated_at': '2025-10-23T18:53:19.080625Z', 'uuid': '78c7df95-6d8d-4b1f-b2d6-e87c60819b6d', 'value': '30'}], 'property_count': 2, 'public': False, 'updated_at': '2025-10-23T18:53:19.080635Z', 'uuid': 'd91f3fe6-2acf-40de-b44e-593a86e43030'}]
Searching for material in a project by name¶
To search for a material within a project, execute the GET request below using the project uuidand the material name. The API may return material nodes with names similar to the target name, so filtering the results may be necessary.
# Project uuid
project_uuid = PROJECT_UUID # Add your project uuid here
# Material name
material_name = "Test - Material - 2" # Add your material name here
# End point for searching in project
url=f"{base_url}/search/project/{project_uuid}/material?q={material_name}"
# Make request
response = requests.get(url, headers=headers)
# See the result
if response.status_code == 200:
# Get the data
data = response.json()
# If there is not any material in the response, print nothing
if data["data"]["count"] == 0:
print("Material not found")
# If there is a material, print it
else:
# Filtering the materials with the exact name of the query
materials = [material for material in data["data"]["result"] if material["name"] == material_name]
print(f"Material found! \n {materials}")
else:
print("Material not found")
Material found!
[{'component_count': 0, 'computational_forcefield_count': 0, 'created_at': '2025-10-21T20:43:02.741093Z', 'identifier_count': 0, 'locked': False, 'model_version': '1.0.1', 'name': 'Test - Material - 2', 'node': ['Material'], 'project': [{'name': 'API Test Project', 'node': ['Project'], 'uuid': '256b6550-087d-4d64-bfc7-19d322430564'}], 'property_count': 0, 'public': False, 'updated_at': '2025-10-21T20:43:02.741102Z', 'uuid': '778f419d-3120-41e6-b0ae-fd46d2b51ae2'}]
Deleting nodes¶
To delete any node, execute a DELETE request passing the node type (project, material, property, citation, etc) and its uuid. The code below deletes a material node.
# Node uuid
node_uuid = "d8ce8926-edd7-4968-b5bf-1a2bcf8b70e0" # Add node uuid here
# Node type
node_type = "material" # Add node type here (project, material, property, etc)
# Define the endpoint for accessing the node
url = f"{base_url}/{node_type}/{node_uuid}"
# Make request
response = requests.delete(url, headers=headers)
# See results
if response.status_code == 200:
print(f"Successfully deleted {node_type} node! UUID: {node_uuid}")
else:
print(f"Could not delete {node_type} node")
Successfully deleted material node! UUID: d8ce8926-edd7-4968-b5bf-1a2bcf8b70e0
Useful functions¶
Repeating all these processes can be exhausting and prone to errors. So, we prepared a list of useful functions and their descriptions!
# Base URL
base_url = "https://api.criptapp.org/api/v1"
# Keys
bearer_token = "" # You API Token goes here
storage_key = "" # Your Storage Token goes here
# Headers
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {bearer_token}",
"X-Storage-Key": storage_key
}
def post_request(node_type, data_json):
""""
This function executes a POST request, adding a node of type `node_type` with data in `data_json`
"""
global base_url, headers
url = f"{base_url}/{node_type}"
# Make request
response = requests.post(url, json=data_json, headers=headers)
if response.status_code == 200:
# Get the data
data = response.json()
return data
else:
print(f"Could not post {data_json}")
raise Exception(f"{response.json()}")
def patch_request(node_type, data_json, uuid):
""""
This function updates a node of type `node_type` and uuid `uuid` with the data in `data_json`
"""
global base_url, headers
url = f"{base_url}/{node_type}/{uuid}"
# Make request
response = requests.patch(url, json=data_json, headers=headers)
if response.status_code == 200:
# Get the data
data = response.json()
return data["data"]["result"]
else:
print(f"{response.status_code}")
raise Exception(f"{response.json()}")
def get_request(node_type, uuid):
""""
This function executes a GET request on a node of type `node_type` and uuid `uuid`
"""
global base_url, headers
url = f"{base_url}/{node_type}/{uuid}"
# Make request
response = requests.get(url, headers=headers)
if response.status_code == 200:
# Get the data
data = response.json()
return data
else:
print(f"Could not get {uuid}")
return response.json()
def add_node_to_project(project_uuid, json_list, node_type, node_name):
""""
This function adds a node to a project if it does not already exist.
Parameters:
- project_uuid: project uuid
- json_list: list with new node and its data
- node_type: type of the new node
- node_name: name of the new node
"""
# Look for node in the project
data = search_node_in_project(project_uuid=project_uuid, node_name=node_name, node_type=node_type)
# If already exists, return it
if data:
return data
# If does not exist, create
project_json = {
"node": ["Project"],
node_type: json_list
}
data = patch_request(node_type="project", data_json=project_json, uuid=project_uuid)
return data
def create_node(node_type, node_name):
""""
This function creates a new node of type `node_type` and name `node_name`
"""
global headers
data_json = {
"node": [node_type],
"name": node_name,
}
# Try to create the node
data = post_request(node_type=node_type, data_json=data_json)
# If it was successful, return the uuid
if data["code"] == 200:
uuid = data["data"]["result"][0]
return uuid
else:
print(f"Could {node_name} \n {data}")
return None
def search_by_name(node_type, node_name):
""""
This function searches a node by its type (`node_type`) and name (`node_name`)
"""
global base_url, headers
url = f"{base_url}/search/{node_type}?q={node_name}"
# Make request
response = requests.get(url, headers=headers)
if response.status_code == 200:
# Get the data
data = response.json()
if data["data"]["count"] == 0:
return None
else:
return data["data"]["result"][0]
else:
print(f"Did not find {node_name} \n {response.json()}")
return None
def create_or_get_node(node_type, node_name):
""""
This function creates a node of type `node_type` and name `node_name` if it does not already exist
"""
# Search node name
data = search_by_name(node_type, node_name)
# If it does not exist, create node
if data is None:
data = create_node(node_type, node_name)
return data
def delete(node_type, uuid):
""""
This function deletes a node, given its type (`node_type`) and uuid (`uuid`)
"""
global base_url, headers
url = f"{base_url}/{node_type}/{uuid}"
# Make request
response = requests.delete(url, headers=headers)
if response.status_code == 200:
# Get the data
data = response.json()
return data
else:
print(f"Could not delete {uuid}")
return response.json()
def search_node_in_project(project_uuid, node_name, node_type):
""""
This function looks for a node in a project given:
- project_uuid: uuis of the project
- node_name: name of the node
- node_type: type of the node
"""
global headers, base_url
# Set the url for searching within a project
url=f"{base_url}/search/project/{project_uuid}/{node_type}?q={node_name}"
# Make request
response = requests.get(url, headers=headers, params={'limit': None})
# Return the results
if response.status_code == 200:
data = response.json()
# Filter the results that exactly match the query
material_data = [material for material in data["data"]["result"] if material["name"] == node_name]
return material_data
else:
return None