How to use the API¶
In this guide, you will use Python's requests package to call NOMAD's REST
API directly. A public Entry search serves as a concrete example: you will
limit the returned metadata and request the next page of results. The API also
supports other resources and operations, and the same request structure applies
across NOMAD deployments.
Use the REST API directly when you want full control over requests and responses, minimal Python dependencies, or JSON-compatible data. For efficient bulk retrieval of processed archives as schema-aware Python objects, use How-to guides > ... > Access processed data.
The GUI calls the user-facing file container a Project. The REST API
represents the same container as an upload resource, so endpoint paths and
fields retain backend names such as uploads and upload_id.
Before you begin¶
Install requests in your Python environment:
The examples use public data and do not require authentication. They connect to NOMAD Central by default. To test against another deployment, set its API URL before running the scripts. For the NOMAD develop deployment, use:
Build a query in the GUI¶
The GUI can translate filters into an API query:
- Open the NOMAD GUI, select Apps, and open Entries or another search app.
- Use the filter bar or the filter controls to restrict the displayed results. For the query used below, add the Elements filter and select titanium and oxygen. The active filters appear as chips above the results.
- Select the button with the View API call for the query tooltip next to the filter chips.
-
Inspect the API dialog:
- Query contains the API-compatible
ownerandquerygenerated from the active filters. - Request shows the HTTP method, endpoint URL, and full request body used to render the page, including display-related options such as pagination and aggregations.
- Response contains the data returned by that request.
- Query contains the API-compatible
Use Query as a starting point for your own request. Include the additional fields from Request only when your script needs the corresponding result or aggregation settings.
Example: send an Entry search request¶
Create query_entries.py with the following content:
import os
import requests
api_url = os.getenv('NOMAD_API_URL', 'https://nomad-lab.eu/backend/api/v1')
request_body = {
'owner': 'public',
'query': {
'results.material.elements': {'all': ['Ti', 'O']},
},
'pagination': {'page_size': 3},
'required': {
'include': [
'entry_id',
'results.material.chemical_formula_hill',
],
},
}
response = requests.post(
f'{api_url}/entries/query',
json=request_body,
timeout=30,
)
response.raise_for_status()
payload = response.json()
print(f'Total matching Entries: {payload["pagination"]["total"]}')
for entry in payload['data']:
formula = entry['results']['material']['chemical_formula_hill']
print(entry['entry_id'], formula)
Run the script:
The request body combines four fields:
"owner": "public"restricts the search to published Entries without an embargo."query"applies thealloperator toresults.material.elements, requiring the normalized material to contain both titanium and oxygen."page_size": 3underpaginationlimits the current page to at most three Entries.required.includelimits the returned metadata to each Entry's ID and chemical formula.
Calling raise_for_status() makes the script stop on an unsuccessful HTTP
response instead of trying to interpret an error as a successful result.
The response contains the matching records under data and information about
the complete result set under pagination. Entry IDs and the order of results
can change as the deployment's data changes; scripts should consume the
response rather than depend on copied output.
Request the next page¶
Each non-final response contains pagination.next_page_after_value. Pass that
value unchanged as page_after_value in the next request:
next_value = payload['pagination'].get('next_page_after_value')
if next_value:
request_body['pagination']['page_after_value'] = next_value
response = requests.post(
f'{api_url}/entries/query',
json=request_body,
timeout=30,
)
response.raise_for_status()
next_payload = response.json()
Continue until next_page_after_value is absent. Prefer this cursor-based
method when iterating through a result set because page numbers and offsets
have endpoint-specific restrictions.
For field definitions and additional pagination behavior, see Reference > REST API > Pagination.
Authenticate a request¶
Public Entry searches do not require authentication. Requirements for other
requests depend on the resource, endpoint, and deployment. To authenticate with
a personal access token, create one with the minimum required scopes. Set the
NOMAD_PAT environment variable to the token value, then add it to the request
headers:
import os
headers = {
'Authorization': f'Bearer {os.environ["NOMAD_PAT"]}',
'Accept': 'application/json',
}
response = requests.post(
f'{api_url}/entries/query',
headers=headers,
json=request_body,
timeout=30,
)
response.raise_for_status()
See How-to guides > ... > Authenticate programmatically for token creation, scopes, and secure handling.
Discover available endpoints¶
Each deployment provides interactive API documentation generated from its current OpenAPI contract. Open the NOMAD API dashboard to inspect request and response models or try an operation in the browser.
The GUI's APIs page also lists the built-in NOMAD API and APIs supplied by installed plugins. The available plugin APIs therefore depend on the NOMAD deployment.
Related pages¶
- How-to guides > ... > Download data — download Projects, raw files, or processed archives.
- How-to guides > ... > Access processed data — query processed archives as schema-aware Python objects.
- How-to guides > ... > Manage data with Python — create, update, or publish Projects with Python.
- How-to guides > ... > Make Graph API calls — traverse related NOMAD resources in one request.
- Explanation > Data structure — the relationship between Projects, Entries, archives, and schemas.
- Explanation > Authentication and authorization — authentication and authorization concepts.
- Reference > REST API — shared REST request and response fields, including base URLs, resources, query syntax, ownership, pagination, errors, limits, and user-group endpoints.