> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pretectum.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Data Object

> Create a new data object (record) in a specific dataset

The Create Data Object endpoint allows you to add new records to a dataset. The data object structure is determined by the schema definition, and the API validates field values according to schema rules.

## Prerequisites

* A Pretectum API key (see [API Keys](/api-reference/authentication/api-keys))
* Permission to create data objects in your tenant
* Valid business area ID (see [List Business Areas](/api-reference/business-areas/list))
* Valid schema ID (see [List Schemas](/api-reference/schemas/list))
* Valid dataset ID (see [List Datasets](/api-reference/datasets/list))

## Authentication

Include your API key in the `Authorization` header.

```bash theme={null}
Authorization: pre_your_api_key
```

## Request

### Path Parameters

<ParamField path="businessAreaId" type="string" required>
  The unique identifier of the business area. You can obtain this from the [List Business Areas](/api-reference/business-areas/list) endpoint.
</ParamField>

<ParamField path="schemaId" type="string" required>
  The unique identifier of the schema that defines the data structure. You can obtain this from the [List Schemas](/api-reference/schemas/list) endpoint.
</ParamField>

<ParamField path="datasetId" type="string" required>
  The unique identifier of the dataset where the data object will be created. You can obtain this from the [List Datasets](/api-reference/datasets/list) endpoint.
</ParamField>

### Headers

<ParamField header="Authorization" type="string" required initialValue="pre_your_api_key">
  Your Pretectum API key. Create one in the Pretectum app under **Configuration → API Keys**.
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`.
</ParamField>

<ParamField header="Accept" type="string" default="application/json">
  The response content type. Currently only `application/json` is supported.
</ParamField>

### Request Body

The request body should be a JSON object with field names as keys and their values. Field names must match the schema field names exactly.

<ParamField body="[Field Name]" type="varies" required>
  Dynamic fields based on the schema definition. Use the field names as defined in the schema. Values should be formatted according to the field's data type:

  * **string**: Plain text values
  * **integer**: Whole numbers
  * **float**: Decimal numbers
  * **boolean**: `true` or `false`
  * **date**: Date string in the format defined by the schema (e.g., "MM/DD/YYYY")
  * **datetime**: DateTime string in the format defined by the schema
  * **time**: Time string in the format defined by the schema
  * **email**: Valid email address
  * **url**: Valid URL
  * **phone**: Phone number string
  * **picklist**: Value from the predefined list
</ParamField>

### Example Requests

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.pretectum.io/v1/businessareas/20240115103000123a1b2c3d4e5f6789012345678901234/schemas/20240115103000456d1e2f3a4b5c6789012345678901234/datasets/20240925152201042a1b2c3d4e5f6789012345678901234/dataobjects" \
    -H "Authorization: pre_your_api_key" \
    -H "Content-Type: application/json" \
    -H "Accept: application/json" \
    -d '{
      "First Name": "John",
      "Last Name": "Smith",
      "Email": "john.smith@example.com",
      "Phone": "+1 555-123-4567",
      "Date of Birth": "01/15/1985",
      "Status": "Active"
    }'
  ```

  ```javascript JavaScript theme={null}
  const apiKey = 'pre_your_api_key';
  const businessAreaId = '20240115103000123a1b2c3d4e5f6789012345678901234';
  const schemaId = '20240115103000456d1e2f3a4b5c6789012345678901234';
  const datasetId = '20240925152201042a1b2c3d4e5f6789012345678901234';

  async function createDataObject(businessAreaId, schemaId, datasetId, data) {
    const response = await fetch(
      `https://api.pretectum.io/v1/businessareas/${businessAreaId}/schemas/${schemaId}/datasets/${datasetId}/dataobjects`,
      {
        method: 'POST',
        headers: {
          'Authorization': apiKey,
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        body: JSON.stringify(data)
      }
    );

    if (!response.ok) {
      throw new Error(`Failed to create data object: ${response.statusText}`);
    }

    return response.json();
  }

  const newCustomer = {
    'First Name': 'John',
    'Last Name': 'Smith',
    'Email': 'john.smith@example.com',
    'Phone': '+1 555-123-4567',
    'Date of Birth': '01/15/1985',
    'Status': 'Active'
  };

  const created = await createDataObject(businessAreaId, schemaId, datasetId, newCustomer);
  console.log(`Created data object with ID: ${created._dataObjectId}`);
  ```

  ```python Python theme={null}
  import requests

  api_key = 'pre_your_api_key'
  business_area_id = '20240115103000123a1b2c3d4e5f6789012345678901234'
  schema_id = '20240115103000456d1e2f3a4b5c6789012345678901234'
  dataset_id = '20240925152201042a1b2c3d4e5f6789012345678901234'

  def create_data_object(business_area_id, schema_id, dataset_id, data):
      response = requests.post(
          f'https://api.pretectum.io/v1/businessareas/{business_area_id}/schemas/{schema_id}/datasets/{dataset_id}/dataobjects',
          json=data,
          headers={
              'Authorization': api_key,
              'Content-Type': 'application/json',
              'Accept': 'application/json'
          }
      )
      response.raise_for_status()
      return response.json()

  new_customer = {
      'First Name': 'John',
      'Last Name': 'Smith',
      'Email': 'john.smith@example.com',
      'Phone': '+1 555-123-4567',
      'Date of Birth': '01/15/1985',
      'Status': 'Active'
  }

  created = create_data_object(business_area_id, schema_id, dataset_id, new_customer)
  print(f"Created data object with ID: {created['_dataObjectId']}")
  ```
</CodeGroup>

## Response

A successful request returns the created data object with system-generated fields.

<ResponseField name="_dataObjectId" type="string" required>
  The unique identifier generated for the new data object.
</ResponseField>

<ResponseField name="_version" type="integer" required>
  The version number of the data object. A newly created object starts at version `0`; each successful update increments it by one. Send the current value as `_version` when updating.
</ResponseField>

<ResponseField name="_errors" type="array" required>
  An array of validation errors. If the data doesn't conform to schema validation rules, errors will be listed here. The data object is still created, but flagged with errors.

  <Expandable title="Error object properties">
    <ResponseField name="name" type="string">
      The name of the field that has the validation error.
    </ResponseField>

    <ResponseField name="errors" type="string">
      Description of the validation error.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="[Field Name]" type="varies">
  The field values as stored in the system. These may be transformed based on schema rules (e.g., date formatting).
</ResponseField>

### Example Response

```json theme={null}
{
  "_dataObjectId": "20240601120000123f1a2b3c4d5e6789012345678901234",
  "_version": 0,
  "_errors": [],
  "First Name": "John",
  "Last Name": "Smith",
  "Email": "john.smith@example.com",
  "Phone": "+1 555-123-4567",
  "Date of Birth": "01/15/1985",
  "Status": "Active"
}
```

### Response with Validation Errors

If the data doesn't conform to schema rules, the object is created but flagged with errors:

```json theme={null}
{
  "_dataObjectId": "20240601120000123f1a2b3c4d5e6789012345678901234",
  "_version": 0,
  "_errors": [
    {
      "name": "Email",
      "errors": "Invalid email format"
    },
    {
      "name": "Date of Birth",
      "errors": "Date format does not match expected format MM/DD/YYYY"
    }
  ],
  "First Name": "John",
  "Last Name": "Smith",
  "Email": "invalid-email",
  "Phone": "+1 555-123-4567",
  "Date of Birth": "1985-01-15",
  "Status": "Active"
}
```

## Error Responses

| Status Code | Description |
| - | - |
| `400 Bad Request` | Invalid request body or malformed JSON; a missing primary key value when the schema has one (`PRIMARY_KEY_REQUIRED`); or a primary key value already used by another record in the dataset (`DUPLICATE_PRIMARY_KEY`). |
| `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 create data objects. Contact your tenant administrator. |
| `404 Not Found` | The specified business area, schema, or dataset does not exist, or you do not have access to it. |
| `500 Internal Server Error` | An unexpected error occurred on the server. Try again later or contact support. |

## Validation

The API validates field values based on the schema definition:

* **Required fields**: Fields marked as required in the schema must have a value.
* **Data types**: Values must match the expected data type (e.g., integers for integer fields).
* **Format validation**: Emails, URLs, phones, and dates are validated against their expected formats.
* **Picklist values**: Values must be from the predefined list if the field is a picklist.

<Note>
  Data objects with validation errors are still created but flagged in the `_errors` array. This allows you to import data and fix validation issues later.
</Note>

## Best Practices

1. **Validate before sending**: Validate data on the client side before making API calls to reduce errors.
2. **Use correct field names**: Field names are case-sensitive and must match the schema exactly.
3. **Handle errors gracefully**: Check the `_errors` array in the response to identify and report validation issues.
4. **Store the ID**: Save the `_dataObjectId` for future updates or deletions.
5. **Batch imports**: For large data imports, consider using the batch import feature instead of individual API calls.

## Related Endpoints

<CardGroup cols={2}>
  <Card title="List Data Objects" icon="list" href="/api-reference/dataobjects/list">
    Retrieve records from a dataset
  </Card>

  <Card title="Update Data Object" icon="pen" href="/api-reference/dataobjects/update">
    Modify existing records
  </Card>

  <Card title="Delete Data Object" icon="trash" href="/api-reference/dataobjects/delete">
    Remove records from a dataset
  </Card>

  <Card title="Get Data Object by Primary Key" icon="fingerprint" href="/api-reference/dataobjects/get-by-primary-key">
    Fetch one record by its primary key value
  </Card>

  <Card title="Get Schema Details" icon="file-code" href="/api-reference/schemas/get">
    View schema field definitions
  </Card>
</CardGroup>
