

The dataset PATCH API is used to edit page content and metadata.
It is distinct from the file upload API.
It accepts a JSON Patch body which is applied to the dataset JSON. Edits to immutable fields will be ignored.
editor role can patch any field.uploader role can only patch resources, links, nextReviewDate, createdAt and updatedAt. Patching anything else returns 403.dataset.updatedAt are not automatically updated.
/updatedAt with an ISO 8601 timestamp, or leave it intact to make silent updates.| :id | 5-character ID of the dataset, eg. "ab12x" | string | Required |
| Authorization | API key with editor permissions. | string | Required |
| Content-Type | Must be "application/json". Most clients will set this automatically. | string | Required |
| 200 | Returns the updated dataset JSON. |
| 400 | Returns a JSON object explaining the error. |
| 403 | API key does not have editor permissions, or an uploader attempted to edit locked metadata. |
| 404 | The dataset does not exist. |
import requests, os, json
api_key = os.getenv("DATAPRESS_API_KEY")
dataset_id = "20abc"
headers = { "Authorization": api_key }
patch = [
{
"op": "replace",
"path": "/title",
"value": "Title has been updated"
}
]
url = f"https://data.website/api/v3/dataset/{dataset_id}"
# This will submit the patch with the header "Content-Type: application/json"
response = requests.patch(url, json=patch, headers=headers)
print(json.dumps(response.json(), indent=2))
{
"dataset": {
"id": "20abc",
"title": "Title has been updated",
// [...full JSON structure...]
},
// The JSON Patch operations that were actually applied:
"applied": [
{ "op": "replace", "path": "/title", "value": "Title has been updated" }
]
}
The API will return a 400 Bad Request code if the patch is invalid. The error message provides more information.
For example, this script attempts to set the title to an empty string:
import requests, os, json
# This patch is invalid:
# It attempts to set the title to an empty string.
patch = [
{
"op": "replace",
"path": "/title",
"value": ""
}
]
url = f"https://data.website/api/v3/dataset/20abc"
# This will submit the patch with the header "Content-Type: application/json"
headers = { "Authorization": os.getenv("DATAPRESS_API_KEY") }
response = requests.patch(url, json=patch, headers=headers)
print(f"// HTTP Status Code: {response.status_code}")
print(f"// Status Message: {response.reason}")
print("// Response JSON body:")
print(json.dumps(response.json(), indent=2))
// HTTP Status Code: 400
// Status Message: There are validation errors.
// Response JSON body:
{
"url": "/api/v3/dataset/20abc",
"statusCode": 400,
"statusMessage": "There are validation errors.",
"message": "There are validation errors.\n* title: This field is required",
"data": [
{
"code": "too_small",
"minimum": 1,
"type": "string",
"inclusive": true,
"exact": false,
"message": "This field is required",
"path": [
"title"
]
}
]
}
The dataset.resources and dataset.links objects automatically generate unique 3-character IDs for new entries.
bcdefghjklmnpqrstvwxyz0123456789/links/_ will cause the API to generate the ID for you.import requests, os, json
patch = [
{
"op": "add",
"path": "/links/this_id_is_overwritten",
"value": {
# Valid link JSON goes here. Minimal keys are "url" and "title":
"url": "https://datapress.com/docs/api",
"title": "DataPress API Reference"
}
}
]
url = f"https://data.website/api/v3/dataset/20abc"
headers = { "Authorization": os.getenv("DATAPRESS_API_KEY") }
# This will submit the patch with the header "Content-Type: application/json"
response = requests.patch(url, json=patch, headers=headers)
print(json.dumps(response.json(), indent=2))
{
"dataset": {
// [...full JSON structure]
"links": {
// The ID of the new field:
"gn9": {
"url": "https://datapress.com/docs/api",
"title": "DataPress API Reference",
"order": 2,
"description": "",
// Immutable, server-generated:
// (The QA data is refreshed every 24 hours).
"qa": {
"hash": null,
"size": null,
"mimetype": "text/html; charset=utf-8",
"timestamp": "2025-01-27T18:21:56.938Z",
"httpStatus": 404
}
}
}
}
}