---
title: "Entities"
section: "API Reference"
route: /apientities
account: {accountId}
bruce_api: https://{accountId}.api.nextspace.host
guardian_api: https://guardian.nextspace.host
---
# Entities

Entities are the core of Nextspace. An Entity is a record that can represent anything based on your own level of categorization, attribution, and tagging.

Examples of Entity records can be a certain building, a person, or a vehicle.

## Data model

To avoid repeating the data model in the documentation, we'll cover it once here.

Please refer to the terminology section for a definition if you're unsure what an Entity is.

Below is a minimal example of an Entity record. Your custom attributes will sit alongside the Nextspace ones.

```typescript
// @Warning this example is primarily focused at non-assembly Entities.
// Assembly Entities have relative positions to their parent.
interface IEntity {
    // Bruce is a code-word for the Nextspace API.
    // These are internal fields.
    "Bruce": {
        "ID": string,
        "EntityType.ID": string,
        "CreatedBy.User.ID": string,
        // Array of Entity Tag IDs.
        "Layer.ID": number[],
        // Created/updated date/time in ISO 8601 UTC.
        "Created": string;
        "Updated": string;
        "Location"?: {
            // Lat/long are in degrees.
            "latitude": number,
            "longitude": number
            // Altitude is in meters.
            // The Entity's Style will dictate what this is relative to.
            // For example the Style may say "relative-to-ground" which would mean-
            // this altitude value should be added to the ground elevation.
            "altitude"?: number
        },
        "Boundaries"?: {
            // Lat/long are in degrees.
            "maxLatitude": number;
            "maxLongitude": number;
            "minLatitude": number;
            "minLongitude": number;
            // Altitude is in meters.
            "maxAltitude"?: number;
            "minAltitude"?: number;
        },
        "Transform"?: {
            // H/P/R are in degrees.
            "heading"?: number,
            "pitch"?: number,
            "roll"?: number,
            // Scale is a multiplier.
            // This will be multiplied by the Entity Style scale as well.
            "scale"?: number
        },
        // Outline on what parts of the Entity loaded from where.
        // Only available when there are >1 sources of data, or if the only source has something of interest.
        "Outline"?: {
            // Human readable name of the source.
            "Source.Name": string;
            // Indicates if this is the baseline source.
            // This means that the base list of attributes are sourced from here.
            // Other sources will be overlaid on top of this one.
            "Baseline"?: boolean;
            // Array of attribute paths that were sourced from here.
            // If Baseline is true, then this isn't specified and all unspecified attributes are sourced from here.
            "Attribute"?: string[];
            // Indicates if this source is editable.
            // If false, inputs for related attributes will be disabled.
            "Editable": boolean;
            // If the record itself or attributes were sourced from here.
            "Kind": "ATTRIBUTE" | "ENTITY";
            // ID of the source, if any.
            "Source.ID"?: number;
            // Entity Type source ID, if any.
            "EntityType.Source.ID"?: number;
            // Related DateTime if any (for Historic data).
            "DateTime"?: string;
            // Related Scenario record if any.
            "Scenario"?: string | number;
            // Related linking attribute.
            // Eg: for historic data this is the date-time key, for sources it's the FK.
            "ForeignKey"?: string;
        }[];
    },
    // There can be any number of custom attributes defined by you.
    "MyAttribute": string,
    "MyOtherAttribute": {
        "MySubAttribute": number
    }
}
```

[Entity data model](https://nextspace-limited.github.io/nextspace-web-bundle/docs/bruce-models/interfaces/Entity.IEntity.html)

## Requesting an Entity record

The simplest way to retrieve an Entity record is through an HTTPS GET request.

It is best to include a session header as Entities can be restricted through tags.

### Get a single record by ID

```http
GET https://{accountId}.api.nextspace.host/v3/entity/{entity_id}?Type={entityTypeId}&$expand=location
```

**Requires:**

- Account ID: Account ID must be specified in the subdomain of the request url.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `{accountId}` | path | yes | The account id of the account to perform the request on. |
| `{entity_id}` | path | yes | The ID of the Entity to get. |
| `Type={entityTypeId}` | query | no | Optional query parameter to view the Entity under a specific schema. |
| `$expand=location` | query | no | (see the documentation page, this description is rich content) |

**Response**

```typescript
// Response is the same as the Entity definition.
// It returns the Entity JSON directly.
```

**Javascript example**

```javascript
const url = "https://{accountId}.api.nextspace.host/v3/entity/{entity_id}";
const method = "get";
const token = "your-token";
const body = null;

async function doRequest(type, url, body, token) {
    const headers = {
        "Authorization": `Bearer ${token}`,
        "Content-Type": "application/json"
    };
    const options = {
        method: type,
        headers: headers,
        body: body ? JSON.stringify(body) : null
    };
    const res = await fetch(url, options);
    const json = await res.json();
    return json;
}

doRequest(method, url, body, token).then((res) => {
    console.log(res);
}).catch((err) => {
    console.error(err);
});
```

## Requesting list by IDs

You can also request a list of Entities by their IDs.

### Get list of records by IDs

```http
POST https://{accountId}.api.nextspace.host/v3/getEntities
```

**Requires:**

- Account ID: Account ID must be specified in the subdomain of the request url.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `{accountId}` | path | yes | The account id of the account to perform the request on. |

**Request body**

```typescript
interface IPostBody {
    "Filter": {
        ID: {
            // Array of IDs you'd like to request.
            in: string[]
        }
    },
    // Unfortunately, this is required.
    // Set it to length of ID array, otherwise it will use a server default length.
    "PageSize": number
}
```

**Example request body**

```json
{
    "Filter": {
        "ID": {
            "in": [
                "some-entity-id-1",
                "some-entity-id-2"
            ]
        }
    },
    "PageSize": 2
}
```

**Response**

```typescript
interface IResponse {
    "Items": IEntity[];
}
```

**Javascript example**

```javascript
const url = "https://{accountId}.api.nextspace.host/v3/getEntities";
const method = "post";
const token = "your-token";
const body = {
    "Filter": {
        "ID": {
            "in": [
                "some-entity-id-1",
                "some-entity-id-2"
            ]
        }
    },
    "PageSize": 2
};

async function doRequest(type, url, body, token) {
    const headers = {
        "Authorization": `Bearer ${token}`,
        "Content-Type": "application/json"
    };
    const options = {
        method: type,
        headers: headers,
        body: body ? JSON.stringify(body) : null
    };
    const res = await fetch(url, options);
    const json = await res.json();
    return json;
}

doRequest(method, url, body, token).then((res) => {
    console.log(res);
}).catch((err) => {
    console.error(err);
});
```

## Requesting list with an attribute query

Below is a breakdown of how the basics of attribute queries work when requesting a list of Entities.

Supported microservices will apply these filters when requesting external data (for example Maximo) by reversing the data mapping between the two sources.

It is recommended to use DataLab for more advanced queries.

### Get list of records with attribute queries

```http
POST https://{accountId}.api.nextspace.host/v3/getEntities
```

**Requires:**

- Account ID: Account ID must be specified in the subdomain of the request url.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `{accountId}` | path | yes | The account id of the account to perform the request on. |

**Request body**

```typescript
interface IPostBody {
    "Filter": {
        // Attribute path segments are separated by a forward slash. Eg: 'address/city'.
        "an-attribute-path": {
            "an-operator": "a-value"
        }
    },
    "PageSize": number
}

interface ISamples {
    "Filter": {
        // Nested string attribute containing "queen".
        // This is case-insensitive.
        "address/street": {
            "contains": "queen"
        },
        // Nested string attribute equal to "auckland".
        "address/city": {
            "=": "auckland"
        },
        // Numeric attribute between 0 and 100.
        "value-1": {
            "between": [0, 100]
        },
        // Numeric attribute bigger than 100.
        "value-2": {
            ">": 100
        },
        // Date time attribute equal or after 2024-03-15T02:00:52Z.
        "founded-date": {
            // ISO 8601 format.
            ">=": "2024-03-15T02:00:52Z"
        },
        // Date time attribute between 2024-03-15T02:00:52Z and 2024-03-15T02:00:52Z.
        "founded-date-2": {
            // ISO 8601 format.
            "between": ["2024-03-15T02:00:52Z", "2024-03-15T02:00:52Z"]
        },
        // String attribute starting with "a".
        "something-1": {
            "startswith": "a"
        }
        // String attribute ending with "b".
        "something-2": {
            "endswith": "b"
        }
        // Boolean attribute equal to true.
        "is-active": {
            "=": true
        }
    },
    "PageSize": 2
}
```

**Javascript example**

```javascript
const url = "https://{accountId}.api.nextspace.host/v3/getEntities";
const method = "post";
const token = "your-token";
const body = null;

async function doRequest(type, url, body, token) {
    const headers = {
        "Authorization": `Bearer ${token}`,
        "Content-Type": "application/json"
    };
    const options = {
        method: type,
        headers: headers,
        body: body ? JSON.stringify(body) : null
    };
    const res = await fetch(url, options);
    const json = await res.json();
    return json;
}

doRequest(method, url, body, token).then((res) => {
    console.log(res);
}).catch((err) => {
    console.error(err);
});
```

## Requesting list with a geographic query

Below is how you can perform a basic geographic boundary query when requesting a list of Entities.

### Get list of records by IDs

```http
POST https://{accountId}.api.nextspace.host/v3/getEntities
```

**Requires:**

- Account ID: Account ID must be specified in the subdomain of the request url.

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `{accountId}` | path | yes | The account id of the account to perform the request on. |

**Request body**

```typescript
interface IPostBody {
    "Filter": {
        "boundaries": {
            "intersects": [
                // South (min latitude).
                0,
                // North (max latitude).
                0,
                // West (min longitude).
                0,
                // East (max longitude).
                0
            ]
        }
    },
    "PageSize": number
}
```

**Javascript example**

```javascript
const url = "https://{accountId}.api.nextspace.host/v3/getEntities";
const method = "post";
const token = "your-token";
const body = null;

async function doRequest(type, url, body, token) {
    const headers = {
        "Authorization": `Bearer ${token}`,
        "Content-Type": "application/json"
    };
    const options = {
        method: type,
        headers: headers,
        body: body ? JSON.stringify(body) : null
    };
    const res = await fetch(url, options);
    const json = await res.json();
    return json;
}

doRequest(method, url, body, token).then((res) => {
    console.log(res);
}).catch((err) => {
    console.error(err);
});
```

## Updating and creating records

You can request an update or create an Entity record by performing an HTTPS POST request with the Entity's data within the body.

If the Entity ID is not provided, a new Entity will be created.

### Create or update an Entity record

```http
POST https://{accountId}.api.nextspace.host/v3/entity/{entity_id}?Type={entityTypeId}&DataOverride={true/false}
```

**Requires:**

- Account ID: Account ID must be specified in the subdomain of the request url.
- Logged in user auth token: A token for an active user session on the account, sent as "Authorization: Bearer <token>".

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `{accountId}` | path | yes | The account id of the account to perform the request on. |
| `{entity_id}` | path | no | The ID of the Entity to update. If unspecified then a new Entity will be created |
| `Type={entityTypeId}` | query | no | Required parameter if you're creating a record. This will specify the data schema to create the Entity under. |
| `DataOverride={true/false}` | query | no | Overriding the record means that any unspecified attributes will be removed from the record. |

**Request body**

```typescript
// Body is the same as the Entity definition.
// Pass the Entity JSON directly.
```

**Example request body**

```json
{
    "Bruce": {
        "ID": "my_existing_entity_id"
    },
    "MyAttribute": "My new value"
}
```

**Response**

```typescript
// Response is the same as the Entity definition.
// It returns the Entity JSON directly.
```

**Javascript example**

```javascript
const url = "https://{accountId}.api.nextspace.host/v3/entity/{entity_id}";
const method = "post";
const token = "your-token";
const body = {
    "Bruce": {
        "ID": "my_existing_entity_id"
    },
    "MyAttribute": "My new value"
};

async function doRequest(type, url, body, token) {
    const headers = {
        "Authorization": `Bearer ${token}`,
        "Content-Type": "application/json"
    };
    const options = {
        method: type,
        headers: headers,
        body: body ? JSON.stringify(body) : null
    };
    const res = await fetch(url, options);
    const json = await res.json();
    return json;
}

doRequest(method, url, body, token).then((res) => {
    console.log(res);
}).catch((err) => {
    console.error(err);
});
```

### Create or update an array of Entity records

```http
POST https://{accountId}.api.nextspace.host/v3/entities?Type={entityTypeId}&DataOverride={true/false}
```

**Requires:**

- Account ID: Account ID must be specified in the subdomain of the request url.
- Logged in user auth token: A token for an active user session on the account, sent as "Authorization: Bearer <token>".

| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `{accountId}` | path | yes | The account id of the account to perform the request on. |
| `Type={entityTypeId}` | query | no | Required parameter if you're creating a record. This will specify the data schema to create the Entity under. |
| `DataOverride={true/false}` | query | no | Overriding the record means that any unspecified attributes will be removed from the record. |

**Request body**

```typescript
Items: IEntity[]
```

**Example request body**

```json
{
    "Items": [
        {
            "Bruce": {
                "ID": "my_existing_entity_id"
            },
            "MyAttribute": "My new value"
        }
    ]
}
```

**Response**

```typescript
Items: IEntity[]
```

**Javascript example**

```javascript
const url = "https://{accountId}.api.nextspace.host/v3/entities";
const method = "post";
const token = "your-token";
const body = {
    "Items": [
        {
            "Bruce": {
                "ID": "my_existing_entity_id"
            },
            "MyAttribute": "My new value"
        }
    ]
};

async function doRequest(type, url, body, token) {
    const headers = {
        "Authorization": `Bearer ${token}`,
        "Content-Type": "application/json"
    };
    const options = {
        method: type,
        headers: headers,
        body: body ? JSON.stringify(body) : null
    };
    const res = await fetch(url, options);
    const json = await res.json();
    return json;
}

doRequest(method, url, body, token).then((res) => {
    console.log(res);
}).catch((err) => {
    console.error(err);
});
```

---

Urls on this page are resolved for account `{accountId}`.
Site index: https://docs.nextspace.host/llms.txt · whole site in one file: https://docs.nextspace.host/llms-full.txt
Human-readable version of this page: https://docs.nextspace.host/apientities
