Get Data Object by Primary Key
curl --request GET \
--url https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue} \
--header 'Authorization: <authorization>'import requests
url = "https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}"
headers = {"Authorization": "<authorization>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<authorization>'}};
fetch('https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<authorization>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body{
"_dataObjectId": "<string>",
"_version": 123,
"_errors": [
{
"name": "<string>",
"errors": "<string>"
}
],
"[Field Name]": {}
}Data Objects
Get Data Object by Primary Key
Retrieve a single data object by the value of its schema’s primary key field
GET
/
v1
/
businessareas
/
{businessAreaId}
/
schemas
/
{schemaId}
/
datasets
/
{datasetId}
/
dataobjects
/
by-pk
/
{pkValue}
Get Data Object by Primary Key
curl --request GET \
--url https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue} \
--header 'Authorization: <authorization>'import requests
url = "https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}"
headers = {"Authorization": "<authorization>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: '<authorization>'}};
fetch('https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "<authorization>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}")
.header("Authorization", "<authorization>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pretectum.io/v1/businessareas/{businessAreaId}/schemas/{schemaId}/datasets/{datasetId}/dataobjects/by-pk/{pkValue}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = '<authorization>'
response = http.request(request)
puts response.read_body{
"_dataObjectId": "<string>",
"_version": 123,
"_errors": [
{
"name": "<string>",
"errors": "<string>"
}
],
"[Field Name]": {}
}The Get Data Object by Primary Key endpoint returns one record from a dataset, looked up by the value of the field the schema marks as its primary key. It is the direct way to fetch a record when you know its business identifier (a customer number, a SKU, an account code) rather than its
_dataObjectId, and the cheapest way to check whether a record already exists before creating it.
Prerequisites
- A Pretectum API key (see API Keys)
- Permission to access data objects in your tenant
- Valid business area ID (see List Business Areas)
- Valid schema ID (see List Schemas)
- Valid dataset ID (see List Datasets)
- A schema with a primary key field. The Get Schema response marks it with
isPrimaryKey: true.
Authentication
Include your API key in theAuthorization header.
Authorization: pre_your_api_key
Request
Path Parameters
string
required
The unique identifier of the business area. You can obtain this from the List Business Areas endpoint.
string
required
The unique identifier of the schema. You can obtain this from the List Schemas endpoint.
string
required
The unique identifier of the dataset to look in. Primary key values are unique within a dataset, not across datasets. You can obtain this from the List Datasets endpoint.
string
required
The value of the primary key field, exactly as stored. Matching is case-sensitive. URL-encode the value if it contains spaces or reserved characters (
CUST 001 becomes CUST%20001).Headers
string
required
Your Pretectum API key. Create one in the Pretectum app under Configuration → API Keys.
string
default:"application/json"
The response content type. Currently only
application/json is supported.Example Requests
curl -X GET "https://api.pretectum.io/v1/businessareas/20240115103000123a1b2c3d4e5f6789012345678901234/schemas/20240115103000456d1e2f3a4b5c6789012345678901234/datasets/20240925152201042a1b2c3d4e5f6789012345678901234/dataobjects/by-pk/CUST-000123" \
-H "Authorization: pre_your_api_key" \
-H "Accept: application/json"
const apiKey = 'pre_your_api_key';
const businessAreaId = '20240115103000123a1b2c3d4e5f6789012345678901234';
const schemaId = '20240115103000456d1e2f3a4b5c6789012345678901234';
const datasetId = '20240925152201042a1b2c3d4e5f6789012345678901234';
async function getDataObjectByPrimaryKey(businessAreaId, schemaId, datasetId, pkValue) {
const response = await fetch(
`https://api.pretectum.io/v1/businessareas/${businessAreaId}/schemas/${schemaId}/datasets/${datasetId}/dataobjects/by-pk/${encodeURIComponent(pkValue)}`,
{
headers: {
'Authorization': apiKey,
'Accept': 'application/json'
}
}
);
if (response.status === 404) {
return null;
}
if (!response.ok) {
throw new Error(`Lookup failed: ${response.status} ${response.statusText}`);
}
return response.json();
}
const customer = await getDataObjectByPrimaryKey(businessAreaId, schemaId, datasetId, 'CUST-000123');
if (customer) {
console.log(`Found ${customer['First Name']} ${customer['Last Name']} (version ${customer._version})`);
} else {
console.log('No customer with that number');
}
import requests
from urllib.parse import quote
api_key = 'pre_your_api_key'
business_area_id = '20240115103000123a1b2c3d4e5f6789012345678901234'
schema_id = '20240115103000456d1e2f3a4b5c6789012345678901234'
dataset_id = '20240925152201042a1b2c3d4e5f6789012345678901234'
def get_data_object_by_primary_key(business_area_id, schema_id, dataset_id, pk_value):
response = requests.get(
f'https://api.pretectum.io/v1/businessareas/{business_area_id}/schemas/{schema_id}/datasets/{dataset_id}/dataobjects/by-pk/{quote(pk_value, safe="")}',
headers={
'Authorization': api_key,
'Accept': 'application/json'
}
)
if response.status_code == 404:
return None
response.raise_for_status()
return response.json()
customer = get_data_object_by_primary_key(business_area_id, schema_id, dataset_id, 'CUST-000123')
if customer:
print(f"Found {customer['First Name']} {customer['Last Name']} (version {customer['_version']})")
else:
print('No customer with that number')
Response
A successful request returns the data object in the same shape as List Data Objects: the schema’s fields keyed by their display names, plus the system metadata fields.string
required
The unique identifier of the data object. Use it with Update Data Object and Delete Data Object.
integer
required
The current version of the data object. Send this value as
_version when updating the object; the update is rejected if the object has changed since.array
required
varies
The field values, keyed by the schema’s field display names. Date, time and datetime values are formatted according to the schema’s field configuration. Attachment-type fields (
image, document, video, attachment) are returned with time-limited download URLs.Example Response
{
"Customer Number": "CUST-000123",
"First Name": "John",
"Last Name": "Smith",
"Email": "john.smith@example.com",
"Phone": "+1 555-123-4567",
"Date of Birth": "01/15/1985",
"Status": "Active",
"_dataObjectId": "20240601120000123f1a2b3c4d5e6789012345678901234",
"_version": 3,
"_errors": []
}
Not Found
When no record in the dataset has that primary key value, the response is404 Not Found with an empty body. The same response is returned when the schema has no primary key field, and for a record that has been deleted: deleting a record releases its primary key value, so the value can be used again by a new record.
HTTP/1.1 404 Not Found
Error Responses
| Status Code | Description |
|---|---|
401 Unauthorized | The API key is missing, malformed, unknown, inactive, expired or deleted. Check the key in Configuration → API Keys. |
403 Forbidden | Your application client does not have permission to access data objects. Contact your tenant administrator. |
404 Not Found | No record in the dataset has that primary key value, the schema has no primary key field, or the business area, schema or dataset does not exist or is not accessible to you. |
500 Internal Server Error | An unexpected error occurred on the server. Try again later or contact support. |
How the Lookup Works
Pretectum enforces primary key uniqueness within a dataset: when a record is created or its primary key value is changed, the value is reserved in the dataset’s key index, and a second record with the same value is rejected withDUPLICATE_PRIMARY_KEY. This endpoint reads that index, so it is a single, exact lookup regardless of how many records the dataset holds.
Leading and trailing whitespace is trimmed from primary key values both when a record is written and when one is looked up, so
" CUST-000123 " and "CUST-000123" refer to the same record. Matching is otherwise exact and case-sensitive, so cust-000123 does not.Use Cases
Upsert: Create or Update by Business Key
Look a record up by its business identifier and create it if missing, or update it with the version you just read:async function upsertCustomer(businessAreaId, schemaId, datasetId, customer) {
const existing = await getDataObjectByPrimaryKey(businessAreaId, schemaId, datasetId, customer['Customer Number']);
if (!existing) {
return createDataObject(businessAreaId, schemaId, datasetId, customer);
}
return updateDataObject(businessAreaId, schemaId, datasetId, existing._dataObjectId, {
_version: existing._version,
...customer
});
}
def upsert_customer(business_area_id, schema_id, dataset_id, customer):
existing = get_data_object_by_primary_key(business_area_id, schema_id, dataset_id, customer['Customer Number'])
if existing is None:
return create_data_object(business_area_id, schema_id, dataset_id, customer)
return update_data_object(
business_area_id,
schema_id,
dataset_id,
existing['_dataObjectId'],
{'_version': existing['_version'], **customer}
)
Fetching the Current Version Before an Update
An update needs the record’s current_version. When you know the business key, this endpoint is cheaper than paging through List Data Objects to find the record:
const current = await getDataObjectByPrimaryKey(businessAreaId, schemaId, datasetId, 'CUST-000123');
await updateDataObject(businessAreaId, schemaId, datasetId, current._dataObjectId, {
_version: current._version,
'Status': 'Inactive'
});
Best Practices
- Treat
404as “does not exist”: It is the normal answer for a key that has not been used yet, not a failure. Check the ids only if every lookup returns404. - URL-encode the value: Key values with spaces, slashes or other reserved characters must be encoded in the path.
- Use the returned
_versionimmediately: Another writer may change the record between your lookup and your update. OnDATA_OBJECT_VERSION_CONFLICT, look the record up again and retry. - Prefer this endpoint to search for exact lookups: Search Data Objects is for finding records by content; this endpoint is for fetching a known record.
Related Endpoints
List Data Objects
Page through every record in a dataset
Create Data Object
Add a record when the lookup returns 404
Update Data Object
Modify the record using the returned version
Get Schema Details
Find which field is the primary key
