> ## 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.

# Search Data Objects

> Search across your master data objects using flexible query parameters

The Search Data Objects endpoint allows you to search through your master data across business areas, schemas, and datasets. You can perform full-text searches and filter results based on your organizational structure.

## Prerequisites

* A Pretectum API key (see [API Keys](/api-reference/authentication/api-keys))
* Permission to search data objects in your tenant

## Authentication

Include your API key in the `Authorization` header.

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

## Request

### Query Parameters

<ParamField query="query" type="string" required>
  The search query string. This supports full-text search across all indexed fields in your data objects. You can use standard search operators like `AND`, `OR`, and wildcards (`*`).

  **Examples:**

  * `John` - Search for "John" in any field
  * `John AND Smith` - Search for records containing both "John" and "Smith"
  * `email:*@example.com` - Search for email addresses ending with @example.com
</ParamField>

<ParamField query="businessArea" type="string">
  Filter results to a specific business area by name. If not provided or set to "all", the search will include all business areas you have access to.

  Use the [List Business Areas](/api-reference/business-areas/list) endpoint to get the available business area names for your application.

  **Example:** `Customer`, `Product`, `Supplier`
</ParamField>

<ParamField query="schema" type="string">
  Filter results to a specific schema by name. A schema defines the structure and fields of your data objects within a business area.

  Use the [List Schemas](/api-reference/schemas/list) endpoint to get the available schema names for a business area.

  **Example:** `Individual Customer`, `Business Customer`
</ParamField>

<ParamField query="dataSet" type="string">
  Filter results to a specific dataset by name. Datasets are collections of data objects that share the same schema.

  Use the [List Datasets](/api-reference/datasets/list) endpoint to get the available dataset names for a schema.

  **Example:** `US Customers`, `European Customers`
</ParamField>

<ParamField query="from" type="number" default="0">
  The starting position for pagination. Use this to skip a number of results for implementing pagination.

  **Example:** `0` (start from the first result), `10` (start from the 11th result)
</ParamField>

<ParamField query="size" type="number" default="10">
  The maximum number of results to return. Use this in combination with `from` for pagination.

  **Example:** `10`, `25`, `50`
</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>

### Example Requests

<CodeGroup>
  ```bash cURL theme={null}
  # Basic search
  curl -X GET "https://api.pretectum.io/v1/dataobjects/search?query=John" \
    -H "Authorization: pre_your_api_key"

  # Search with filters
  curl -X GET "https://api.pretectum.io/v1/dataobjects/search?query=John&businessArea=Customer&schema=Individual" \
    -H "Authorization: pre_your_api_key"

  # Search with pagination
  curl -X GET "https://api.pretectum.io/v1/dataobjects/search?query=John&from=0&size=20" \
    -H "Authorization: pre_your_api_key"
  ```

  ```javascript JavaScript theme={null}
  const apiKey = 'pre_your_api_key';

  // Build query parameters
  const params = new URLSearchParams({
    query: 'John',
    businessArea: 'Customer',
    from: '0',
    size: '20'
  });

  const response = await fetch(
    `https://api.pretectum.io/v1/dataobjects/search?${params}`,
    {
      headers: {
        'Authorization': apiKey
      }
    }
  );

  const data = await response.json();
  console.log(`Found ${data.total} results`);
  data.hits.forEach(hit => console.log(hit));
  ```

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

  api_key = 'pre_your_api_key'

  response = requests.get(
      'https://api.pretectum.io/v1/dataobjects/search',
      params={
          'query': 'John',
          'businessArea': 'Customer',
          'from': 0,
          'size': 20
      },
      headers={
          'Authorization': api_key
      }
  )

  data = response.json()
  print(f"Found {data['total']} results")
  for hit in data['hits']:
      print(hit)
  ```
</CodeGroup>

## Response

A successful search returns a list of matching data objects and the total count.

<ResponseField name="hits" type="array" required>
  An array of data objects matching your search query. Each object contains the data fields defined in its schema plus metadata fields.

  <Expandable title="Hit object properties">
    <ResponseField name="_dataObjectId" type="string">
      The unique identifier for this data object.
    </ResponseField>

    <ResponseField name="_businessAreaName" type="string">
      The name of the business area this data object belongs to.
    </ResponseField>

    <ResponseField name="_schemaName" type="string">
      The name of the schema that defines this data object's structure.
    </ResponseField>

    <ResponseField name="_dataSetName" type="string">
      The name of the dataset this data object belongs to.
    </ResponseField>

    <ResponseField name="_businessAreaId" type="string">
      The unique identifier of the business area.
    </ResponseField>

    <ResponseField name="_schemaId" type="string">
      The unique identifier of the schema.
    </ResponseField>

    <ResponseField name="_dataSetId" type="string">
      The unique identifier of the dataset.
    </ResponseField>

    <ResponseField name="[field_name]" type="varies">
      Additional fields as defined by the schema. The available fields depend on your schema configuration.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="total" type="number" required>
  The total number of data objects matching your search query. Use this with `from` and `size` parameters for pagination.
</ResponseField>

### Example Response

```json theme={null}
{
  "hits": [
    {
      "_dataObjectId": "20240601120000123f1a2b3c4d5e6789012345678901234",
      "_businessAreaName": "Customer",
      "_schemaName": "Individual Customer",
      "_dataSetName": "US Customers",
      "_businessAreaId": "20240115103000123a1b2c3d4e5f6789012345678901234",
      "_schemaId": "20240115103000456d1e2f3a4b5c6789012345678901234",
      "_dataSetId": "20240201140000789h3c4d5e6f7a8901234567890123456",
      "First Name": "John",
      "Last Name": "Smith",
      "Email": "john.smith@example.com",
      "Phone": "+1-555-0123",
      "Street": "123 Main Street",
      "City": "New York",
      "State": "NY",
      "Zip Code": "10001"
    },
    {
      "_dataObjectId": "20240601120100456g2b3c4d5e6f7890123456789012345",
      "_businessAreaName": "Customer",
      "_schemaName": "Individual Customer",
      "_dataSetName": "US Customers",
      "_businessAreaId": "20240115103000123a1b2c3d4e5f6789012345678901234",
      "_schemaId": "20240115103000456d1e2f3a4b5c6789012345678901234",
      "_dataSetId": "20240201140000789h3c4d5e6f7a8901234567890123456",
      "First Name": "John",
      "Last Name": "Doe",
      "Email": "john.doe@example.com",
      "Phone": "+1-555-0456",
      "Street": "456 Oak Avenue",
      "City": "Los Angeles",
      "State": "CA",
      "Zip Code": "90001"
    }
  ],
  "total": 2
}
```

### Empty Results

When no data objects match your query, the response will contain an empty hits array:

```json theme={null}
{
  "hits": [],
  "total": 0
}
```

## 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` | You do not have permission to search data objects. Contact your tenant administrator. |
| `400 Bad Request` | Missing required `query` parameter or invalid parameter values. |

## Search Query Syntax

The `query` parameter supports two types of searches: **full-text search** for finding terms across all fields, and **field-specific search** for filtering by specific attribute values.

### Full-Text Search

Full-text search looks for matching terms across all indexed fields in your data objects.

| Pattern | Description | Example |
| - | - | - |
| Simple term | Match records containing the term in any field | `John` |
| Multiple terms | Match records containing all terms (implicit AND) | `John Smith` |
| AND operator | Explicit AND between terms | `John AND Smith` |
| OR operator | Match records containing either term | `John OR Jane` |
| NOT operator | Exclude records containing a term | `John NOT Doe` |
| Wildcards | Match partial terms | `Jo*` (matches John, Jones, etc.) |
| Phrase search | Match exact phrase in sequence | `"John Smith"` |
| Grouping | Group terms with parentheses | `(John OR Jane) AND Smith` |

<CodeGroup>
  ```bash Full-Text Examples theme={null}
  # Find records containing "John" in any field
  query=John

  # Find records containing both "John" and "Smith" anywhere
  query=John Smith
  query=John AND Smith

  # Find records containing either "John" or "Jane"
  query=John OR Jane

  # Find records with "John" but not "Doe"
  query=John NOT Doe

  # Find exact phrase "John Smith"
  query="John Smith"

  # Find names starting with "Jo"
  query=Jo*

  # Complex query with grouping
  query=(John OR Jane) AND (Smith OR Doe)
  ```
</CodeGroup>

### Comparison Operators

You can also use comparison operators with bracket notation for field names. This syntax is useful when field names contain spaces or special characters.

| Operator | Description | Example |
| - | - | - |
| `eq` | Equals - exact match | `[First Name] eq "Tim"` |
| `ne` | Not equals - exclude exact match | `[Status] ne "Inactive"` |
| `gt` | Greater than | `[Age] gt 21` |
| `lt` | Less than | `[Age] lt 65` |
| `ge` | Greater than or equal | `[Order Amount] ge 100` |
| `le` | Less than or equal | `[Price] le 500` |
| `contains` | Contains substring | `[Email] contains "example.com"` |
| `startswith` | Starts with value | `[Last Name] startswith "Sm"` |
| `endswith` | Ends with value | `[Email] endswith ".com"` |

<CodeGroup>
  ```bash Comparison Operator Examples theme={null}
  # Find customers where First Name equals "Tim"
  query=[First Name] eq "Tim"

  # Find customers where Last Name equals "Smith"
  query=[Last Name] eq "Smith"

  # Find customers where Status is not "Inactive"
  query=[Status] ne "Inactive"

  # Find customers older than 21
  query=[Age] gt 21

  # Find customers 65 or younger
  query=[Age] le 65

  # Find orders with amount greater than or equal to $100
  query=[Order Amount] ge 100

  # Find products with price less than $500
  query=[Price] lt 500

  # Find customers with email containing "example.com"
  query=[Email] contains "example.com"

  # Find customers whose last name starts with "Sm"
  query=[Last Name] startswith "Sm"

  # Find customers whose email ends with ".org"
  query=[Email] endswith ".org"
  ```
</CodeGroup>

### Combining Comparison Operators

You can combine multiple comparison operators using `and` and `or` keywords.

<CodeGroup>
  ```bash Combined Operator Examples theme={null}
  # Find customers named Tim Smith
  query=[First Name] eq "Tim" and [Last Name] eq "Smith"

  # Find customers in CA or NY
  query=[State] eq "CA" or [State] eq "NY"

  # Find active customers aged 18 to 65
  query=[Status] eq "Active" and [Age] ge 18 and [Age] le 65

  # Find premium customers with high order value
  query=[Customer Type] eq "Premium" and [Order Amount] gt 1000

  # Find customers in specific cities
  query=[City] eq "New York" or [City] eq "Los Angeles" or [City] eq "Chicago"

  # Complex condition with grouping
  query=([State] eq "CA" or [State] eq "NY") and [Status] eq "Active"

  # Find inactive customers or those with no recent orders
  query=[Status] eq "Inactive" or [Last Order Date] lt "2024-01-01"

  # Find products in Electronics category under $500
  query=[Category] eq "Electronics" and [Price] le 500 and [In Stock] eq "true"
  ```
</CodeGroup>

### Mixing Query Styles

You can combine bracket notation with standard field syntax in the same query.

<CodeGroup>
  ```bash Mixed Query Examples theme={null}
  # Combine bracket notation with standard syntax
  query=[First Name] eq "Tim" AND address.state:CA

  # Full-text search with comparison operator
  query=premium AND [Customer Type] eq "Enterprise"

  # Field-specific with comparison operator
  query=email:*@example.com and [Status] eq "Active"
  ```
</CodeGroup>

### Field-Specific Search (Attribute Filtering)

Filter records by specific attribute values using the `field:value` syntax. This allows you to target searches to particular fields in your data objects.

| Pattern | Description | Example |
| - | - | - |
| Exact field match | Match exact value in a specific field | `firstName:John` |
| Field with wildcard | Match partial values in a field | `email:*@example.com` |
| Field phrase | Match exact phrase in a field | `address.city:"New York"` |
| Field range | Match numeric or date ranges | `age:[18 TO 65]` |
| Field exists | Find records where field has any value | `_exists_:email` |
| Field missing | Find records where field is empty | `NOT _exists_:phone` |
| Multiple fields | Combine field filters | `firstName:John AND city:Boston` |

<CodeGroup>
  ```bash Field-Specific Examples theme={null}
  # Find customers with first name "John"
  query=firstName:John

  # Find customers with last name "Smith" or "Johnson"
  query=lastName:(Smith OR Johnson)

  # Find customers with email addresses from example.com
  query=email:*@example.com

  # Find customers in New York city
  query=address.city:"New York"

  # Find customers in California state
  query=address.state:CA

  # Find customers with a phone number on file
  query=_exists_:phone

  # Find customers missing email address
  query=NOT _exists_:email

  # Combine full-text and field-specific search
  query=John AND address.state:NY

  # Find customers in NY or CA with name containing "Smith"
  query=lastName:*Smith* AND address.state:(NY OR CA)
  ```
</CodeGroup>

### Numeric and Date Range Queries

Use range syntax to filter by numeric values or dates.

| Pattern | Description | Example |
| - | - | - |
| Inclusive range | Match values within range (inclusive) | `age:[18 TO 65]` |
| Exclusive range | Match values within range (exclusive) | `age:{18 TO 65}` |
| Greater than | Match values greater than | `age:>18` |
| Less than | Match values less than | `age:<65` |
| Greater or equal | Match values greater than or equal | `age:>=18` |
| Less or equal | Match values less than or equal | `age:<=65` |

<CodeGroup>
  ```bash Range Query Examples theme={null}
  # Find customers aged 18 to 65 (inclusive)
  query=age:[18 TO 65]

  # Find customers aged between 18 and 65 (exclusive)
  query=age:{18 TO 65}

  # Find customers older than 21
  query=age:>21

  # Find customers 65 or younger
  query=age:<=65

  # Find orders with amount between $100 and $1000
  query=orderAmount:[100 TO 1000]

  # Find records created after a specific date
  query=createdDate:>2024-01-01

  # Find records updated in 2024
  query=updatedDate:[2024-01-01 TO 2024-12-31]
  ```
</CodeGroup>

### Nested Object Queries

For data objects with nested attributes, use dot notation to access nested fields.

<CodeGroup>
  ```bash Nested Field Examples theme={null}
  # Search by nested address fields
  query=address.city:Boston
  query=address.state:MA
  query=address.zipCode:02101

  # Search by nested contact information
  query=contact.email:*@company.com
  query=contact.phone.mobile:+1-555*

  # Combine nested field searches
  query=address.city:Boston AND address.state:MA

  # Search nested objects with phrase
  query=address.street:"123 Main Street"
  ```
</CodeGroup>

### Escaping Special Characters

If your search term contains special characters, escape them with a backslash (`\`).

**Special characters:** `+ - = && || > < ! ( ) { } [ ] ^ " ~ * ? : \ /`

```bash theme={null}
# Search for email with special characters
query=email:john\+newsletter@example.com

# Search for values containing parentheses
query=company:"Acme \(Corp\)"
```

### Query Examples by Use Case

<AccordionGroup>
  <Accordion title="Customer Search Examples">
    ```bash theme={null}
    # Find customer by full name
    query=firstName:John AND lastName:Smith

    # Find customers by email domain
    query=email:*@bigcorp.com

    # Find customers in a specific region
    query=address.state:(CA OR OR OR WA) AND customerType:Enterprise

    # Find customers with recent orders
    query=lastOrderDate:>2024-01-01 AND status:Active

    # Find VIP customers in New York
    query=customerTier:VIP AND address.city:"New York"
    ```
  </Accordion>

  <Accordion title="Product Search Examples">
    ```bash theme={null}
    # Find products by SKU prefix
    query=sku:PROD-2024*

    # Find products in a price range
    query=price:[50 TO 200] AND category:Electronics

    # Find products by brand
    query=brand:(Apple OR Samsung OR Google)

    # Find in-stock products
    query=inventory:>0 AND status:Active

    # Find products with specific attributes
    query=color:Blue AND size:(M OR L) AND inStock:true
    ```
  </Accordion>

  <Accordion title="Complex Query Examples">
    ```bash theme={null}
    # Multi-condition customer search
    query=(firstName:John OR firstName:Jane) AND address.state:CA AND NOT status:Inactive

    # Product availability search
    query=category:Electronics AND price:[100 TO 500] AND inventory:>10 AND rating:>=4

    # Full-text with field filters
    query="premium service" AND customerType:Enterprise AND region:(North OR East)

    # Date range with status filter
    query=createdDate:[2024-01-01 TO 2024-06-30] AND status:(Pending OR Processing)
    ```
  </Accordion>
</AccordionGroup>

## Pagination

For large result sets, use pagination to retrieve results in smaller batches:

```bash theme={null}
# First page (results 1-20)
GET /v1/dataobjects/search?query=John&from=0&size=20

# Second page (results 21-40)
GET /v1/dataobjects/search?query=John&from=20&size=20

# Third page (results 41-60)
GET /v1/dataobjects/search?query=John&from=40&size=20
```

<Tip>
  Use the `total` field in the response to determine the total number of pages available.
</Tip>

## Best Practices

1. **Use specific queries**: More specific queries return more relevant results and perform better.
2. **Filter by business area**: When possible, filter by `businessArea` to narrow your search scope.
3. **Implement pagination**: Always paginate large result sets to improve performance.
4. **Handle empty results**: Your application should gracefully handle cases where no results are found.
5. **Reuse one key**: An API key does not expire on its own, so hold it in configuration rather than fetching a credential per request.
