# Introduction

{% columns fullWidth="false" %}
{% column width="50%" %}

## API Reference

Welcome to the **gospace AI** API reference. Our API is organised around REST, offering predictable, resource-oriented URLs, and uses standard HTTP response codes and verbs. It is designed to have an effortless integration and provide powerful features for developers looking to incorporate intelligent, dynamic space scheduling and workspace utilisation into their applications or platforms.

The **gospace API** empowers you to streamline and automate complex office management tasks like space scheduling, team coordination, and workspace demand forecasting.

With the **gospace API**, you can:

* **Manage and Automate Scheduling:** Schedule, update, and cancel space bookings on behalf of teams or individuals within an organisation.
* **Retrieve and Analyse Space Usage Data:** Access real-time and historical data on space usage and workspace demand patterns.
* **Integrate with Existing Tools:** Seamlessly integrate with collaboration platforms like Microsoft 365 for a unified workspace management experience.
* **Configure Settings and Preferences:** Define team requirements, set minimum in-office days, or decommission unused space programmatically.
  {% endcolumn %}

{% column %}

#### Getting started?

Check out our developer [quick start guide](/start-building/setup-your-development-environment)

#### Not a Developer?

Use the gospace AI [admin console](https://console.gospace.app/) to automate your workplace, or [contact us](https://www.gospace.com/contact) for any custom integrations <support@gospace.com>.

<div data-full-width="true"><figure><img src="/files/wZMho094RXwgdyPyEZuY" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}
{% endcolumns %}

We've designed our API with developer usability in mind. Each API endpoint in the gospace AI API comes with detailed descriptions, usage examples, and error messages to make your development process as smooth as possible.

We also provide extensive libraries for popular programming languages and a detailed developer dashboard for testing and troubleshooting. You can find more details about specific endpoints, requests, and responses in the subsequent sections of this documentation.

Whether you're integrating the **gospace AI** into a single platform or developing a suite of workspace management tools, our API is designed to provide you with the flexibility and power you need to create an efficient, future-ready work environment.


# Authentication

The gospace API uses API keys to authenticate requests. You can view and manage your API keys in the gospace AI console by navigating to [**Admin > Settings > API Keys**](https://console.gospace.app/settings/api-keys).

### API Key Creation

* **One-Time Display**: API keys are **only visible once at the time of creation**. After you generate an API key, it will not be displayed again for security reasons.
* **Secure Storage Required**: Immediately store your new API key in a secure location. If you lose access to it, you will need to generate a new key.

### Authentication

Authentication to the API is performed via HTTP headers using the `x-api-key` header. Provide your API key in the following format:

{% code title="REQUEST HEADERS" %}

```typescript
headers: {
  "x-api-key": "prod_********-****-****-1a234b56"
}
```

{% endcode %}

* **HTTPS Required**: All API requests must be made over HTTPS. Calls made over plain HTTP will fail.
* **Authentication Required**: API requests without a valid API key will fail

### Security Best Practices

Your API keys hold a significant amount of power, so make sure to keep them secure!

* **Avoid Sharing Secret API Keys**: Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so on.
* **Secure Storage Solutions**: Use secure methods to store your API keys, such as environment variables, key management services, or encrypted configuration files.
* **Access Control**: Limit access to your API keys to only those individuals who need them for development or deployment purposes.
* **Avoid Hard-Coding**: Do not hard-code API keys into your application's source code, especially if the code will be stored in version control systems or shared repositories.
* **Rotate Keys Periodically**: For enhanced security, rotate your API keys periodically.

### Managing Your API Keys

* **Creating a New API Key**:
  1. Navigate to your account dashboard.
  2. Go to **Admin > Settings > API Keys**.
  3. Click on **Create New API Key**.
  4. **Copy the key when it is displayed. Remember, this is the only time you will be able to view it.**
* **Regenerating an API Key**: If you lose your API key, delete the lost key from the dashboard and create a new one.
* **Revoking an API Key**: To revoke access, delete the API key from your account dashboard. This action cannot be undone.

### Troubleshooting

* **Lost API Key**: If you did not save your API key at the time of creation and have lost it, you must generate a new one.
* **Unauthorised Errors**: If you encounter authentication errors, ensure that you are using a valid API key and that it has not been revoked.
* **Rate Limit Exceeded**: If you receive errors related to rate limits, review your application's request patterns and adjust accordingly.
* **Contact Support**: For any issues not resolved by the above steps, contact our support team for assistance.

***

Remember that API keys are sensitive credentials that grant access to your account's capabilities and data. Handling them with care is essential for maintaining the security and integrity of your applications.


# Errors

**gospace AI** uses standard HTTP response codes to signal the success or failure of an API request. Typically:

* Codes in the 2xx range signify success.
* Codes in the 4xx range suggest that the request failed due to the provided information. This could be due to reasons like missing a required parameter, a model training failure, etc.
* Codes in the 5xx range imply a server-side error with gospace AI's systems, which are quite rare.

Certain 4xx errors that could be programmatically addressed, such as insufficient training data or unsupported model type, include an error code offering a brief explanation of the reported error.

<table data-full-width="false"><thead><tr><th></th><th></th></tr></thead><tbody><tr><td>200 - OK</td><td>The request succeeded.</td></tr><tr><td>400 - Bad Request</td><td>There's an issue with the data in the request.</td></tr><tr><td>401 - Unauthorised</td><td>No valid API key provided.</td></tr><tr><td>403 - Forbidden</td><td>The API key doesn't have permission.</td></tr><tr><td>404 - Not Found</td><td>The requested resource doesn't exist.</td></tr><tr><td>429 - Too Many Requests</td><td>Too many requests hit the API too quickly. </td></tr><tr><td>500, 502, 503, 504 - Server Errors</td><td>Oops thats us...</td></tr></tbody></table>


# Pagination

In this guide, we will look at how to work with paginated responses when querying the gospace API. The default limit for all responses is 25. However, this can be overwritten by adding a `limit` parameter to your requests (50000 max or 10Mb).&#x20;

Pagination is supported on all endpoints that return an array of objects. In paginated responses, objects are nested in a `data` attribute. You can use the `limit` and `skip` query parameters to browse pages.

{% code title="RESPONSE" fullWidth="false" %}

```typescript
{
    success: true,
    identifier: <request identifier>,
    data: {
        [response key]: [...],
        pagination: {
            current_results: {
                from: 1,
                to: 25
            },
            total_results: 100
        },
        identifier: <endpoint identifier>
    }
}
```

{% endcode %}


# API Limits

The **gospace APIs** enforce limits to ensure performance, reliability, and fair usage across all services hosted at [https://api.gospace.app](https://api.gospace.app/). These limits cover usage quotas, request and response size restrictions, and timeouts. Below are the details for developers integrating with any **gospace API**.

### Usage Limits

Usage limits are applied per API key to manage the number of requests you can make across all gospace APIs within a specified time period. These limits help maintain service availability and prevent abuse. Exceeding these limits results in a 429 Too Many Requests response. Contact support at [support@gospace.com](mailto:support@gospace.com\)) to discuss higher quotas or custom plans.

| Limit Type          | Value                | Description                                                                     |
| ------------------- | -------------------- | ------------------------------------------------------------------------------- |
| Requests per Second | 100 requests/second  | Maximum number of API requests allowed per second per API key across all APIs.  |
| Requests per Day    | 100,000 requests/day | Maximum number of API requests allowed per day (24-hour period) per API key.    |
| Burst Limit         | 200 requests         | Maximum number of requests that can be made in a short burst before throttling. |

* Note: Usage limits reset daily at midnight UTC. If you require higher limits, please contact  <support@gospace.com> for a custom plan.

### Request Size Limits

The size of incoming requests (including headers, query parameters, and body) is limited to ensure efficient processing across all gospace APIs. Exceeding these limits results in a 413 Payload Too Large response.

| Parameter         | Limit | Description                                                                       |
| ----------------- | ----- | --------------------------------------------------------------------------------- |
| Request Body Size | 10 MB | Maximum size of the request body (e.g., JSON payload for POST or PUT requests).   |
| Query Parameters  | 10 KB | Maximum total size of query parameters (e.g., skip, limit, or filter parameters). |
| Headers           | 10 KB | Maximum total size of HTTP headers, including the x-api-key header.               |

* Example: For a POST request to create resources (e.g., { "connections": \[] } or { "teams": \[] }), ensure the JSON payload does not exceed 10 MB. Query parameters in GET requests (e.g., skip=0\&limit=25) must stay within 10 KB.

### Response Size Limits

The size of API responses is limited to ensure efficient data transfer. If a response exceeds these limits, it may be truncated, and a 413 Payload Too Large response will be returned.

| Parameter          | Limit | Description                                                                    |
| ------------------ | ----- | ------------------------------------------------------------------------------ |
| Response Body Size | 10 MB | Maximum size of the response body (e.g., JSON data returned by GET endpoints). |

* Example: For a GET request retrieving a list of resources (e.g., { "success": true, "data": { "connections": \[] } }), the response is limited to 10 MB. Use pagination parameters (skip, limit) to manage large result sets.

### Timeout Limits

API requests are subject to timeout limits to ensure timely responses and prevent resource exhaustion. If a request exceeds the timeout, a 504 Gateway Timeout response is returned.

| Parameter       | Limit      | Description                                                                  |
| --------------- | ---------- | ---------------------------------------------------------------------------- |
| Request Timeout | 30 seconds | Maximum time allowed for the API to process a request and return a response. |

* Example: Complex queries (e.g., filtering by entity type or ID) must complete within 30 seconds, or the request will time out.

### Best Practices

* Pagination: Use skip and limit query parameters in GET requests (e.g., GET /connections?skip=0\&limit=25) to retrieve large datasets incrementally and avoid exceeding response size limits.
* Batch Operations: Leverage bulk operations (e.g., POST /labels/mapping, PUT /connections) to create or update multiple resources in a single request, reducing the number of requests and staying within usage quotas.
* Optimise Payloads: Minimise the size of request bodies by including only necessary fields in objects like connection\_entity\_data or details.
* Rate Limiting Handling: Implement exponential backoff in your application to retry requests after receiving a 429 Too Many Requests response.
* Error Monitoring: Check the identifier field in error responses (e.g., "identifier": "bad\_request") to diagnose issues related to limits.

### Error Responses

Exceeding API limits results in the following HTTP status codes and error responses:

| Status Code | Description       | Example Response                                                                                                                 |
| ----------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| 429         | Too Many Requests | { "success": false, "error": { "code": 429, "message": "Rate limit exceeded." }, "identifier": "rate\_limit\_exceeded" }         |
| 413         | Payload Too Large | { "success": false, "error": { "code": 413, "message": "Request or response too large." }, "identifier": "payload\_too\_large" } |
| 504         | Gateway Timeout   | { "success": false, "error": { "code": 504, "message": "Request timed out." }, "identifier": "request\_timeout" }                |

### Contact Support

If you need assistance with limits, require higher quotas, or encounter issues, contact our support team at <support@gospace.com>.


# Webhooks

Webhooks provide a mechanism for notifying client applications when certain events happen on the server. This is an efficient alternative to polling for changes. You can configure a webhook by logging into the [gospace AI console](https://console.gospace.app) and navigating to `Admin > Settings > Webhooks.`

### Webhook security

To verify that the request comes from gospace AI, a `x-gospace-signature` header is added to each request. The value of this header is a HMAC SHA256 hash computed from the request body and your webhook signature key.

{% code title="RESPONSE HEADERS" %}

```json
headers: {
  "x-gospace-signature": "11eu12e102ru102ur102ru019u2r102ur012ur09"
}
```

{% endcode %}

### Webhook format

When an event occurs, we will make a `POST` request to the URL specified when you created the webhook. The request body will contain an event object which includes the topic string and data object.

{% code title="REQUEST" %}

```json
{
  topic: <topic string>,
  data: {
    _id: <entity ID>
  }
}
```

{% endcode %}

### Webhook events

gospace AI features an extensive events library that allows organisations to subscribe to and act on real-time events. This powerful feature enables businesses to track actions and automate responses, creating a dynamic and interactive AI environment.

| Event                       | Description                          |
| --------------------------- | ------------------------------------ |
| ALLOCATION\_CREATED         | An allocation has been created.      |
| ALLOCATION\_UPDATED         | An allocation has been updated.      |
| ALLOCATION\_DELETED         | An allocation has been deleted.      |
| INTENTION\_CREATED          | An intention has been created.       |
| INTENTION\_UPDATED          | An intention has been updated.       |
| INTENTION\_DELETED          | An intention has been deleted.       |
| PEOPLE\_CREATED             | A person has been created.           |
| PEOPLE\_UPDATED             | A person has been update.            |
| PEOPLE\_DELETED             | A person has been deleted.           |
| PEOPLE\_SETTINGS\_CREATED   | People settings have been created.   |
| PEOPLE\_SETTINGS\_UPDATED   | People settings have been created.   |
| TEAM\_CREATED               | A team has been created.             |
| TEAM\_UPDATED               | A team has been updated.             |
| TEAM\_DELETED               | A team has been deleted.             |
| TEAM\_SETTINGS\_CREATED     | Team settings have been created.     |
| TEAM\_SETTINGS\_UPDATED     | Team settings have been updated.     |
| TEAM\_MEMBER\_ADDED         | A team member has been added.        |
| TEAM\_MEMBER\_REMOVED       | A team member has been removed.      |
| LOCATION\_CREATED           | A location has been created.         |
| LOCATION\_UPDATED           | A location has been updated.         |
| LOCATION\_DELETED           | A location has been deleted.         |
| LAYER\_CREATED              | A layer has been created.            |
| LAYER\_UPDATED              | A layer has been updated.            |
| LAYER\_DELETED              | A layer has been deleted.            |
| ZONE\_CREATED               | A zone has been created.             |
| ZONE\_UPDATED               | A zone has been updated.             |
| ZONE\_DELETED               | A zone has been deleted.             |
| ROOM\_CREATED               | A room has been created.             |
| ROOM\_UPDATED               | A room has been updated.             |
| ROOM\_DELETED               | A room has been deleted.             |
| SPACE\_CREATED              | A space has been created.            |
| SPACE\_UPDATED              | A space has been updated.            |
| SPACE\_DELETED              | A space has been deleted.            |
| CLUSTER\_CREATED            | A space cluster has been created.    |
| CLUSTER\_UPDATED            | A space cluster has been updated.    |
| CLUSTER\_DELETED            | A space cluster has been deleted.    |
| CIRCULATION\_ROUTE\_CREATED | A circulation path has been created. |
| CIRCULATION\_ROUTE\_UPDATED | A circulation path has been updated. |
| CIRCULATION\_ROUTE\_DELETED | A circulation path has been deleted. |


# Versioning

The gospace AI API uses a URL-based versioning scheme. Each version is specified in the base URL, ensuring that clients can work with a stable, targeted version of the API.

```
https://api.gospace.app/api/{version}/
```

In the event of an API version reaching its deprecation phase, we will ensure to provide ample warnings and detailed communications to all affected parties.&#x20;


# Setup your development environment

Learn how to install and configure the gospace SDKs, set up your environment variables, and prepare your system for building and running API integrations.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Node.js v18 LTS or newer
* npm v9+
* A valid gospace API key

### 1. Install Node.js and npm

Check your version:

```bash
node -v
npm -v
```

If you need to upgrade, download from [nodejs.org](https://nodejs.org/) or use a version manager:

```bash
nvm install 18
nvm use 18
```

### 2. Create a New Project

```bash
mkdir gospace-dev
cd gospace-dev
npm init -y
```

### 3. Install the gospace AI SDK

```bash
npm install @gospace-ai/api
```

### 4. Store Your API Key Securely

```bash
npm install dotenv
```

Create `.env`:

```env
GOSPACE_API_KEY=your_api_key_here
```

Load it in your code:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);
```

{% endtab %}
{% endtabs %}


# Send your first API request

Make your first call to the gospace API to verify your setup, authenticate successfully, and retrieve live data from your workspace environment.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Setup Your Development Environment**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file

### 1. Install dependencies

If you haven’t already:

```bash
npm install @gospace-ai/api dotenv
```

### 2. Create a request script

Create `first-request.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  // Initialize the client with your API key
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!, {
    // Optional: use sandbox when available
    // url: "https://sandbox.api.gospace.app",
  });

  // Example: fetch supported countries from the System API
  const res = await gospace.system.getCountries();

  // Print the response data
  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Request failed:", err);
  process.exit(1);
});
```

{% hint style="info" %}
Prefer TypeScript? Run with `tsx`. Prefer JavaScript? See the JS version below.
{% endhint %}

### 3. Run the script

With TypeScript (recommended):

```bash
npx tsx first-request.ts
```

{% endtab %}
{% endtabs %}


# Create a location

Add a new location in gospace to represent a physical site or office, providing the foundation for layers, spaces, and allocations.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Setup Your Development Environment** and **Send Your First API Request**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file

### 1. Create the script

Create `create-location.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.spatial.createLocations({
    locations: [
      {
        name: "New Office",
        country: {
          country_id: "GB_ID",
          name: "United Kingdom",
          iso2: "GB",
          selected_timezone: "Europe/London",
          timezones: ["Europe/London"],
        },
        address: {
          postal_code: "EC2V 6DN",
          country_name: "UK",
          line1: "1 Example St",
          line2: "Suite 100",
        },
        coords: { latitude: 51.514, longitude: -0.093 },
        external_id: "new-office-1",
      },
    ],
  });

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Request failed:", err);
  process.exit(1);
});
```

### 2. Run the script

With TypeScript:

```bash
npx tsx create-location.ts
```

{% endtab %}
{% endtabs %}


# Create a layer

Add a new floor or layer to a location, either by uploading a floorplan file or defining it via the Spatial API, to serve as the container for rooms and spaces.

### Option A — Create a layer via the Spatial API&#x20;

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Setup Your Development Environment** and **Send Your First API Request**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file
* An existing **location\_id** (layers must be linked to a location)

#### 1) Create `create-layer.ts`

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.spatial.createLayers({
    layers: [
      {
        location_id: "loc_123",   // required: your existing location
        name: "Level 1",          // required: layer name
        // external_id: "level-1", // optional
        // ...include any other fields your schema supports
      },
    ],
  });

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Request failed:", err);
  process.exit(1);
});
```

Run:

```bash
npx tsx create-layer.ts
```

{% endtab %}
{% endtabs %}

### Option B — Create a layer by uploading a floorplan (System API)

Use a file (e.g., DXF or PDF) to seed a new layer for a location. This is an **async** process: you request a signed URL, upload the file, and the system processes it.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Setup Your Development Environment** and **Send Your First API Request**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file
* An existing **location\_id**
* A floorplan file in DXF or PDF format
* The correct **MIME type** for your file (`application/dxf` or `application/pdf`)
* Access to the file path locally to perform the signed URL upload

#### 1) Request a signed URL

```ts
// request-upload.ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const upload = await gospace.system.uploadFile({
    file_type: "application/dxf",     // or "application/pdf"
    upload_process: "floorplan",      // use the floorplan ingestion process
    binding_id: "loc_123",            // bind the upload to your location_id
  });

  console.log(JSON.stringify(upload.data, null, 2));
  // -> { signed_url, upload_id, ... }
}

main().catch(console.error);
```

Run:

```bash
npx tsx request-upload.ts
```

#### 2) Upload the file to the signed URL

```ts
// put-upload.ts
import "dotenv/config";
import { readFile } from "node:fs/promises";

async function main() {
  const signedUrl = process.env.SIGNED_URL!;     // set from step 1 output
  const filePath  = "./floorplans/level1.dxf";   // your local file path

  const body = await readFile(filePath);
  const resp = await fetch(signedUrl, {
    method: "PUT",
    headers: {
      "Content-Type": "application/dxf",         // must match file_type used in step 1
    },
    body,
  });

  if (!resp.ok) {
    throw new Error(`Upload failed: ${resp.status} ${resp.statusText}`);
  }

  console.log("Upload successful.");
}

main().catch((err) => {
  console.error("Upload failed:", err);
  process.exit(1);
});
```

Run:

```bash
SIGNED_URL="<<paste from step 1>>" npx tsx put-upload.ts
```

{% endtab %}
{% endtabs %}

### DXF File requirements

To auto-create **walls, desks/seats, rooms, clusters, zones,** and visual **areas** from a DXF, your file must follow the layer and geometry rules below.

### 1) Supported Layers & Geometry

| Layer name        | Geometry                    | Required | Purpose                                                                                                                                    |
| ----------------- | --------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `wall_perimeter`  | **Closed Polyline**         | ✅        | Outer building shell and internal voids (atria). Must be a single closed ring; holes/voids may be separate closed rings on the same layer. |
| `spaces`          | **Closed Polyline**         | ✅        | Bookable capacity units (e.g., a desk or seat). Each polygon = one space.                                                                  |
| `rooms`           | **Closed Polyline**         | ⭕        | Encloses *spaces* that belong to the same room. If omitted, spaces can exist without rooms.                                                |
| `clusters`        | **Closed Polyline**         | ⭕        | Groups of related *spaces* (e.g., team pods).                                                                                              |
| `zones`           | **Closed Polyline**         | ⭕        | Larger logical groupings across an area/floor (e.g., Zone A).                                                                              |
| `areas`           | **Polyline / Text / Block** | ⭕        | Decorative/non-bookable features: kitchens, open areas, elevators, stairs, icons. These render in UI but do not create capacity.           |
| `wall_partitions` | **Polyline**                | ⭕        | Interior partitions used for routing/visualization. Not required for area derivation.                                                      |
| `circulation`     | **Polyline**                | ⭕        | Walkways/aisles; optional hinting for pathing/analytics. Not required for ingestion.                                                       |

**Geometry rules**

* **Closed Polyline** = `LWPOLYLINE` or `POLYLINE` with the **Closed** flag set. Splines/ellipses are **not** supported for closed shapes.
* Coordinates must be **planar** (2D). Z is ignored.
* Units should be **meters** (recommended) or **millimeters**. If using mm, set scale metadata or export units consistently (see Export Checklist).
* Avoid self-intersections and duplicate vertices.
* Don’t rely on colors/linetypes for semantics; the **layer name** drives behavior.
* Blocks for semantic geometry should be **exploded** to polylines before export (icons may remain blocks on `areas`).

### 2) Hierarchy & Containment Expectations

* `spaces` **inside** a `rooms` polygon are assigned to that room.
* `rooms`/`clusters` **inside** a `zones` polygon inherit that zone.
* `wall_perimeter` encloses the usable floor boundary. **Voids** (e.g., atria) can be drawn as separate closed rings on the same layer **inside** the perimeter; these will be treated as holes.
* Overlaps:
  * `spaces` must **not** overlap each other.
  * `rooms` may touch but shouldn’t overlap.
  * `clusters` and `zones` can overlap if you intend multi-membership; otherwise, avoid overlaps.

### 3) Naming Conventions (recommended)

While not required, these help downstream mapping and reporting:

* `spaces`: add **space labels** as `MTEXT/TEXT` on the **same layer** or as block attributes (e.g., `SPACE_ID`, `TYPE`).
  * Examples: `D-001`, `S-014` (desk/seat IDs), `TYPE=desk|seat|focus`
* `rooms`: `RM-###` (e.g., `RM-201`) and optional attributes `NAME`, `TYPE` (e.g., `meeting`, `office`).
* `zones`: `ZN-A`, `ZN-B` or human-readable names.
* `clusters`: `CL-Eng-A` etc.
* Attributes are picked up if present; if not, IDs are auto-generated.

> **Tip:** If attributes are stored as block attributes, be sure the geometric boundary (closed polyline) still lives on the correct layer so it’s discoverable.

### 4) How DXF Layers Map in GoSpace

| DXF layer         | GoSpace entity             | Notes                                                                 |
| ----------------- | -------------------------- | --------------------------------------------------------------------- |
| `wall_perimeter`  | Floor boundary + voids     | Used for clipping and “inside/outside” tests.                         |
| `workpoints`      | Bookable Space (seat/desk) | One polygon → one workpoint; capacity defaults to 1 unless specified. |
| `rooms`           | Room                       | Aggregates contained spaces; can be bookable or just a container.     |
| `clusters`        | Cluster                    | Logical grouping for analytics/allocations.                           |
| `zones`           | Zone                       | High-level grouping used for planning and visibility.                 |
| `areas`           | Decorative Area            | Non-bookable; visible in maps and legends.                            |
| `wall_partitions` | Partition lines            | Rendering and optional routing hints.                                 |
| `circulation`     | Circulation paths          | Optional; used for analytics/path hints when present.                 |

### 5) Export Checklist (AutoCAD/BricsCAD/etc.)

* [ ] All bookable outlines are **Closed** Polylines on the **correct layers**.
* [ ] Units set consistently (meters preferred). If file is in **mm**, note it and keep consistent across floors.
* [ ] **Explode** blocks for walls/rooms/spaces into polylines (icons/text on `areas` may stay blocks).
* [ ] **Purge** unused layers/blocks; remove duplicate/hidden geometry.
* [ ] Ensure no stray polylines are outside `wall_perimeter`.
* [ ] No overlapping `spaces`; tiny gaps are OK.
* [ ] Save as **DXF R2018** or newer.

### 6) Common Validation Errors

* “Found open polyline on `spaces`”: close the polyline (set Closed flag).
* “Overlapping spaces detected”: adjust geometries so they don’t overlap.
* “Self-intersecting polygon”: simplify/clean the shape.
* “Missing `wall_perimeter`”: add the floor boundary as a closed polygon.
* “Unsupported entity on semantic layer”: convert to closed polylines (for rooms/spaces/zones/clusters) or polylines (for partitions/circulation).

#### Example DXF


# Create spaces

Define individual spaces such as desks, workstations, or generic areas within a layer to represent your workplace layout.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Setup Your Development Environment** and **Send Your First API Request**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file
* An existing **location\_id** and **layer\_id** (spaces belong to a layer)

### 1) Create the script

Create `create-spaces.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.spatial.createSpaces({
    spaces: [
      {
        layer_id: "layer_123",     // required: the layer this space belongs to
        name: "Desk A-1",          // required: space name
        // external_id: "desk-a-1", // optional
      },
      {
        layer_id: "layer_123",
        name: "Desk A-2",
        // external_id: "desk-a-2",
      }
    ],
  });

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Request failed:", err);
  process.exit(1);
});
```

### 2) Run the script

With TypeScript:

```bash
npx tsx create-spaces.ts
```

### 3) (Optional) Verify spaces on a layer

List spaces for your layer:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);
  const res = await gospace.spatial.getSpaces({
    layer_id: "layer_123",
    skip: 0,
    limit: 50,
  });
  console.log(JSON.stringify(res.data.spaces, null, 2));
}

main().catch(console.error);
```

Run:

```bash
npx tsx list-spaces.ts
```

{% endtab %}
{% endtabs %}


# Create rooms

Add rooms (e.g., meeting rooms, focus rooms) to your workplace layers, linked to specific spaces for usage and booking.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Setup Your Development Environment** and **Send Your First API Request**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file
* An existing **location\_id** and **layer\_id** (rooms belong to a layer)
* One or more **space\_id** values (spaces must already exist before you can assign them to a room)

***

### 1) Create the script

Create `create-room.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.spatial.createRooms({
    rooms: [
      {
        layer_id: "layer_123",          // required: the layer this room belongs to
        name: "Conference Room A",      // required: room name
        spaces: ["space_001", "space_002"], // assign existing space IDs
        // external_id: "conf-a",        // optional
      },
      {
        layer_id: "layer_123",
        name: "Focus Room 1",
        spaces: ["space_003"],          // single space assigned to the room
      }
    ],
  });

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Request failed:", err);
  process.exit(1);
});
```

***

### 2) Run the script

With TypeScript:

```bash
npx tsx create-room.ts
```

***

### 3) (Optional) Verify rooms and their spaces

List rooms for your layer and see which spaces are assigned:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);
  const res = await gospace.spatial.getRooms({
    layer_id: "layer_123",
    skip: 0,
    limit: 50,
  });
  console.log(JSON.stringify(res.data.rooms, null, 2));
}

main().catch(console.error);
```

Run:

```bash
npx tsx list-rooms.ts
```

{% endtab %}
{% endtabs %}


# Create zones

Define logical zones or neighbourhoods within your workplace to group spaces and support zone-level allocations and reporting.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Setup Your Development Environment** and **Send Your First API Request**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file
* An existing **location\_id** and **layer\_id** (zones belong to a layer)
* One or more **space\_id** values (spaces must already exist before you can assign them to a zone)

***

### 1) Create the script

Create `create-zones.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.spatial.createZones({
    zones: [
      {
        layer_id: "layer_123",             // required: the layer this zone belongs to
        name: "Quiet Zone",                // required: zone name
        spaces: ["space_101", "space_102"],// assign existing space IDs
        // external_id: "quiet-zone",       // optional
      },
      {
        layer_id: "layer_123",
        name: "Collaboration Zone",
        spaces: ["space_103", "space_104", "space_105"],
      }
    ],
  });

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Request failed:", err);
  process.exit(1);
});
```

***

### 2) Run the script

With TypeScript:

```bash
npx tsx create-zones.ts
```

***

### 3) (Optional) Verify zones and their spaces

List zones for your layer and see which spaces are assigned:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);
  const res = await gospace.spatial.getZones({
    layer_id: "layer_123",
    skip: 0,
    limit: 50,
  });
  console.log(JSON.stringify(res.data.zones, null, 2));
}

main().catch(console.error);
```

Run:

```bash
npx tsx list-zones.ts
```

{% endtab %}
{% endtabs %}


# Add directory people/teams

Populate your workplace directory with people and teams, then link people to their respective teams for allocations and analytics.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Setup Your Development Environment** and **Send Your First API Request**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file

***

### 1) Add people

Create `add-people.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.directory.createPeople({
    people: [
      { email: "alice@example.com", first_name: "Alice", last_name: "Smith" },
      { email: "bob@example.com", first_name: "Bob", last_name: "Nguyen" }
    ],
  });

  console.log(JSON.stringify(res.data.people, null, 2));
}

main().catch((err) => {
  console.error("Create people failed:", err);
  process.exit(1);
});
```

Run:

```bash
npx tsx add-people.ts
```

***

### 2) Add teams

Create `add-teams.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.directory.createTeams({
    teams: [
      { team_name: "Engineering" },
      { team_name: "People Operations" }
    ],
  });

  console.log(JSON.stringify(res.data.teams, null, 2));
}

main().catch((err) => {
  console.error("Create teams failed:", err);
  process.exit(1);
});
```

Run:

```bash
npx tsx add-teams.ts
```

***

### 3) Map people to teams (add team members)

You’ll need the `team_id` values from step 2 and the `people_id` values from step 1.

Create `add-team-members.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

const TEAM_ID = "team_123"; // replace with your real team_id

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  await gospace.directory.addTeamMembers(TEAM_ID, {
    members: [
      { people_id: "person_abc" },
      { people_id: "person_def" },
    ],
  });

  console.log("Members added.");
}

main().catch((err) => {
  console.error("Add team members failed:", err);
  process.exit(1);
});
```

Run:

```bash
npx tsx add-team-members.ts
```

{% endtab %}
{% endtabs %}


# Add historic attendance

Send past attendance records to gospace to build a history of workplace usage, enabling forecasting and AI-based optimisation.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Setup Your Development Environment** and **Send Your First API Request**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file
* Existing **location\_id** or **location\_external\_id**
* Existing **people\_id** or **people\_external\_id**

{% hint style="info" %}
Required fields per record: one of `location_id` or `location_external_id`, one of `people_id` or `people_external_id`, and `seen_at`.\
Optional fields per record: `team_id`, `first_seen_at`, `last_seen_at`, `timezone`.\
If sending **multiple batches**, you must use a **session** (see “Batching with sessions”).
{% endhint %}

### 1) Send a single batch (no session)

Create `add-historic-attendance.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

type AttendanceRecord = {
  location_id?: string;
  location_external_id?: string;
  people_id?: string;
  people_external_id?: string;
  seen_at: string;        // ISO 8601, e.g. "2025-08-11T14:30:00Z" (UTC unless timezone provided)
  team_id?: string;
  first_seen_at?: string; // ISO 8601
  last_seen_at?: string;  // ISO 8601
  timezone?: string;      // e.g., "Europe/London" (used to interpret seen_at/first/last when not UTC)
};

function toUtcIso(d: Date | string) {
  const dt = typeof d === "string" ? new Date(d) : d;
  return dt.toISOString().replace(/\.\d{3}Z$/, "Z");
}

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const occupancy: AttendanceRecord[] = [
    {
      location_id: "loc_123",
      people_external_id: "ext-person-001",
      seen_at: toUtcIso("2025-08-10T09:15:00Z"),
      team_id: "team_789",
      first_seen_at: toUtcIso("2025-08-10T09:00:00Z"),
      last_seen_at: toUtcIso("2025-08-10T17:30:00Z"),
    },
    {
      location_external_id: "ext-loc-002",
      people_id: "person_def",
      seen_at: "2025-08-10T09:15:00",
      timezone: "Europe/London",
    },
  ];

  const res = await gospace.system.createOccupancy({ occupancy });
  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Add historic attendance failed:", err);
  process.exit(1);
});
```

***

### 2) Batching with sessions (required for multi-request imports)

When importing **large datasets in multiple requests**, wrap them in a **session**:

* **First batch** must include `session_started: true`. The API returns a `session_id`.
* **Intermediate batches** must include the returned `session_id`.
* **Final batch** must include both `session_id` and `session_finished: true`.

Create `add-historic-attendance-batched.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

type AttendanceRecord = {
  location_id?: string;
  location_external_id?: string;
  people_id?: string;
  people_external_id?: string;
  seen_at: string;
  team_id?: string;
  first_seen_at?: string;
  last_seen_at?: string;
  timezone?: string;
};

function toUtcIso(d: Date | string) {
  const dt = typeof d === "string" ? new Date(d) : d;
  return dt.toISOString().replace(/\.\d{3}Z$/, "Z");
}

// Example generator of many records
function generateRecords(count: number): AttendanceRecord[] {
  const base = new Date("2025-08-10T09:00:00Z");
  return Array.from({ length: count }, (_, i) => ({
    location_id: "loc_123",
    people_id: `person_${i + 1}`,
    seen_at: toUtcIso(new Date(base.getTime() + i * 60_000)),
  }));
}

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const all = generateRecords(2500);
  const chunkSize = 500;

  let sessionId: string | undefined;

  for (let i = 0; i < all.length; i += chunkSize) {
    const chunk = all.slice(i, i + chunkSize);

    const isFirst = i === 0;
    const isLast = i + chunkSize >= all.length;

    const payload: any = { occupancy: chunk };

    if (isFirst) payload.session_started = true;
    if (sessionId) payload.session_id = sessionId;
    if (isLast) {
      payload.session_finished = true;
      if (sessionId) payload.session_id = sessionId;
    }

    const res = await gospace.system.createOccupancy(payload);

    // Capture session_id from the first response
    if (isFirst) {
      sessionId = res.data?.session_id || res.data?.session?.session_id;
      if (!sessionId) {
        throw new Error("No session_id returned from first batch");
      }
    }

    console.log(
      `Batch ${i / chunkSize + 1} sent (${chunk.length} records)${
        isFirst ? " [session_started]" : ""
      }${isLast ? " [session_finished]" : ""}`
    );
  }

  console.log("All batches completed for session:", sessionId);
}

main().catch((err) => {
  console.error("Batched historic attendance failed:", err);
  process.exit(1);
});
```

**Notes for sessions**

* Use consistent IDs/external IDs across batches.
* If a session fails mid-way, you can retry a batch with the **same `session_id`**.
* Keep batch sizes reasonable (e.g., 500–1000 records) to avoid timeouts.
* Timestamps should be ISO‑8601. Use `timezone` if not sending UTC (`Z`).
  {% endtab %}
  {% endtabs %}


# Start forecasting

Use your historic attendance data to generate AI-driven forecasts for people, teams, and locations, helping predict future space needs.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Add historic attendance** (including session finish if you batched)
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file
* At least one populated **location** with historic occupancy data

{% hint style="info" %}
**Note:** Any fields ending with `_inc` include adjustments for minimum targets, people intentions (bookings), and contingencies.
{% endhint %}

***

### 1) Trigger a forecast run

If your project is configured for automatic rebuilds, you can skip this step. Otherwise, trigger forecasting explicitly.

Create `start-forecast.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  // Kick off a forecast rebuild for a location and optional date range
  const res = await gospace.system.startForecast({
    location_id: "68499cf4af8729934aae208a",
    // Optional time window. If omitted, backend will choose sensible defaults.
    // starts_at: "2025-06-20T00:00:00Z",
    // ends_at: "2025-07-31T23:59:59Z",
    // Optional control flags
    // force_rebuild: true
  });

  console.log(JSON.stringify(res.data, null, 2));
  // Expect a job or task identifier you can poll
}

main().catch((err) => {
  console.error("Start forecast failed:", err);
  process.exit(1);
});
```

***

### 2) (Optional) Poll job status

If `startForecast` returns a job, poll until it’s complete.

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

const JOB_ID = "your_forecast_job_id";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  for (;;) {
    const status = await gospace.system.getForecastJob({ job_id: JOB_ID });
    console.log(status.data.state);
    if (status.data.state === "completed") break;
    if (status.data.state === "failed") throw new Error("Forecast job failed");
    await new Promise((r) => setTimeout(r, 3000));
  }

  console.log("Forecast ready.");
}

main().catch((e) => {
  console.error(e);
  process.exit(1);
});
```

***

### 3) Fetch forecasts

#### A) People forecast (per person, optionally scoped to team)

Create `get-people-forecast.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.system.getPeopleForecast({
    location_id: "68499cf4af8729934aae208a",
    // Optional filters:
    // people_id: "68518a559c86c18f01ee84e4",
    // team_id: "68518a549c86c18f01ee84b0",
    starts_at: "2025-06-29T23:00:00Z",
    ends_at: "2025-07-07T22:59:00Z",
    skip: 0,
    limit: 25,
  });

  // Example shape (truncated):
  // {
  //   success: true,
  //   data: { forecast: [ { starts_at, ends_at, location_id, people_id, team_id, forecasted_desk, forecasted_room, forecasted_total }, ... ] },
  //   pagination: { current_results: { from, to }, total_results },
  //   identifier: "get_forecast_successful"
  // }

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Get people forecast failed:", err);
  process.exit(1);
});
```

#### B) Team forecast (aggregated by team)

Create `get-team-forecast.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.system.getTeamForecast({
    location_id: "68499cf4af8729934aae208a",
    starts_at: "2025-06-20T23:00:00Z",
    ends_at: "2025-06-22T22:59:00Z",
    skip: 0,
    limit: 25,
  });

  // Records include *_inc fields:
  // forecasted_desks, forecasted_rooms, forecasted_total,
  // forecasted_desks_inc, forecasted_rooms_inc, forecasted_total_inc

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Get team forecast failed:", err);
  process.exit(1);
});
```

#### C) Location forecast (location‑level totals)

Create `get-location-forecast.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.system.getLocationForecast({
    location_id: "68499cf4af8729934aae208a",
    starts_at: "2025-06-20T23:00:00Z",
    ends_at: "2025-07-23T22:59:00Z",
    skip: 0,
    limit: 25,
  });

  // Records include *_inc fields for adjusted capacity planning.

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Get location forecast failed:", err);
  process.exit(1);
});
```

***

### 4) Turn forecasts into capacity requirements

#### Daily desk and room requirements (using \*\_inc)

```ts
type LocationForecast = {
  starts_at: string;
  ends_at: string;
  location_id: string;
  forecasted_desks_inc: number;
  forecasted_rooms_inc: number;
  forecasted_total_inc: number;
};

function summarizeCapacity(rows: LocationForecast[]) {
  return rows.reduce(
    (acc, r) => {
      acc.maxDesks = Math.max(acc.maxDesks, r.forecasted_desks_inc);
      acc.maxRooms = Math.max(acc.maxRooms, r.forecasted_rooms_inc);
      acc.maxTotal = Math.max(acc.maxTotal, r.forecasted_total_inc);
      return acc;
    },
    { maxDesks: 0, maxRooms: 0, maxTotal: 0 }
  );
}

// Example usage:
// const summary = summarizeCapacity(res.data.forecast);
// console.log(summary); // { maxDesks, maxRooms, maxTotal }
```

#### Aggregating per‑team to size team neighborhoods

```ts
type TeamForecast = {
  team_id: string;
  starts_at: string;
  forecasted_desks_inc: number;
};

function peakPerTeam(rows: TeamForecast[]) {
  const map = new Map<string, number>();
  for (const r of rows) {
    map.set(r.team_id, Math.max(map.get(r.team_id) ?? 0, r.forecasted_desks_inc));
  }
  return map; // team_id -> peak desks required
}
```

#### Checking person‑level confidence

Use people forecasts to validate outliers (e.g., unexpected spikes for specific individuals or teams) before making seating or room allocation changes.

***

### Tips

* Use `_inc` fields to plan **for the real world** (targets, bookings, contingencies).
* Choose consistent **day boundaries** (`starts_at`/`ends_at`) that match your business day/timezone.
* Use pagination (`skip`, `limit`) to iterate long horizons.
* Rebuild forecasts after **significant new history** or **policy changes** (e.g., new minimum targets).
  {% endtab %}
  {% endtabs %}


# Optimise your first location

Trigger the AI to evolve your location layout based on forecasts and settings, dynamically assigning spaces to teams and people.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Add historic attendance** and **Start forecasting**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file
* A **location\_id** with recent forecasts available

{% hint style="info" %}
The evolution process uses your forecasts and configuration to create dynamic **allocations** (teams/people → space types). These adjust over time (daily, weekly, bi‑weekly, monthly, quarterly) according to your setup.
{% endhint %}

***

### 1) Choose evolution settings

* **date** — the effective date (YYYY‑MM‑DD) you want to evolve.
* **disruption** — how much change you’re willing to accept:
  * `MIN` – smallest movement; preserve stability.
  * `MAX` – full optimisation; least stable.
* **run\_by\_zone** — `true` to evolve zone‑by‑zone (useful when zones are meaningful capacity containers), `false` to evolve the whole location at once.

***

### 2) Trigger evolution

Create `evolve-location.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.system.evolveLocation({
    location_id: "68824ca5369c856b7c670510",
    date: "2025-08-08",
    settings: {
      disruption: "MIN",   // 'MIN' | 'MAX'
      run_by_zone: false,  // evolve entire location in one pass
    },
  });

  // Expect: { success, data: { evolution_id, status }, identifier }
  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Trigger evolve failed:", err);
  process.exit(1);
});
```

***

### 3) Poll status until completion

Create `evolve-status.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

const EVOLUTION_ID = process.env.EVOLUTION_ID!; // set from step 2 response

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  for (;;) {
    const res = await gospace.system.getEvolutionStatus({
      evolution_id: EVOLUTION_ID,
    });

    const status = res.data.status; // 'created' | 'processing' | 'no_execution' | 'successful' | 'failed'
    console.log(`[evolve] status: ${status}`);

    if (status === "successful" || status === "no_execution") break;
    if (status === "failed") throw new Error("Evolution failed");
    await new Promise((r) => setTimeout(r, 3000));
  }

  console.log("Evolution complete.");
}

main().catch((err) => {
  console.error("Check evolve status failed:", err);
  process.exit(1);
});
```

Run:

```bash
EVOLUTION_ID="94289524-04ac-44d3-8f05-45b8a937f663" npx tsx evolve-status.ts
```

***

### 4) Interpreting the results

After a **successful** evolution:

* The system produces **allocations** that map **teams/people** to **space types** (e.g., desks, rooms) for the requested date.
* Allocations are driven by your **forecast** (including `*_inc` adjustments for minimum targets, bookings/intentions, and contingencies) and your **settings** (`disruption`, `run_by_zone`).
* These allocations **grow/shrink dynamically** as forecasts change and as you re‑run evolution on your chosen cadence (daily/weekly/bi‑weekly/monthly/quarterly).

{% hint style="info" %}
If your evolution returns **`no_execution`**, it means there were no material changes to apply given the current forecasts and settings. Consider increasing `disruption`, adjusting forecasts/targets, or running by zones.
{% endhint %}
{% endtab %}
{% endtabs %}


# Recommended allocations

Retrieve and review AI-generated allocations at the people, team, or zone level for each day, and optionally adjust them manually.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Start forecasting** and **Optimise your first location (Evolve)**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file
* A **location\_id** with at least one **successful** evolution

{% hint style="info" %}
Allocations can be **zone/neighbourhood level**, **team level**, or **people level**.\
You can fetch recommendations with `getAllocations()` and optionally override them with `createAllocations()`, `updateAllocations()`, and `deleteAllocations()`.
{% endhint %}

***

### Allocation record shape

Depending on allocation type, fields will be populated as follows:

```ts
type Allocation = {
  starts_at: string;         // ISO timestamp (interval start)
  ends_at: string;           // ISO timestamp (interval end)
  location_id: string;
  location_name: string;
  layer_id: string;          // floor/layer allocated to
  layer_name: string;
  spaces: string[];          // array of space IDs allocated
  type: string;              // "SPACE" or "ROOM" (type of allocation)
  people_id?: string;        // present for people allocations
  team_id?: string;          // present for team allocations (or people with team assignment)
  room_id?: string;          // present only on room allocations
};
```

***

### 1) Get recommended allocations for a location (day-by-day)

Create `get-allocations.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.system.getAllocations({
    location_id: "68824ca5369c856b7c670510",
    starts_at: "2025-07-01T00:00:00Z",
    ends_at:   "2025-07-31T23:59:59Z",
    // Optional filters:
    // team_id: "68518a549c86c18f01ee84a3",
    // people_id: "68518a559c86c18f01ee84e4",
    // layer_id: "layer_123",
    // type: "ROOM" | "SPACE",
    skip: 0,
    limit: 250,
  });

  const allocations = res.data.allocations as Allocation[];
  console.log(JSON.stringify(allocations.slice(0, 5), null, 2));
}

main().catch((err) => {
  console.error("getAllocations failed:", err);
  process.exit(1);
});
```

***

### 2) Summarise allocations per day

```ts
type DaySummary = { date: string; desks: number; rooms: number; total: number };

function dayKey(a: Allocation) {
  return (a.starts_at ?? "").slice(0, 10);
}

export function summarizeByDay(rows: Allocation[]): DaySummary[] {
  const map = new Map<string, DaySummary>();
  for (const r of rows) {
    const key = dayKey(r);
    if (!map.has(key)) map.set(key, { date: key, desks: 0, rooms: 0, total: 0 });
    const entry = map.get(key)!;
    if (r.type === "SPACE") entry.desks += r.spaces.length;
    if (r.type === "ROOM") entry.rooms += (r.spaces?.length || 1);
    entry.total = entry.desks + entry.rooms;
  }
  return Array.from(map.values()).sort((a, b) => a.date.localeCompare(b.date));
}
```

***

### 3) Inspect by level: zone/neighbourhood, team, people

```ts
// Zone/neighbourhood-level: no people_id, no team_id
const zoneLevel = allocations.filter(a => !a.people_id && !a.team_id);

// Team-level
const teamLevel = allocations.filter(a => !!a.team_id && !a.people_id);

// People-level
const peopleLevel = allocations.filter(a => !!a.people_id);
```

You can also filter by `layer_id` to analyse a specific floor, or by `type` to focus on **ROOM** vs **SPACE** allocations.

***

### 4) Make manual adjustments (create/update/delete)

You might want to tweak AI recommendations—for example, **swap spaces** between two teams or assign a specific person to a different desk on a given day.

#### A) Create manual allocations

```ts
// create-manual-allocation.ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.system.createAllocations({
    allocations: [
      {
        starts_at: "2025-07-15T00:00:00Z",
        ends_at:   "2025-07-15T23:59:59Z",
        location_id: "68824ca5369c856b7c670510",
        location_name: "London HQ",     // if supported/returned
        layer_id: "layer_123",
        layer_name: "Level 1",
        type: "SPACE",
        team_id: "68518a549c86c18f01ee84a3",
        spaces: ["space_A1", "space_A2"],
      },
    ],
  });

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((e) => {
  console.error("createAllocations failed:", e);
  process.exit(1);
});
```

#### B) Update allocations (e.g., swap spaces)

```ts
// swap-spaces.ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

// Helper: get the first matching allocation for a team and day
async function getTeamAllocationForDay(
  gospace: GospaceAI,
  location_id: string,
  team_id: string,
  date: string
) {
  const res = await gospace.system.getAllocations({
    location_id,
    team_id,
    starts_at: `${date}T00:00:00Z`,
    ends_at:   `${date}T23:59:59Z`,
    limit: 1,
  });
  return (res.data.allocations ?? [])[0] as Allocation | undefined;
}

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);
  const location_id = "68824ca5369c856b7c670510";
  const date = "2025-07-15";

  const teamA = "team_A";
  const teamB = "team_B";

  const allocA = await getTeamAllocationForDay(gospace, location_id, teamA, date);
  const allocB = await getTeamAllocationForDay(gospace, location_id, teamB, date);

  if (!allocA || !allocB) throw new Error("Missing allocations for one or both teams");

  // Swap a single space between teams (example)
  const [spaceFromA] = allocA.spaces;
  const [spaceFromB] = allocB.spaces;

  const updatedA = { ...allocA, spaces: [spaceFromB, ...allocA.spaces.slice(1)] };
  const updatedB = { ...allocB, spaces: [spaceFromA, ...allocB.spaces.slice(1)] };

  // Your API may require allocation IDs; include them if provided by getAllocations().
  const res = await gospace.system.updateAllocations({
    allocations: [updatedA, updatedB],
  });

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((e) => {
  console.error("updateAllocations failed:", e);
  process.exit(1);
});
```

#### C) Delete allocations

```ts
// delete-allocations.ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  // First, fetch the allocations you intend to remove
  const res = await gospace.system.getAllocations({
    location_id: "68824ca5369c856b7c670510",
    starts_at: "2025-07-15T00:00:00Z",
    ends_at:   "2025-07-15T23:59:59Z",
    team_id: "68518a549c86c18f01ee84a3",
    limit: 50,
  });

  // Assume each allocation has an `_id` or `allocation_id` field
  const toDelete = (res.data.allocations ?? [])
    .map((a: any) => ({ allocation_id: a._id || a.allocation_id }))
    .filter(x => !!x.allocation_id);

  if (toDelete.length === 0) {
    console.log("Nothing to delete.");
    return;
  }

  const del = await gospace.system.deleteAllocations({ allocations: toDelete });
  console.log(JSON.stringify(del.data, null, 2));
}

main().catch((e) => {
  console.error("deleteAllocations failed:", e);
  process.exit(1);
});
```

***

### 5) Common patterns

* **Paginate** long ranges with `skip`/`limit`.
* **Filter** by `team_id`, `people_id`, `layer_id`, `type` to narrow scope.
* **Respect intervals** — allocations are effective from `starts_at` to `ends_at`.
* **Manual overrides** — use create/update/delete to pin critical changes (e.g., VIP desks, event days).
* **Audit your swaps** — log original vs. updated `spaces` arrays to keep a trail of changes.
  {% endtab %}
  {% endtabs %}


# Create connections and label space

Set positive or negative relationships between people, teams, and spaces, and tag spaces with labels to guide AI allocation decisions.

{% tabs %}
{% tab title="Node.js" %}

### Prerequisites

* Completed **Setup Your Development Environment** and **Send Your First API Request**
* Node.js v18+ and npm v9+
* A valid gospace API key in your `.env` file
* Known IDs (or external IDs) for the entities you want to relate

{% hint style="info" %}
**Allowed connection entity types:** `TEAM`, `PERSON`, `LABEL`, `SPACE`, `ROOM`, `ZONE`.\
Strength is an integer (e.g., **-100 → 100**). Negative is an *avoid* signal; positive is a *prefer* signal.
{% endhint %}

***

### 1) Create connections (positive & negative)

Create `create-connections.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.connections.createConnections({
    connections: [
      // Positive: person prefers to sit near a team
      {
        strength: 75,
        connection_from_entity: {
          connection_entity_id: "person_123",
          connection_entity_type: "PERSON",
          connection_entity_data: {
            first_name: "Alice",
            last_name: "Smith",
            email: "alice@example.com",
            person_id: "person_123",
            external_id: "ext-alice",
          },
        },
        connection_to_entity: {
          connection_entity_id: "team_456",
          connection_entity_type: "TEAM",
          connection_entity_data: {
            team_name: "Engineering",
            team_id: "team_456",
            external_id: "ext-team-eng",
          },
        },
      },

      // Negative: team should avoid a particular room
      {
        strength: -50,
        connection_from_entity: {
          connection_entity_id: "team_456",
          connection_entity_type: "TEAM",
          connection_entity_data: {
            team_name: "Engineering",
            team_id: "team_456",
          },
        },
        connection_to_entity: {
          connection_entity_id: "room_789",
          connection_entity_type: "ROOM",
          connection_entity_data: {
            room_name: "Conference Room A",
            room_id: "room_789",
          },
        },
      },
    ],
  });

  console.log(JSON.stringify(res.data.connections, null, 2));
}

main().catch((err) => {
  console.error("Create connections failed:", err);
  process.exit(1);
});
```

***

### 2) Query connections (by entity, type, or external\_id)

Create `get-connections.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  // Examples of useful filters:
  const res = await gospace.connections.getConnections({
    // connection_id: "conn_123", // exact connection
    connection_entity_id: "team_456", // find all touching this entity
    connection_entity_type: "TEAM",   // TEAM | PERSON | LABEL | SPACE | ROOM | ZONE
    // external_id: "ext-alice",     // match external_id of PERSON/TEAM in from/to entities
    skip: 0,
    limit: 25,
    sort: "strength",
    order: "desc",
  });

  console.log(JSON.stringify(res.data.connections, null, 2));
}

main().catch((err) => {
  console.error("Get connections failed:", err);
  process.exit(1);
});
```

***

### 3) Update connection strength / endpoints

Create `update-connections.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.connections.updateConnections({
    connections: [
      {
        _id: "conn_abc123",     // the connection to update
        strength: 90,           // new strength (e.g., boost preference)
        connection_from_entity: {
          connection_entity_id: "person_123",
          connection_entity_type: "PERSON",
        },
        connection_to_entity: {
          connection_entity_id: "team_456",
          connection_entity_type: "TEAM",
        },
      },
    ],
  });

  console.log(JSON.stringify(res.data.connections, null, 2));
}

main().catch((err) => {
  console.error("Update connections failed:", err);
  process.exit(1);
});
```

***

### 4) Delete connections

Create `delete-connections.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.connections.deleteConnections({
    connections: [
      { connection_id: "conn_abc123" },
      { connection_id: "conn_def456" },
    ],
  });

  console.log(JSON.stringify(res.data, null, 2));
}

main().catch((err) => {
  console.error("Delete connections failed:", err);
  process.exit(1);
});
```

***

### 5) Create labels (for tagging entities)

Create `create-labels.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.connections.createLabels({
    labels: [
      {
        name: "Quiet",
        type: "category",
        details: { color: "blue", description: "Quiet working area" },
      },
      {
        name: "Exec",
        type: "tag",
        details: { color: "gold", description: "Executive seating" },
      },
    ],
  });

  console.log(JSON.stringify(res.data.labels, null, 2));
}

main().catch((err) => {
  console.error("Create labels failed:", err);
  process.exit(1);
});
```

***

### 6) Label space (map a label to SPACE/ROOM/ZONE/TEAM/PERSON)

Create `map-labels.ts`:

```ts
import "dotenv/config";
import GospaceAI from "@gospace-ai/api";

async function main() {
  const gospace = new GospaceAI(process.env.GOSPACE_API_KEY!);

  const res = await gospace.connections.createLabelMappings({
    mappings: [
      // Label a space as "Quiet"
      {
        label_id: "label_quiet",
        entity_id: "space_101",
        entity_type: "SPACE", // TEAM | PERSON | LABEL | SPACE | ROOM | ZONE
        details: { applied_at: new Date().toISOString() },
      },

      // Label a room as "Exec"
      {
        label_id: "label_exec",
        entity_id: "room_789",
        entity_type: "ROOM",
        details: { applied_at: new Date().toISOString() },
      },
    ],
  });

  console.log(JSON.stringify(res.data.mappings, null, 2));
}

main().catch((err) => {
  console.error("Create label mappings failed:", err);
  process.exit(1);
});
```

***

### 7) Query & manage label mappings

**Get mappings** (filter by label, entity, type, or external\_id):

```ts
const mappings = await gospace.connections.getLabelMappings({
  // mapping_id: "map_123",
  label_id: "label_quiet",
  entity_type: "SPACE",
  skip: 0,
  limit: 25,
  sort: "label_id",
  order: "asc",
});
console.log(JSON.stringify(mappings.data.mappings, null, 2));
```

**Update mappings:**

```ts
await gospace.connections.updateLabelMappings({
  mappings: [
    {
      _id: "map_123",
      label_id: "label_quiet",
      entity_id: "space_101",
      entity_type: "SPACE",
      details: { applied_at: new Date().toISOString(), note: "Near windows" },
    },
  ],
});
```

**Delete mappings:**

```ts
await gospace.connections.deleteLabelMappings({
  mappings: [{ mapping_id: "map_123" }],
});
```

***

### Tips & patterns

* **Model behaviour:**
  * Positive connections (`> 0`) indicate affinity or proximity preference.
  * Negative connections (`< 0`) indicate separation or avoidance.
* **Granularity:**
  * Use **people ↔ team** for day‑to‑day seating preferences.
  * Use **team ↔ room/zone/space** for capacity and neighborhood tuning.
  * Use **labels** to tag assets (e.g., “Quiet”, “Client‑facing”, “Accessible”).
* **Searchability:**
  * Use `external_id` on people/teams, then query `getConnections` with `external_id` to keep your system in sync.
* **Governance:**
  * Keep connection strengths within a standard range (e.g., -100, -50, -25, 25, 50, 100) so they’re interpretable.
  * Periodically audit old connections and label mappings to avoid stale constraints.
    {% endtab %}
    {% endtabs %}


# Partner API

## GET /organisations

> List child organisations owned by the authenticated partner. Deleted organisations are excluded by default.

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/partner/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"PartnerOrganisation":{"type":"object","properties":{"organisation_id":{"type":"string","description":"MongoDB identifier for the organisation."},"organisation_key":{"type":"string","description":"gospace organisation key used for tenant context."},"organisation_name":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"division_key":{"type":"string","description":"Initial division key created with the organisation."},"deleted_at":{"type":"string","format":"date-time","nullable":true},"partner_external_id":{"type":"string","description":"Optional partner-side identifier for this organisation."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["organisation_id","organisation_key","organisation_name","country","created_at","updated_at"]},"ErrorEnvelope":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string"},"error":{"type":"object","additionalProperties":true},"violation":{"type":"object","additionalProperties":true}},"required":["success","identifier"]}},"responses":{"Unauthorised":{"description":"Missing, malformed, disabled, deleted, or non-partner API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"paths":{"/organisations":{"get":{"operationId":"listPartnerOrganisations","description":"List child organisations owned by the authenticated partner. Deleted organisations are excluded by default.","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}},{"name":"include_deleted","in":"query","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Organisations listed.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string","enum":["partner_organisations_listed"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/PartnerOrganisation"}}},"required":["success","identifier","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorised"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## POST /organisations

> Create a child organisation owned by the authenticated partner. The response includes one newly generated standard organisation API key. Use that child organisation API key for data writes into the child organisation.

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/partner/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"CreatePartnerOrganisationRequest":{"type":"object","properties":{"organisation_name":{"type":"string","minLength":1},"country":{"type":"string","minLength":2,"maxLength":2,"description":"ISO 3166-1 alpha-2 country code."},"division_timezone":{"type":"string","minLength":1},"division_name":{"type":"string","minLength":1,"description":"Optional name for the initial division. Defaults to `organisation_name`."},"partner_external_id":{"type":"string","minLength":1,"description":"Optional partner-side identifier for this organisation."}},"required":["organisation_name","country","division_timezone"]},"PartnerOrganisationWithApiKey":{"allOf":[{"$ref":"#/components/schemas/PartnerOrganisation"},{"type":"object","properties":{"organisation_api_key":{"type":"string","description":"Newly generated standard organisation API key. Returned only when the organisation is created."}},"required":["organisation_api_key"]}]},"PartnerOrganisation":{"type":"object","properties":{"organisation_id":{"type":"string","description":"MongoDB identifier for the organisation."},"organisation_key":{"type":"string","description":"gospace organisation key used for tenant context."},"organisation_name":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"division_key":{"type":"string","description":"Initial division key created with the organisation."},"deleted_at":{"type":"string","format":"date-time","nullable":true},"partner_external_id":{"type":"string","description":"Optional partner-side identifier for this organisation."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["organisation_id","organisation_key","organisation_name","country","created_at","updated_at"]},"ErrorEnvelope":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string"},"error":{"type":"object","additionalProperties":true},"violation":{"type":"object","additionalProperties":true}},"required":["success","identifier"]}},"responses":{"Unauthorised":{"description":"Missing, malformed, disabled, deleted, or non-partner API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"paths":{"/organisations":{"post":{"operationId":"createPartnerOrganisation","description":"Create a child organisation owned by the authenticated partner. The response includes one newly generated standard organisation API key. Use that child organisation API key for data writes into the child organisation.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePartnerOrganisationRequest"}}}},"responses":{"200":{"description":"Organisation created.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string","enum":["partner_organisation_created"]},"data":{"$ref":"#/components/schemas/PartnerOrganisationWithApiKey"}},"required":["success","identifier","data"]}}}},"400":{"description":"Bad Request - Invalid request body."},"401":{"$ref":"#/components/responses/Unauthorised"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## GET /organisations/{organisation\_id}

> Retrieve one child organisation by MongoDB organisation ID. Organisations not owned by the authenticated partner are rejected.

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/partner/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"PartnerOrganisation":{"type":"object","properties":{"organisation_id":{"type":"string","description":"MongoDB identifier for the organisation."},"organisation_key":{"type":"string","description":"gospace organisation key used for tenant context."},"organisation_name":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"division_key":{"type":"string","description":"Initial division key created with the organisation."},"deleted_at":{"type":"string","format":"date-time","nullable":true},"partner_external_id":{"type":"string","description":"Optional partner-side identifier for this organisation."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["organisation_id","organisation_key","organisation_name","country","created_at","updated_at"]},"ErrorEnvelope":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string"},"error":{"type":"object","additionalProperties":true},"violation":{"type":"object","additionalProperties":true}},"required":["success","identifier"]}},"responses":{"Unauthorised":{"description":"Missing, malformed, disabled, deleted, or non-partner API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"PartnerOrganisationNotFound":{"description":"Organisation not found or not owned by the authenticated partner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"paths":{"/organisations/{organisation_id}":{"get":{"operationId":"getPartnerOrganisation","description":"Retrieve one child organisation by MongoDB organisation ID. Organisations not owned by the authenticated partner are rejected.","parameters":[{"name":"organisation_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-f\\\\d]{24}$"}},{"name":"include_deleted","in":"query","required":false,"schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"Organisation found.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string","enum":["partner_organisation_found"]},"data":{"$ref":"#/components/schemas/PartnerOrganisation"}},"required":["success","identifier","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorised"},"404":{"$ref":"#/components/responses/PartnerOrganisationNotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## DELETE /organisations/{organisation\_id}

> Soft-delete an owned child organisation and revoke its organisation API keys. If the deleted target is itself a partner organisation, child organisations linked to that partner are also soft-deleted and their keys revoked.

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/partner/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"DeletePartnerOrganisationResult":{"type":"object","properties":{"organisation_ids":{"type":"array","description":"Organisation IDs that were soft-deleted.","items":{"type":"string"}}},"required":["organisation_ids"]},"ErrorEnvelope":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string"},"error":{"type":"object","additionalProperties":true},"violation":{"type":"object","additionalProperties":true}},"required":["success","identifier"]}},"responses":{"Unauthorised":{"description":"Missing, malformed, disabled, deleted, or non-partner API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"PartnerOrganisationNotFound":{"description":"Organisation not found or not owned by the authenticated partner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"paths":{"/organisations/{organisation_id}":{"delete":{"operationId":"deletePartnerOrganisation","description":"Soft-delete an owned child organisation and revoke its organisation API keys. If the deleted target is itself a partner organisation, child organisations linked to that partner are also soft-deleted and their keys revoked.","parameters":[{"name":"organisation_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-f\\\\d]{24}$"}}],"responses":{"200":{"description":"Organisation deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string","enum":["partner_organisation_deleted"]},"data":{"$ref":"#/components/schemas/DeletePartnerOrganisationResult"}},"required":["success","identifier","data"]}}}},"401":{"$ref":"#/components/responses/Unauthorised"},"404":{"$ref":"#/components/responses/PartnerOrganisationNotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## PATCH /organisations/{organisation\_id}

> Update safe partner-facing organisation metadata only. Fields such as \`country\`, \`location\`, \`shard\_key\`, \`organisation\_key\`, \`divisions\`, \`is\_partner\`, and ownership fields cannot be updated through this API.

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/partner/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"UpdatePartnerOrganisationRequest":{"type":"object","additionalProperties":false,"properties":{"organisation_name":{"type":"string","minLength":1},"partner_external_id":{"type":"string","minLength":1}},"minProperties":1},"PartnerOrganisation":{"type":"object","properties":{"organisation_id":{"type":"string","description":"MongoDB identifier for the organisation."},"organisation_key":{"type":"string","description":"gospace organisation key used for tenant context."},"organisation_name":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"division_key":{"type":"string","description":"Initial division key created with the organisation."},"deleted_at":{"type":"string","format":"date-time","nullable":true},"partner_external_id":{"type":"string","description":"Optional partner-side identifier for this organisation."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["organisation_id","organisation_key","organisation_name","country","created_at","updated_at"]},"ErrorEnvelope":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string"},"error":{"type":"object","additionalProperties":true},"violation":{"type":"object","additionalProperties":true}},"required":["success","identifier"]}},"responses":{"Unauthorised":{"description":"Missing, malformed, disabled, deleted, or non-partner API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"PartnerOrganisationNotFound":{"description":"Organisation not found or not owned by the authenticated partner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"paths":{"/organisations/{organisation_id}":{"patch":{"operationId":"updatePartnerOrganisation","description":"Update safe partner-facing organisation metadata only. Fields such as `country`, `location`, `shard_key`, `organisation_key`, `divisions`, `is_partner`, and ownership fields cannot be updated through this API.","parameters":[{"name":"organisation_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-f\\\\d]{24}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpdatePartnerOrganisationRequest"}}}},"responses":{"200":{"description":"Organisation updated.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string","enum":["partner_organisation_updated"]},"data":{"$ref":"#/components/schemas/PartnerOrganisation"}},"required":["success","identifier","data"]}}}},"400":{"description":"Bad Request - Invalid request body."},"401":{"$ref":"#/components/responses/Unauthorised"},"404":{"$ref":"#/components/responses/PartnerOrganisationNotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```

## GET /organisations/{organisation\_id}/usage

> Retrieve storage and API request usage for an owned child organisation for a single month. Monthly totals are returned when available; otherwise daily storage and API usage records are aggregated.

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/partner/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"PartnerUsage":{"type":"object","properties":{"organisation_id":{"type":"string"},"organisation_key":{"type":"string"},"usage_month":{"type":"string","pattern":"^\\\\d{4}-\\\\d{2}$"},"timezone":{"type":"string"},"total_bytes":{"type":"number","default":0},"total_documents":{"type":"number","default":0},"days_recorded":{"type":"number","default":0},"peak_total_bytes":{"type":"number","default":0},"peak_total_documents":{"type":"number","default":0},"total_requests":{"type":"number","default":0},"api_days_recorded":{"type":"number","default":0},"peak_total_requests":{"type":"number","default":0}},"required":["organisation_id","organisation_key","usage_month","timezone","total_bytes","total_documents","days_recorded","peak_total_bytes","peak_total_documents","total_requests","api_days_recorded","peak_total_requests"]},"ErrorEnvelope":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string"},"error":{"type":"object","additionalProperties":true},"violation":{"type":"object","additionalProperties":true}},"required":["success","identifier"]}},"responses":{"Unauthorised":{"description":"Missing, malformed, disabled, deleted, or non-partner API key.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"PartnerOrganisationNotFound":{"description":"Organisation not found or not owned by the authenticated partner.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"InternalServerError":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}},"paths":{"/organisations/{organisation_id}/usage":{"get":{"operationId":"getPartnerOrganisationUsage","description":"Retrieve storage and API request usage for an owned child organisation for a single month. Monthly totals are returned when available; otherwise daily storage and API usage records are aggregated.","parameters":[{"name":"organisation_id","in":"path","required":true,"schema":{"type":"string","pattern":"^[a-f\\\\d]{24}$"}},{"name":"usage_month","in":"query","required":true,"schema":{"type":"string","pattern":"^\\\\d{4}-\\\\d{2}$"}}],"responses":{"200":{"description":"Usage found.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string","enum":["partner_organisation_usage_found"]},"data":{"$ref":"#/components/schemas/PartnerUsage"}},"required":["success","identifier","data"]}}}},"400":{"description":"Bad Request - Invalid usage month."},"401":{"$ref":"#/components/responses/Unauthorised"},"404":{"$ref":"#/components/responses/PartnerOrganisationNotFound"},"500":{"$ref":"#/components/responses/InternalServerError"}}}}}}
```


# Models

## The PartnerOrganisation object

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"components":{"schemas":{"PartnerOrganisation":{"type":"object","properties":{"organisation_id":{"type":"string","description":"MongoDB identifier for the organisation."},"organisation_key":{"type":"string","description":"gospace organisation key used for tenant context."},"organisation_name":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"division_key":{"type":"string","description":"Initial division key created with the organisation."},"deleted_at":{"type":"string","format":"date-time","nullable":true},"partner_external_id":{"type":"string","description":"Optional partner-side identifier for this organisation."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["organisation_id","organisation_key","organisation_name","country","created_at","updated_at"]}}}}
```

## The PartnerOrganisationWithApiKey object

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"components":{"schemas":{"PartnerOrganisationWithApiKey":{"allOf":[{"$ref":"#/components/schemas/PartnerOrganisation"},{"type":"object","properties":{"organisation_api_key":{"type":"string","description":"Newly generated standard organisation API key. Returned only when the organisation is created."}},"required":["organisation_api_key"]}]},"PartnerOrganisation":{"type":"object","properties":{"organisation_id":{"type":"string","description":"MongoDB identifier for the organisation."},"organisation_key":{"type":"string","description":"gospace organisation key used for tenant context."},"organisation_name":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"division_key":{"type":"string","description":"Initial division key created with the organisation."},"deleted_at":{"type":"string","format":"date-time","nullable":true},"partner_external_id":{"type":"string","description":"Optional partner-side identifier for this organisation."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"required":["organisation_id","organisation_key","organisation_name","country","created_at","updated_at"]}}}}
```

## The CreatePartnerOrganisationRequest object

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"components":{"schemas":{"CreatePartnerOrganisationRequest":{"type":"object","properties":{"organisation_name":{"type":"string","minLength":1},"country":{"type":"string","minLength":2,"maxLength":2,"description":"ISO 3166-1 alpha-2 country code."},"division_timezone":{"type":"string","minLength":1},"division_name":{"type":"string","minLength":1,"description":"Optional name for the initial division. Defaults to `organisation_name`."},"partner_external_id":{"type":"string","minLength":1,"description":"Optional partner-side identifier for this organisation."}},"required":["organisation_name","country","division_timezone"]}}}}
```

## The UpdatePartnerOrganisationRequest object

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"components":{"schemas":{"UpdatePartnerOrganisationRequest":{"type":"object","additionalProperties":false,"properties":{"organisation_name":{"type":"string","minLength":1},"partner_external_id":{"type":"string","minLength":1}},"minProperties":1}}}}
```

## The PartnerUsage object

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"components":{"schemas":{"PartnerUsage":{"type":"object","properties":{"organisation_id":{"type":"string"},"organisation_key":{"type":"string"},"usage_month":{"type":"string","pattern":"^\\\\d{4}-\\\\d{2}$"},"timezone":{"type":"string"},"total_bytes":{"type":"number","default":0},"total_documents":{"type":"number","default":0},"days_recorded":{"type":"number","default":0},"peak_total_bytes":{"type":"number","default":0},"peak_total_documents":{"type":"number","default":0},"total_requests":{"type":"number","default":0},"api_days_recorded":{"type":"number","default":0},"peak_total_requests":{"type":"number","default":0}},"required":["organisation_id","organisation_key","usage_month","timezone","total_bytes","total_documents","days_recorded","peak_total_bytes","peak_total_documents","total_requests","api_days_recorded","peak_total_requests"]}}}}
```

## The DeletePartnerOrganisationResult object

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"components":{"schemas":{"DeletePartnerOrganisationResult":{"type":"object","properties":{"organisation_ids":{"type":"array","description":"Organisation IDs that were soft-deleted.","items":{"type":"string"}}},"required":["organisation_ids"]}}}}
```

## The ErrorEnvelope object

```json
{"openapi":"3.0.3","info":{"title":"Partner API","version":"1.0"},"components":{"schemas":{"ErrorEnvelope":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string"},"error":{"type":"object","additionalProperties":true},"violation":{"type":"object","additionalProperties":true}},"required":["success","identifier"]}}}}
```


# Authentication API

## POST /sdk/token

> Generates an SDK access token for the provided email.

```json
{"openapi":"3.0.3","info":{"title":"Authentication API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/authentication/v1","description":"UAT environment for SDK token generation"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/sdk/token":{"post":{"description":"Generates an SDK access token for the provided email.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"The email address of the user requesting the token."},"expiry_minutes":{"type":"integer","description":"Optional token lifetime in minutes (default 60).","default":60,"minimum":1}},"required":["email"]}}}},"responses":{"200":{"description":"Successfully generated SDK access token.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the request was successful."},"data":{"type":"object","properties":{"access_token":{"type":"string","description":"JWT access token for SDK authentication."}},"required":["access_token"]},"identifier":{"type":"string","description":"Identifier for the response, e.g., 'auth_successful'."}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request - Invalid input or missing required fields.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the request was successful."},"error":{"type":"object","properties":{"code":{"type":"integer","description":"HTTP status code."},"message":{"type":"string","description":"Error message describing the issue."}},"required":["code","message"]},"identifier":{"type":"string","description":"Identifier for the error, e.g., 'bad_request'."}},"required":["success","error","identifier"]}}}},"401":{"description":"Unauthorized - Invalid or missing API key.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the request was successful."},"error":{"type":"object","properties":{"code":{"type":"integer","description":"HTTP status code."},"message":{"type":"string","description":"Error message describing the issue."}},"required":["code","message"]},"identifier":{"type":"string","description":"Identifier for the error, e.g., 'unauthorised'."}},"required":["success","error","identifier"]}}}},"500":{"description":"Internal Server Error.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Indicates if the request was successful."},"error":{"type":"object","properties":{"code":{"type":"integer","description":"HTTP status code."},"message":{"type":"string","description":"Error message describing the issue."}},"required":["code","message"]},"identifier":{"type":"string","description":"Identifier for the error, e.g., 'internal_server_error'."}},"required":["success","error","identifier"]}}}}}}}}}
```


# Scenarios API

coming soon - create digital twins to test "What if?" scenarios

## GET /scenarios

> Retrieve scenarios. The \`scenario\_id\` can be used as \`x-configuiration-key\` on other public APIs.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"Scenario":{"type":"object","properties":{"_id":{"type":"string"},"scenario_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"mode":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"object","additionalProperties":true}},"changes":{"type":"boolean"},"unsaved_changes":{"type":"boolean"},"created_by":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_by":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"archived_by":{"type":"string"},"archived_at":{"type":"string","format":"date-time"},"deleted_by":{"type":"string"},"deleted_at":{"type":"string","format":"date-time"},"active_admins":{"type":"array","items":{"type":"object","additionalProperties":true}},"services_publishing":{"type":"object","additionalProperties":true}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/scenarios":{"get":{"operationId":"getScenarios","description":"Retrieve scenarios. The `scenario_id` can be used as `x-configuiration-key` on other public APIs.","parameters":[{"name":"scenario_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"mode","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"scenarios":{"type":"array","items":{"$ref":"#/components/schemas/Scenario"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"identifier":{"type":"string"}}}}}}}}}}}
```

## POST /scenarios

> Create a new scenario.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"Scenario":{"type":"object","properties":{"_id":{"type":"string"},"scenario_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"mode":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"object","additionalProperties":true}},"changes":{"type":"boolean"},"unsaved_changes":{"type":"boolean"},"created_by":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_by":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"archived_by":{"type":"string"},"archived_at":{"type":"string","format":"date-time"},"deleted_by":{"type":"string"},"deleted_at":{"type":"string","format":"date-time"},"active_admins":{"type":"array","items":{"type":"object","additionalProperties":true}},"services_publishing":{"type":"object","additionalProperties":true}},"additionalProperties":true}}},"paths":{"/scenarios":{"post":{"operationId":"createScenario","description":"Create a new scenario.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"mode":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"object","additionalProperties":true}}},"required":["name","mode"]}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Scenario"},"identifier":{"type":"string"}}}}}}}}}}}
```

## GET /scenarios/{scenario\_id}

> Retrieve a scenario by ID.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"Scenario":{"type":"object","properties":{"_id":{"type":"string"},"scenario_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"mode":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"object","additionalProperties":true}},"changes":{"type":"boolean"},"unsaved_changes":{"type":"boolean"},"created_by":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_by":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"archived_by":{"type":"string"},"archived_at":{"type":"string","format":"date-time"},"deleted_by":{"type":"string"},"deleted_at":{"type":"string","format":"date-time"},"active_admins":{"type":"array","items":{"type":"object","additionalProperties":true}},"services_publishing":{"type":"object","additionalProperties":true}},"additionalProperties":true}}},"paths":{"/scenarios/{scenario_id}":{"get":{"operationId":"getScenarioById","description":"Retrieve a scenario by ID.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"allOf":[{"$ref":"#/components/schemas/Scenario"}],"nullable":true},"identifier":{"type":"string"}}}}}}}}}}}
```

## PUT /scenarios/{scenario\_id}

> Update a scenario.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"Scenario":{"type":"object","properties":{"_id":{"type":"string"},"scenario_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"mode":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"object","additionalProperties":true}},"changes":{"type":"boolean"},"unsaved_changes":{"type":"boolean"},"created_by":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_by":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"archived_by":{"type":"string"},"archived_at":{"type":"string","format":"date-time"},"deleted_by":{"type":"string"},"deleted_at":{"type":"string","format":"date-time"},"active_admins":{"type":"array","items":{"type":"object","additionalProperties":true}},"services_publishing":{"type":"object","additionalProperties":true}},"additionalProperties":true}}},"paths":{"/scenarios/{scenario_id}":{"put":{"operationId":"updateScenario","description":"Update a scenario.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"mode":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Scenario"},"identifier":{"type":"string"}}}}}}}}}}}
```

## DELETE /scenarios/{scenario\_id}

> Delete a scenario.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"Scenario":{"type":"object","properties":{"_id":{"type":"string"},"scenario_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"mode":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"object","additionalProperties":true}},"changes":{"type":"boolean"},"unsaved_changes":{"type":"boolean"},"created_by":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_by":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"archived_by":{"type":"string"},"archived_at":{"type":"string","format":"date-time"},"deleted_by":{"type":"string"},"deleted_at":{"type":"string","format":"date-time"},"active_admins":{"type":"array","items":{"type":"object","additionalProperties":true}},"services_publishing":{"type":"object","additionalProperties":true}},"additionalProperties":true}}},"paths":{"/scenarios/{scenario_id}":{"delete":{"operationId":"deleteScenario","description":"Delete a scenario.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Scenario"},"identifier":{"type":"string"}}}}}}}}}}}
```

## POST /scenarios/{scenario\_id}/publish

> Publish a scenario's changes.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"Scenario":{"type":"object","properties":{"_id":{"type":"string"},"scenario_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"mode":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"object","additionalProperties":true}},"changes":{"type":"boolean"},"unsaved_changes":{"type":"boolean"},"created_by":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_by":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"archived_by":{"type":"string"},"archived_at":{"type":"string","format":"date-time"},"deleted_by":{"type":"string"},"deleted_at":{"type":"string","format":"date-time"},"active_admins":{"type":"array","items":{"type":"object","additionalProperties":true}},"services_publishing":{"type":"object","additionalProperties":true}},"additionalProperties":true}}},"paths":{"/scenarios/{scenario_id}/publish":{"post":{"operationId":"publishScenario","description":"Publish a scenario's changes.","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"mode":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"object","additionalProperties":true}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Scenario"},"identifier":{"type":"string"}}}}}}}}}}}
```

## DELETE /scenarios/{scenario\_id}/discard

> Discard unsaved changes for a scenario.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"Scenario":{"type":"object","properties":{"_id":{"type":"string"},"scenario_id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"status":{"type":"string"},"mode":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"notes":{"type":"array","items":{"type":"object","additionalProperties":true}},"changes":{"type":"boolean"},"unsaved_changes":{"type":"boolean"},"created_by":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_by":{"type":"string"},"updated_at":{"type":"string","format":"date-time"},"archived_by":{"type":"string"},"archived_at":{"type":"string","format":"date-time"},"deleted_by":{"type":"string"},"deleted_at":{"type":"string","format":"date-time"},"active_admins":{"type":"array","items":{"type":"object","additionalProperties":true}},"services_publishing":{"type":"object","additionalProperties":true}},"additionalProperties":true}}},"paths":{"/scenarios/{scenario_id}/discard":{"delete":{"operationId":"discardScenarioChanges","description":"Discard unsaved changes for a scenario.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/Scenario"},"identifier":{"type":"string"}}}}}}}}}}}
```

## GET /changes

> Retrieve changes. Use \`scenario\_id\` to filter changes for a single scenario.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"Change":{"type":"object","properties":{"_id":{"type":"string"},"change_id":{"type":"string"},"configuration_id":{"type":"string"},"status":{"type":"string"},"service":{"type":"string"},"entity_id":{"type":"string"},"entity_type":{"type":"string"},"method":{"type":"string"},"data":{"type":"object","additionalProperties":true},"created_by":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_by":{"type":"string"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/changes":{"get":{"operationId":"getChanges","description":"Retrieve changes. Use `scenario_id` to filter changes for a single scenario.","parameters":[{"name":"scenario_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"configuration_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"service","in":"query","required":false,"schema":{"type":"string"}},{"name":"entity_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"entity_type","in":"query","required":false,"schema":{"type":"string"}},{"name":"method","in":"query","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"changes":{"type":"array","items":{"$ref":"#/components/schemas/Change"}},"pagination":{"$ref":"#/components/schemas/Pagination"}}},"identifier":{"type":"string"}}}}}}}}}}}
```

## POST /changes

> Create one or more changes.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/changes":{"post":{"operationId":"createChanges","description":"Create one or more changes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"session_id":{"type":"string"},"changes":{"type":"array","items":{"type":"object","properties":{"configuration_id":{"type":"string"},"service":{"type":"string"},"entity_id":{"type":"string"},"entity_type":{"type":"string"},"method":{"type":"string"},"data":{"type":"object","additionalProperties":true},"created_by":{"type":"string"},"status":{"type":"string"}},"required":["configuration_id","service","entity_id","entity_type","method","data"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","additionalProperties":true},"identifier":{"type":"string"}}}}}}}}}}}
```

## PUT /changes

> Update one or more changes.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/changes":{"put":{"operationId":"updateChanges","description":"Update one or more changes.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"merge_to_saved":{"type":"boolean"},"session_id":{"type":"string"},"changes":{"type":"array","items":{"type":"object","properties":{"change_id":{"type":"string"},"service":{"type":"string"},"entity_id":{"type":"string"},"entity_type":{"type":"string"},"status":{"type":"string"},"method":{"type":"string"},"data":{"type":"object","additionalProperties":true}},"required":["change_id"]}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","additionalProperties":true},"identifier":{"type":"string"}}}}}}}}}}}
```

## DELETE /changes/{change\_id}

> Delete a change by ID.

```json
{"openapi":"3.0.3","info":{"title":"Scenarios API","version":"1.0"},"servers":[{"url":"https://api.gospace.app/scenarios/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/changes/{change_id}":{"delete":{"operationId":"deleteChange","description":"Delete a change by ID.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"}}},"identifier":{"type":"string"}}}}}}}}}}}
```


# Spatial API

## GET /locations

> Retrieve a list of locations or a specific location by ID.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"LocationApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"location_id":{"type":"string"},"name":{"type":"string"},"details":{"type":"object","additionalProperties":true},"country":{"type":"object","additionalProperties":true},"address":{"type":"object","additionalProperties":true},"coords":{"type":"object","additionalProperties":true},"settings":{"type":"object","additionalProperties":true},"override_settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}},"required":["from","to"]},"total_results":{"type":"integer"}},"required":["current_results","total_results"]}}},"paths":{"/locations":{"get":{"operationId":"getLocations","description":"Retrieve a list of locations or a specific location by ID.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"locations":{"type":"array","items":{"$ref":"#/components/schemas/LocationApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## POST /locations

> Create locations.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"LocationApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"location_id":{"type":"string"},"name":{"type":"string"},"details":{"type":"object","additionalProperties":true},"country":{"type":"object","additionalProperties":true},"address":{"type":"object","additionalProperties":true},"coords":{"type":"object","additionalProperties":true},"settings":{"type":"object","additionalProperties":true},"override_settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/locations":{"post":{"operationId":"postLocations","description":"Create locations.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["locations"],"properties":{"locations":{"type":"array","minItems":1,"items":{"type":"object","required":["name","country","address","coords"],"properties":{"name":{"type":"string"},"country":{"type":"object","additionalProperties":true},"address":{"type":"object","additionalProperties":true},"coords":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"override_settings":{"type":"object","additionalProperties":true},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/LocationApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## PUT /locations

> Update locations.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"LocationApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"location_id":{"type":"string"},"name":{"type":"string"},"details":{"type":"object","additionalProperties":true},"country":{"type":"object","additionalProperties":true},"address":{"type":"object","additionalProperties":true},"coords":{"type":"object","additionalProperties":true},"settings":{"type":"object","additionalProperties":true},"override_settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/locations":{"put":{"operationId":"putLocations","description":"Update locations.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["locations"],"properties":{"locations":{"type":"array","minItems":1,"items":{"type":"object","required":["location_id"],"properties":{"location_id":{"type":"string"},"name":{"type":"string"},"country":{"type":"object","additionalProperties":true},"address":{"type":"object","additionalProperties":true},"coords":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"settings":{"type":"object","additionalProperties":true}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/LocationApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## DELETE /locations

> Delete locations.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/locations":{"delete":{"operationId":"deleteLocations","description":"Delete locations.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["locations"],"properties":{"locations":{"type":"array","minItems":1,"items":{"type":"object","required":["location_id"],"properties":{"location_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"location_id":{"type":"string"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## GET /layers

> Retrieve layers with optional filters.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"LayerApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"layer_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"location_id":{"type":"string"},"location_name":{"type":"string"},"floor_plan_entities":{"type":"array","items":{}},"settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}},"required":["from","to"]},"total_results":{"type":"integer"}},"required":["current_results","total_results"]}}},"paths":{"/layers":{"get":{"operationId":"getLayers","description":"Retrieve layers with optional filters.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"layer_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"geojson","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"imdf","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"layers":{"type":"array","items":{"$ref":"#/components/schemas/LayerApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## POST /layers

> Create layers.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"LayerApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"layer_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"location_id":{"type":"string"},"location_name":{"type":"string"},"floor_plan_entities":{"type":"array","items":{}},"settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/layers":{"post":{"operationId":"postLayers","description":"Create layers.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["layers"],"properties":{"layers":{"type":"array","minItems":1,"items":{"type":"object","required":["name","location_id","location_name","type"],"properties":{"name":{"type":"string"},"location_id":{"type":"string"},"location_name":{"type":"string"},"type":{"type":"string"},"floor_plan_entities":{"type":"array","items":{}},"settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/LayerApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## PUT /layers

> Update layers.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"LayerApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"layer_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"location_id":{"type":"string"},"location_name":{"type":"string"},"floor_plan_entities":{"type":"array","items":{}},"settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/layers":{"put":{"operationId":"putLayers","description":"Update layers.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["layers"],"properties":{"layers":{"type":"array","minItems":1,"items":{"type":"object","required":["layer_id"],"properties":{"layer_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"floor_plan_entities":{"type":"array","items":{}},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/LayerApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## DELETE /layers

> Delete layers.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/layers":{"delete":{"operationId":"deleteLayers","description":"Delete layers.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["layers"],"properties":{"layers":{"type":"array","minItems":1,"items":{"type":"object","required":["layer_id"],"properties":{"layer_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"layer_id":{"type":"string"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## GET /spaces

> Retrieve spaces with optional filters.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"SpaceApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"space_id":{"type":"string"},"name":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"position":{"type":"object","additionalProperties":true},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}},"required":["from","to"]},"total_results":{"type":"integer"}},"required":["current_results","total_results"]}}},"paths":{"/spaces":{"get":{"operationId":"getSpaces","description":"Retrieve spaces with optional filters.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"layer_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"space_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"geojson","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"imdf","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"spaces":{"type":"array","items":{"$ref":"#/components/schemas/SpaceApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## POST /spaces

> Create spaces.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"SpaceApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"space_id":{"type":"string"},"name":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"position":{"type":"object","additionalProperties":true},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/spaces":{"post":{"operationId":"postSpaces","description":"Create spaces.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["spaces"],"properties":{"spaces":{"type":"array","minItems":1,"items":{"type":"object","required":["location_id","location_name","layer_id","layer_name","position","settings"],"properties":{"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"position":{"type":"object","additionalProperties":true},"settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/SpaceApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## PUT /spaces

> Update spaces.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"SpaceApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"space_id":{"type":"string"},"name":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"position":{"type":"object","additionalProperties":true},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/spaces":{"put":{"operationId":"putSpaces","description":"Update spaces.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["spaces"],"properties":{"spaces":{"type":"array","minItems":1,"items":{"type":"object","required":["space_id"],"properties":{"space_id":{"type":"string"},"name":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"position":{"type":"object","additionalProperties":true},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/SpaceApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## DELETE /spaces

> Delete spaces.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/spaces":{"delete":{"operationId":"deleteSpaces","description":"Delete spaces.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["spaces"],"properties":{"spaces":{"type":"array","minItems":1,"items":{"type":"object","required":["space_id"],"properties":{"space_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"space_id":{"type":"string"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## GET /rooms

> Retrieve rooms with optional filters.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"RoomApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"room_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"geometry":{"type":"object","additionalProperties":true},"spaces":{"type":"array","items":{}},"amenities":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}},"required":["from","to"]},"total_results":{"type":"integer"}},"required":["current_results","total_results"]}}},"paths":{"/rooms":{"get":{"operationId":"getRooms","description":"Retrieve rooms with optional filters.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"layer_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"room_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"geojson","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"imdf","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"rooms":{"type":"array","items":{"$ref":"#/components/schemas/RoomApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## POST /rooms

> Create rooms.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"RoomApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"room_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"geometry":{"type":"object","additionalProperties":true},"spaces":{"type":"array","items":{}},"amenities":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/rooms":{"post":{"operationId":"postRooms","description":"Create rooms.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["rooms"],"properties":{"rooms":{"type":"array","minItems":1,"items":{"type":"object","required":["name","type","layer_id","layer_name","location_id","location_name","spaces"],"properties":{"name":{"type":"string"},"type":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"location_id":{"type":"string"},"location_name":{"type":"string"},"spaces":{"type":"array","items":{}},"settings":{"type":"object","additionalProperties":true},"amenities":{"type":"object","additionalProperties":true},"geometry":{"type":"object","additionalProperties":true},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/RoomApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## PUT /rooms

> Update rooms.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"RoomApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"room_id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"geometry":{"type":"object","additionalProperties":true},"spaces":{"type":"array","items":{}},"amenities":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/rooms":{"put":{"operationId":"putRooms","description":"Update rooms.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["rooms"],"properties":{"rooms":{"type":"array","minItems":1,"items":{"type":"object","required":["room_id"],"properties":{"room_id":{"type":"string"},"spaces":{"type":"array","items":{}},"amenities":{"type":"object","additionalProperties":true},"settings":{"type":"object","additionalProperties":true},"type":{"type":"string"},"name":{"type":"string"},"geometry":{"type":"object","additionalProperties":true},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/RoomApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## DELETE /rooms

> Delete rooms.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/rooms":{"delete":{"operationId":"deleteRooms","description":"Delete rooms.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["rooms"],"properties":{"rooms":{"type":"array","minItems":1,"items":{"type":"object","required":["room_id"],"properties":{"room_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"room_id":{"type":"string"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## GET /zones

> Retrieve zones with optional filters.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ZoneApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"zone_id":{"type":"string"},"name":{"type":"string"},"spaces":{"type":"array","items":{}},"settings":{"type":"object","additionalProperties":true},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}},"required":["from","to"]},"total_results":{"type":"integer"}},"required":["current_results","total_results"]}}},"paths":{"/zones":{"get":{"operationId":"getZones","description":"Retrieve zones with optional filters.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"layer_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"zone_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"geojson","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"imdf","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"zones":{"type":"array","items":{"$ref":"#/components/schemas/ZoneApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## POST /zones

> Create zones.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ZoneApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"zone_id":{"type":"string"},"name":{"type":"string"},"spaces":{"type":"array","items":{}},"settings":{"type":"object","additionalProperties":true},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/zones":{"post":{"operationId":"postZones","description":"Create zones.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["zones"],"properties":{"zones":{"type":"array","minItems":1,"items":{"type":"object","required":["name","spaces","location_id","location_name","layer_id","layer_name"],"properties":{"name":{"type":"string"},"spaces":{"type":"array","items":{}},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ZoneApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## PUT /zones

> Update zones.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ZoneApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"zone_id":{"type":"string"},"name":{"type":"string"},"spaces":{"type":"array","items":{}},"settings":{"type":"object","additionalProperties":true},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/zones":{"put":{"operationId":"putZones","description":"Update zones.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["zones"],"properties":{"zones":{"type":"array","minItems":1,"items":{"type":"object","required":["zone_id"],"properties":{"zone_id":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"name":{"type":"string"},"spaces":{"type":"array","items":{}},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ZoneApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## DELETE /zones

> Delete zones.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/zones":{"delete":{"operationId":"deleteZones","description":"Delete zones.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["zones"],"properties":{"zones":{"type":"array","minItems":1,"items":{"type":"object","required":["zone_id"],"properties":{"zone_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"zone_id":{"type":"string"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## GET /clusters

> Retrieve clusters with optional filters.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ClusterApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"cluster_id":{"type":"string"},"spaces":{"type":"array","items":{}},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}},"required":["from","to"]},"total_results":{"type":"integer"}},"required":["current_results","total_results"]}}},"paths":{"/clusters":{"get":{"operationId":"getClusters","description":"Retrieve clusters with optional filters.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"layer_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"cluster_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"geojson","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"imdf","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"clusters":{"type":"array","items":{"$ref":"#/components/schemas/ClusterApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## POST /clusters

> Create clusters.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ClusterApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"cluster_id":{"type":"string"},"spaces":{"type":"array","items":{}},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/clusters":{"post":{"operationId":"postClusters","description":"Create clusters.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["clusters"],"properties":{"clusters":{"type":"array","minItems":1,"items":{"type":"object","required":["location_id","location_name","layer_id","layer_name","spaces"],"properties":{"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"spaces":{"type":"array","items":{}},"settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ClusterApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## PUT /clusters

> Update clusters.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ClusterApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"cluster_id":{"type":"string"},"spaces":{"type":"array","items":{}},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/clusters":{"put":{"operationId":"putClusters","description":"Update clusters.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["clusters"],"properties":{"clusters":{"type":"array","minItems":1,"items":{"type":"object","required":["cluster_id"],"properties":{"cluster_id":{"type":"string"},"spaces":{"type":"array","items":{}},"settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ClusterApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## DELETE /clusters

> Delete clusters.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/clusters":{"delete":{"operationId":"deleteClusters","description":"Delete clusters.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["clusters"],"properties":{"clusters":{"type":"array","minItems":1,"items":{"type":"object","required":["cluster_id"],"properties":{"cluster_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"cluster_id":{"type":"string"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## GET /areas

> Retrieve areas with optional filters.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"AreaApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"area_id":{"type":"string"},"geometry":{"type":"object","additionalProperties":true},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}},"required":["from","to"]},"total_results":{"type":"integer"}},"required":["current_results","total_results"]}}},"paths":{"/areas":{"get":{"operationId":"getAreas","description":"Retrieve areas with optional filters.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"layer_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"area_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"geojson","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"imdf","in":"query","required":false,"schema":{"type":"boolean","default":false}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"areas":{"type":"array","items":{"$ref":"#/components/schemas/AreaApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## POST /areas

> Create areas.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"AreaApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"area_id":{"type":"string"},"geometry":{"type":"object","additionalProperties":true},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/areas":{"post":{"operationId":"postAreas","description":"Create areas.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["areas"],"properties":{"areas":{"type":"array","minItems":1,"items":{"type":"object","required":["geometry","location_id","location_name","layer_id","layer_name"],"properties":{"geometry":{"type":"object","additionalProperties":true},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AreaApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## PUT /areas

> Update areas.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"AreaApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"area_id":{"type":"string"},"geometry":{"type":"object","additionalProperties":true},"location_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"external_id":{"type":"string"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/areas":{"put":{"operationId":"putAreas","description":"Update areas.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["areas"],"properties":{"areas":{"type":"array","minItems":1,"items":{"type":"object","required":["area_id"],"properties":{"area_id":{"type":"string"},"geometry":{"type":"object","additionalProperties":true},"settings":{"type":"object","additionalProperties":true},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/AreaApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## DELETE /areas

> Delete areas.

```json
{"openapi":"3.0.3","info":{"title":"Spatial API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/spatial/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/areas":{"delete":{"operationId":"deleteAreas","description":"Delete areas.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["areas"],"properties":{"areas":{"type":"array","minItems":1,"items":{"type":"object","required":["area_id"],"properties":{"area_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"type":"object","properties":{"area_id":{"type":"string"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```


# Workplace API

## GET /team/settings

> Retrieve team settings.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"TeamSettingsApiDTO":{"type":"object","properties":{"team_id":{"type":"string"},"team_name":{"type":"string"},"color":{"type":"string"},"head_count":{"type":"integer"},"space_type_preference":{"type":"string","enum":["AUTO","SPACE","ROOM"]},"default_location":{"type":"object","additionalProperties":true},"linked_locations":{"type":"array","items":{"type":"string"}},"settings":{"type":"array","items":{"type":"object","properties":{"location_id":{"type":"string"},"type":{"type":"string"},"min_capacity":{"type":"integer"},"max_capacity":{"type":"integer"},"contingency":{"type":"integer"},"fixed_days":{"type":"array","items":{"type":"integer"}}},"additionalProperties":true}}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/team/settings":{"get":{"operationId":"getTeamSettings","description":"Retrieve team settings.","parameters":[{"name":"team_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"team_settings":{"type":"array","items":{"$ref":"#/components/schemas/TeamSettingsApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## PUT /team/settings

> Update team settings.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"TeamSettingsApiDTO":{"type":"object","properties":{"team_id":{"type":"string"},"team_name":{"type":"string"},"color":{"type":"string"},"head_count":{"type":"integer"},"space_type_preference":{"type":"string","enum":["AUTO","SPACE","ROOM"]},"default_location":{"type":"object","additionalProperties":true},"linked_locations":{"type":"array","items":{"type":"string"}},"settings":{"type":"array","items":{"type":"object","properties":{"location_id":{"type":"string"},"type":{"type":"string"},"min_capacity":{"type":"integer"},"max_capacity":{"type":"integer"},"contingency":{"type":"integer"},"fixed_days":{"type":"array","items":{"type":"integer"}}},"additionalProperties":true}}},"additionalProperties":true}}},"paths":{"/team/settings":{"put":{"operationId":"putTeamSettings","description":"Update team settings.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["team_settings"],"properties":{"team_settings":{"type":"array","items":{"type":"object","required":["team_id","settings"],"properties":{"team_id":{"type":"string"},"space_type_preference":{"type":"string","enum":["AUTO","SPACE","ROOM"]},"settings":{"type":"array","items":{"type":"object","required":["location_id"],"properties":{"location_id":{"type":"string"},"type":{"type":"string"},"min_capacity":{"type":"integer"},"max_capacity":{"type":"integer"},"contingency":{"type":"integer"},"fixed_days":{"type":"array","items":{"type":"integer"}}}}}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/TeamSettingsApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## POST /occupancy

> Create occupancy records.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"OccupancyApiDTO":{"type":"object","properties":{"occupancy_id":{"type":"string"},"location_id":{"type":"string"},"people_id":{"type":"string"},"external_ids":{"type":"array","items":{"type":"string"}},"seen_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"door_external_id":{"type":"string"},"wap_external_id":{"type":"string"},"dock_external_id":{"type":"string"}},"additionalProperties":true}}},"paths":{"/occupancy":{"post":{"operationId":"postOccupancy","description":"Create occupancy records.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["location_id","occupancy"],"properties":{"location_id":{"type":"string"},"occupancy":{"type":"array","items":{"type":"object","required":["people_id","seen_at"],"properties":{"people_id":{"type":"string"},"seen_at":{"type":"string","description":"UTC ISO 8601 format."}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"info":{"type":"string"},"occupancy":{"type":"array","items":{"$ref":"#/components/schemas/OccupancyApiDTO"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## GET /occupancy

> Retrieve occupancy records.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"OccupancyApiDTO":{"type":"object","properties":{"occupancy_id":{"type":"string"},"location_id":{"type":"string"},"people_id":{"type":"string"},"external_ids":{"type":"array","items":{"type":"string"}},"seen_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"door_external_id":{"type":"string"},"wap_external_id":{"type":"string"},"dock_external_id":{"type":"string"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/occupancy":{"get":{"operationId":"getOccupancy","description":"Retrieve occupancy records.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"people_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"occupancy_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"starts_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"ends_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"name"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"occupancy":{"type":"array","items":{"$ref":"#/components/schemas/OccupancyApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## DELETE /occupancy

> Delete occupancy records.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/occupancy":{"delete":{"operationId":"deleteOccupancy","description":"Delete occupancy records.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["location_id"],"properties":{"location_id":{"type":"string"},"timezone":{"type":"string"},"people_id":{"type":"string"},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"},"occupancy":{"type":"array","items":{"type":"object","required":["occupancy_id"],"properties":{"occupancy_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"info":{"type":"string"},"deleted_records":{"type":"integer"}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## POST /forecast/start

> Start a forecasting job.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ForecastJobApiDTO":{"type":"object","properties":{"job_id":{"type":"string"},"location_id":{"type":"string"},"status":{"type":"string"},"service_processing":{"type":"object","additionalProperties":true},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"}},"additionalProperties":true}}},"paths":{"/forecast/start":{"post":{"operationId":"startForecast","description":"Start a forecasting job.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["location_id"],"properties":{"location_id":{"type":"string"},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"},"force_rebuild":{"type":"boolean","default":false}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/ForecastJobApiDTO"},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## GET /forecast/status

> Retrieve forecasting job status.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ForecastJobApiDTO":{"type":"object","properties":{"job_id":{"type":"string"},"location_id":{"type":"string"},"status":{"type":"string"},"service_processing":{"type":"object","additionalProperties":true},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/forecast/status":{"get":{"operationId":"getForecastStatus","description":"Retrieve forecasting job status.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"job_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"created_at"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"forecast_jobs":{"type":"array","items":{"$ref":"#/components/schemas/ForecastJobApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## GET /forecast/locations

> Retrieve forecasted location capacity.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"LocationForecastApiDTO":{"type":"object","additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/forecast/locations":{"get":{"operationId":"getLocationForecast","description":"Retrieve forecasted location capacity.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"starts_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"ends_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"starts_at"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"forecast":{"type":"array","items":{"$ref":"#/components/schemas/LocationForecastApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## GET /forecast/teams

> Retrieve forecasted team attendance.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"TeamForecastApiDTO":{"type":"object","additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/forecast/teams":{"get":{"operationId":"getTeamForecast","description":"Retrieve forecasted team attendance.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"people_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"team_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"starts_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"ends_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"starts_at"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"forecast":{"type":"array","items":{"$ref":"#/components/schemas/TeamForecastApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## GET /forecast/people

> Retrieve forecasted people attendance.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"PeopleForecastApiDTO":{"type":"object","additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/forecast/people":{"get":{"operationId":"getPeopleForecast","description":"Retrieve forecasted people attendance.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"people_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"team_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"starts_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"ends_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"timezone","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"starts_at"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"forecast":{"type":"array","items":{"$ref":"#/components/schemas/PeopleForecastApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## POST /evolve/start

> Trigger an AIDRA evolution run.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"EvolveApiDTO":{"type":"object","properties":{"evolution_id":{"type":"string"},"status":{"type":"string"}},"additionalProperties":true}}},"paths":{"/evolve/start":{"post":{"operationId":"triggerEvolve","description":"Trigger an AIDRA evolution run.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["location_id","date"],"properties":{"location_id":{"type":"string"},"date":{"type":"string","format":"date-time"},"settings":{"type":"object","properties":{"disturbance":{"type":"string","enum":["MIN","MAX"],"default":"MIN"},"run_by_zone":{"type":"boolean","default":false},"future_days":{"type":"integer","minimum":0,"maximum":14,"default":0},"model":{"type":"string","enum":["AIDRA-D1","AIDRA-T1"],"default":"AIDRA-D1"}},"additionalProperties":true}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/EvolveApiDTO"},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## GET /evolve/status

> Retrieve evolution status.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"EvolveApiDTO":{"type":"object","properties":{"evolution_id":{"type":"string"},"status":{"type":"string"}},"additionalProperties":true}}},"paths":{"/evolve/status":{"get":{"operationId":"getEvolveStatus","description":"Retrieve evolution status.","parameters":[{"name":"evolution_id","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"$ref":"#/components/schemas/EvolveApiDTO"},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## GET /allocations

> Retrieve allocations with filters.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"AllocationApiDTO":{"type":"object","properties":{"allocation_id":{"type":"string"},"location_id":{"type":"string"},"location_name":{"type":"string"},"location_timezone":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"room_id":{"type":"string"},"room_name":{"type":"string"},"zone_id":{"type":"string"},"zone_name":{"type":"string"},"team_id":{"type":"string"},"team_name":{"type":"string"},"people_id":{"type":"string"},"people_first_name":{"type":"string"},"people_last_name":{"type":"string"},"people_email":{"type":"string"},"spaces":{"type":"array","items":{}},"type":{"type":"string"},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"},"performance":{"type":"object","additionalProperties":true}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/allocations":{"get":{"operationId":"getAllocations","description":"Retrieve allocations with filters.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"layer_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"room_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"zone_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"people_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"team_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"starts_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"ends_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"location_timezone","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"starts_at"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"allocations":{"type":"array","items":{"$ref":"#/components/schemas/AllocationApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## POST /allocations

> Create allocations.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/allocations":{"post":{"operationId":"postAllocations","description":"Create allocations.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["allocations"],"properties":{"allocations":{"type":"array","items":{"type":"object","required":["location_id","location_name","location_timezone","layer_id","layer_name","spaces","starts_at","ends_at","type"],"properties":{"location_id":{"type":"string"},"location_name":{"type":"string"},"location_timezone":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"spaces":{"type":"array","items":{}},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"},"type":{"type":"string"},"room_id":{"type":"string"},"room_name":{"type":"string"},"zone_id":{"type":"string"},"zone_name":{"type":"string"},"team_id":{"type":"string"},"team_name":{"type":"string"},"people_id":{"type":"string"},"people_first_name":{"type":"string"},"people_last_name":{"type":"string"},"people_email":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string"}},"required":["success","identifier"]}}}}}}}}}
```

## PUT /allocations

> Update allocations.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/allocations":{"put":{"operationId":"putAllocations","description":"Update allocations.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["allocations"],"properties":{"allocations":{"type":"array","items":{"type":"object","required":["allocation_id"],"properties":{"allocation_id":{"type":"string"},"location_name":{"type":"string"},"layer_id":{"type":"string"},"layer_name":{"type":"string"},"room_id":{"type":"string"},"room_name":{"type":"string"},"zone_id":{"type":"string"},"zone_name":{"type":"string"},"team_id":{"type":"string"},"team_name":{"type":"string"},"people_id":{"type":"string"},"people_first_name":{"type":"string"},"people_last_name":{"type":"string"},"people_email":{"type":"string"},"spaces":{"type":"array","items":{}},"type":{"type":"string"},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string"}},"required":["success","identifier"]}}}}}}}}}
```

## DELETE /allocations

> Delete allocations.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/allocations":{"delete":{"operationId":"deleteAllocations","description":"Delete allocations.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["allocations"],"properties":{"allocations":{"type":"array","items":{"type":"object","required":["allocation_id"],"properties":{"allocation_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"identifier":{"type":"string"}},"required":["success","identifier"]}}}}}}}}}
```

## GET /intentions

> Retrieve intentions with optional filters. Only LIVE configuration is supported; scenario keys are ignored.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"IntentionApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"type":{"type":"string"},"location_id":{"type":"string"},"location_name":{"type":"string"},"location_timezone":{"type":"string"},"status":{"type":"string"},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"},"people_id":{"type":"string"},"people_first_name":{"type":"string"},"people_last_name":{"type":"string"},"people_email":{"type":"string"},"team_id":{"type":"string"},"team_name":{"type":"string"},"room_id":{"type":"string"},"room_name":{"type":"string"},"invite_list":{"type":"array","items":{}},"preferences":{"type":"object","additionalProperties":true},"amenities":{"type":"object","additionalProperties":true},"visitors":{"type":"array","items":{}},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/intentions":{"get":{"operationId":"getIntentions","description":"Retrieve intentions with optional filters. Only LIVE configuration is supported; scenario keys are ignored.","parameters":[{"name":"location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_location_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"layer_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"room_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"zone_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"people_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"team_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"starts_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"ends_at","in":"query","required":false,"schema":{"type":"string","format":"date-time"}},{"name":"location_timezone","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_location_timezone","in":"query","required":false,"schema":{"type":"string"}},{"name":"type","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_type","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"intentions":{"type":"array","items":{"$ref":"#/components/schemas/IntentionApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}}}}}}}
```

## POST /intentions

> Create an intention. Only LIVE configuration is supported; scenario keys are ignored.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"IntentionPublicDTO":{"type":"object","additionalProperties":true}}},"paths":{"/intentions":{"post":{"operationId":"createIntention","description":"Create an intention. Only LIVE configuration is supported; scenario keys are ignored.","parameters":[{"name":"force","in":"query","required":false,"schema":{"type":"boolean"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["type","location_id","people_id","people_first_name","people_last_name","people_email","dates"],"properties":{"status":{"type":"string"},"type":{"type":"string"},"location_id":{"type":"string"},"people_id":{"type":"string"},"people_first_name":{"type":"string"},"people_last_name":{"type":"string"},"people_email":{"type":"string"},"team_id":{"type":"string"},"team_name":{"type":"string"},"invite_list":{"type":"array","items":{}},"preferences":{"type":"object","additionalProperties":true},"amenities":{"type":"object","additionalProperties":true},"visitors":{"type":"array","items":{}},"dates":{"type":"array","items":{"type":"object","additionalProperties":true}},"custom_time":{"type":"object","additionalProperties":true},"skip_auto_accept":{"type":"boolean","default":false},"fixed_day":{"type":"object","additionalProperties":true},"allocation":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"intentions":{"type":"array","items":{"$ref":"#/components/schemas/IntentionPublicDTO"}},"errors":{"type":"array","items":{}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"207":{"description":"Partial Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"intentions":{"type":"array","items":{"$ref":"#/components/schemas/IntentionPublicDTO"}},"errors":{"type":"array","items":{}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## POST /intentions/external

> Create external intentions. Only LIVE configuration is supported; scenario keys are ignored.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"IntentionPublicDTO":{"type":"object","additionalProperties":true}}},"paths":{"/intentions/external":{"post":{"operationId":"createExternalIntention","description":"Create external intentions. Only LIVE configuration is supported; scenario keys are ignored.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["intentions"],"properties":{"intentions":{"type":"array","minItems":1,"items":{"type":"object","required":["people_id","people_email","people_first_name","people_last_name","starts_at","ends_at","external_location_id","external_location_name","external_location_timezone","external_type"],"properties":{"people_id":{"type":"string"},"people_email":{"type":"string"},"people_first_name":{"type":"string"},"people_last_name":{"type":"string"},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"},"external_location_id":{"type":"string"},"external_location_name":{"type":"string"},"external_location_timezone":{"type":"string"},"external_type":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/IntentionPublicDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"207":{"description":"Partial Success","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/IntentionPublicDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## PUT /intentions/{intention\_id}/accept

> Accept an intention. Only LIVE configuration is supported; scenario keys are ignored.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/intentions/{intention_id}/accept":{"put":{"operationId":"acceptIntention","description":"Accept an intention. Only LIVE configuration is supported; scenario keys are ignored.","parameters":[{"name":"intention_id","in":"path","required":true,"schema":{"type":"string"}},{"name":"force","in":"query","required":false,"schema":{"type":"string","default":"false"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"},"status":{"type":"string"},"allocation":{"type":"object","additionalProperties":true},"allcoated_at":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"409":{"description":"Conflicting intentions detected","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"existing_intentions":{"type":"array","items":{}},"existing_meetings":{"type":"array","items":{}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## PUT /intentions/{intention\_id}/decline

> Decline an intention. Only LIVE configuration is supported; scenario keys are ignored.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/intentions/{intention_id}/decline":{"put":{"operationId":"declineIntention","description":"Decline an intention. Only LIVE configuration is supported; scenario keys are ignored.","parameters":[{"name":"intention_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"},"status":{"type":"string"},"reason":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## PUT /intentions/{intention\_id}/cancel

> Cancel an intention. Only LIVE configuration is supported; scenario keys are ignored.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/intentions/{intention_id}/cancel":{"put":{"operationId":"cancelIntention","description":"Cancel an intention. Only LIVE configuration is supported; scenario keys are ignored.","parameters":[{"name":"intention_id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"},"cancel_for_all":{"type":"boolean"}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"},"status":{"type":"string"},"reason":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```

## DELETE /intentions/{intention\_id}

> Delete an intention. Only LIVE configuration is supported; scenario keys are ignored.

```json
{"openapi":"3.0.3","info":{"title":"Workplace API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/workplace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/intentions/{intention_id}":{"delete":{"operationId":"deleteIntention","description":"Delete an intention. Only LIVE configuration is supported; scenario keys are ignored.","parameters":[{"name":"intention_id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"_id":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}}}}}}}
```


# Directory API

## GET /people

> Retrieve people by filters or identifiers.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"PeopleApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"people_id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"country":{"type":"string"},"default_location":{"$ref":"#/components/schemas/LocationBlock"},"default_team":{"$ref":"#/components/schemas/TeamBlock"},"default_preferences":{"type":"array","items":{"$ref":"#/components/schemas/LabelBlock"}},"linked_locations":{"type":"array","items":{"type":"string"}},"priority_locations":{"type":"array","items":{"$ref":"#/components/schemas/LocationBlock"}},"external_ids":{"type":"array","items":{"type":"string"}},"teams":{"type":"array","items":{"$ref":"#/components/schemas/TeamBlock"}},"settings":{"type":"object","additionalProperties":true},"override_settings":{"type":"object","additionalProperties":true},"default_connection":{"type":"object","additionalProperties":true}},"additionalProperties":true},"LocationBlock":{"type":"object","properties":{"location_id":{"type":"string"},"location_name":{"type":"string"}}},"TeamBlock":{"type":"object","properties":{"team_id":{"type":"string"},"team_name":{"type":"string"},"assigned_at":{"type":"string","format":"date-time"},"type":{"type":"string"}}},"LabelBlock":{"type":"object","properties":{"label_id":{"type":"string"},"label_name":{"type":"string"}}},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}},"required":["from","to"]},"total_results":{"type":"integer"}},"required":["current_results","total_results"]}}},"paths":{"/people":{"get":{"operationId":"getPeople","description":"Retrieve people by filters or identifiers.","parameters":[{"name":"people_id","in":"query","required":false,"description":"Optional ID of the person to retrieve.","schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"description":"Optional external ID to filter people.","schema":{"type":"string"}},{"name":"email","in":"query","required":false,"description":"Optional email to filter people.","schema":{"type":"string"}},{"name":"first_name","in":"query","required":false,"description":"Optional first name to filter people.","schema":{"type":"string"}},{"name":"last_name","in":"query","required":false,"description":"Optional last name to filter people.","schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"description":"Number of items to skip for pagination.","schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"description":"Maximum number of items to return.","schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"description":"Field to sort by.","schema":{"type":"string"}},{"name":"order","in":"query","required":false,"description":"Sort order, 'asc' or 'desc'.","schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"people":{"type":"array","items":{"$ref":"#/components/schemas/PeopleApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```

## POST /people

> Create multiple people in a single request.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"PeopleApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"people_id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"country":{"type":"string"},"default_location":{"$ref":"#/components/schemas/LocationBlock"},"default_team":{"$ref":"#/components/schemas/TeamBlock"},"default_preferences":{"type":"array","items":{"$ref":"#/components/schemas/LabelBlock"}},"linked_locations":{"type":"array","items":{"type":"string"}},"priority_locations":{"type":"array","items":{"$ref":"#/components/schemas/LocationBlock"}},"external_ids":{"type":"array","items":{"type":"string"}},"teams":{"type":"array","items":{"$ref":"#/components/schemas/TeamBlock"}},"settings":{"type":"object","additionalProperties":true},"override_settings":{"type":"object","additionalProperties":true},"default_connection":{"type":"object","additionalProperties":true}},"additionalProperties":true},"LocationBlock":{"type":"object","properties":{"location_id":{"type":"string"},"location_name":{"type":"string"}}},"TeamBlock":{"type":"object","properties":{"team_id":{"type":"string"},"team_name":{"type":"string"},"assigned_at":{"type":"string","format":"date-time"},"type":{"type":"string"}}},"LabelBlock":{"type":"object","properties":{"label_id":{"type":"string"},"label_name":{"type":"string"}}}}},"paths":{"/people":{"post":{"operationId":"createPeople","description":"Create multiple people in a single request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["people"],"properties":{"people":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"object","required":["email","first_name","last_name","country"],"properties":{"email":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"country":{"type":"string"},"external_ids":{"type":"array","items":{"type":"string"}},"default_location":{"type":"string"},"default_team":{"type":"string"},"default_preferences":{"type":"array","items":{"type":"string"}},"priority_locations":{"type":"array","items":{"type":"string"}},"preferences":{"type":"object","additionalProperties":true},"personal_settings":{"type":"object","additionalProperties":true},"teams":{"type":"array","items":{"type":"string"}},"address":{"type":"object","additionalProperties":true},"coords":{"type":"object","additionalProperties":true}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/PeopleApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```

## PUT /people

> Update multiple existing people by their IDs.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"PeopleApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"people_id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"country":{"type":"string"},"default_location":{"$ref":"#/components/schemas/LocationBlock"},"default_team":{"$ref":"#/components/schemas/TeamBlock"},"default_preferences":{"type":"array","items":{"$ref":"#/components/schemas/LabelBlock"}},"linked_locations":{"type":"array","items":{"type":"string"}},"priority_locations":{"type":"array","items":{"$ref":"#/components/schemas/LocationBlock"}},"external_ids":{"type":"array","items":{"type":"string"}},"teams":{"type":"array","items":{"$ref":"#/components/schemas/TeamBlock"}},"settings":{"type":"object","additionalProperties":true},"override_settings":{"type":"object","additionalProperties":true},"default_connection":{"type":"object","additionalProperties":true}},"additionalProperties":true},"LocationBlock":{"type":"object","properties":{"location_id":{"type":"string"},"location_name":{"type":"string"}}},"TeamBlock":{"type":"object","properties":{"team_id":{"type":"string"},"team_name":{"type":"string"},"assigned_at":{"type":"string","format":"date-time"},"type":{"type":"string"}}},"LabelBlock":{"type":"object","properties":{"label_id":{"type":"string"},"label_name":{"type":"string"}}}}},"paths":{"/people":{"put":{"operationId":"updatePeople","description":"Update multiple existing people by their IDs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["people"],"properties":{"people":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"object","required":["people_id"],"properties":{"people_id":{"type":"string"},"email":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"country":{"type":"string"},"external_ids":{"type":"array","items":{"type":"string"}},"default_location":{"type":"string"},"default_team":{"type":"string"},"default_preferences":{"type":"array","items":{"type":"string"}},"priority_locations":{"type":"array","items":{"type":"string"}},"preferences":{"type":"object","additionalProperties":true},"personal_settings":{"type":"object","additionalProperties":true},"teams":{"type":"array","items":{"type":"string"}},"address":{"type":"object","additionalProperties":true},"coords":{"type":"object","additionalProperties":true},"settings":{"type":"object","additionalProperties":true},"override_settings":{"type":"object","additionalProperties":true},"default_connection":{"type":"object","additionalProperties":true}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/PeopleApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```

## DELETE /people

> Delete multiple people by their IDs.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/people":{"delete":{"operationId":"deletePeople","description":"Delete multiple people by their IDs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["people"],"properties":{"people":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"object","required":["people_id"],"properties":{"people_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"deleted_people":{"type":"array","items":{"type":"string"}},"master_user_not_deleted":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```

## GET /teams

> Retrieve teams with optional filters.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"TeamApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"team_id":{"type":"string"},"name":{"type":"string"},"color":{"type":"string"},"default_location":{"$ref":"#/components/schemas/LocationBlock"},"team_type":{"type":"string"},"linked_locations":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"people":{"type":"array","items":{"$ref":"#/components/schemas/TeamMemberDTO"}},"total_people":{"type":"integer"}},"additionalProperties":true},"LocationBlock":{"type":"object","properties":{"location_id":{"type":"string"},"location_name":{"type":"string"}}},"TeamMemberDTO":{"type":"object","properties":{"_id":{"type":"string"},"people_id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"external_ids":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}},"required":["from","to"]},"total_results":{"type":"integer"}},"required":["current_results","total_results"]}}},"paths":{"/teams":{"get":{"operationId":"getTeams","description":"Retrieve teams with optional filters.","parameters":[{"name":"team_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"name","in":"query","required":false,"schema":{"type":"string"}},{"name":"include_members","in":"query","required":false,"description":"Whether to include team members in the response.","schema":{"type":"string","enum":["true","false"],"default":"false"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"teams":{"type":"array","items":{"$ref":"#/components/schemas/TeamApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```

## POST /teams

> Create multiple teams in a single request.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"TeamApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"team_id":{"type":"string"},"name":{"type":"string"},"color":{"type":"string"},"default_location":{"$ref":"#/components/schemas/LocationBlock"},"team_type":{"type":"string"},"linked_locations":{"type":"array","items":{"type":"string"}},"hierarchy":{"type":"object","additionalProperties":true},"external_id":{"type":"string"},"people":{"type":"array","items":{"$ref":"#/components/schemas/TeamMemberDTO"}},"total_people":{"type":"integer"}},"additionalProperties":true},"LocationBlock":{"type":"object","properties":{"location_id":{"type":"string"},"location_name":{"type":"string"}}},"TeamMemberDTO":{"type":"object","properties":{"_id":{"type":"string"},"people_id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"external_ids":{"type":"array","items":{"type":"string"}}},"additionalProperties":true}}},"paths":{"/teams":{"post":{"operationId":"createTeams","description":"Create multiple teams in a single request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["teams"],"properties":{"teams":{"type":"array","minItems":1,"items":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"color":{"type":"string"},"default_location":{"type":"object","properties":{"location_id":{"type":"string"},"location_name":{"type":"string"}},"additionalProperties":false},"external_id":{"type":"string"},"members":{"type":"array","items":{"type":"object","required":["people_id"],"properties":{"people_id":{"type":"string"}}}}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/TeamApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```

## PUT /teams

> Update multiple existing teams by their IDs.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"UpdatedTeamDTO":{"type":"object","properties":{"_id":{"type":"string"},"team_id":{"type":"string"},"name":{"type":"string"},"color":{"type":"string"},"default_location":{"$ref":"#/components/schemas/LocationBlock"},"external_id":{"type":"string"}}},"LocationBlock":{"type":"object","properties":{"location_id":{"type":"string"},"location_name":{"type":"string"}}}}},"paths":{"/teams":{"put":{"operationId":"updateTeams","description":"Update multiple existing teams by their IDs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["teams"],"properties":{"teams":{"type":"array","minItems":1,"items":{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string"},"name":{"type":"string"},"color":{"type":"string"},"default_location":{"type":"object","nullable":true,"properties":{"location_id":{"type":"string"},"location_name":{"type":"string"}},"additionalProperties":false},"external_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/UpdatedTeamDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```

## DELETE /teams

> Delete multiple teams by their IDs.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/teams":{"delete":{"operationId":"deleteTeams","description":"Delete multiple teams by their IDs.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["teams"],"properties":{"teams":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"object","required":["team_id"],"properties":{"team_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"deleted_teams":{"type":"array","items":{"type":"string"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```

## GET /teams/{team\_id}/members

> Retrieve team members with optional filters.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"TeamMemberDTO":{"type":"object","properties":{"_id":{"type":"string"},"people_id":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"email":{"type":"string"},"external_ids":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}},"required":["from","to"]},"total_results":{"type":"integer"}},"required":["current_results","total_results"]}}},"paths":{"/teams/{team_id}/members":{"get":{"operationId":"getTeamMembers","description":"Retrieve team members with optional filters.","parameters":[{"name":"people_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"email","in":"query","required":false,"schema":{"type":"string"}},{"name":"first_name","in":"query","required":false,"schema":{"type":"string"}},{"name":"last_name","in":"query","required":false,"schema":{"type":"string"}},{"name":"external_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","default":"first_name"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"members":{"type":"array","items":{"$ref":"#/components/schemas/TeamMemberDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```

## PUT /teams/{team\_id}/members

> Add members to a team.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/teams/{team_id}/members":{"put":{"operationId":"addTeamMembers","description":"Add members to a team.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["members"],"properties":{"members":{"type":"array","items":{"type":"object","required":["people_id"],"properties":{"people_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"members_added":{"type":"array","items":{"type":"string"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```

## DELETE /teams/{team\_id}/members

> Remove members from a team.

```json
{"openapi":"3.0.3","info":{"title":"Directory API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/directory/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}}},"paths":{"/teams/{team_id}/members":{"delete":{"operationId":"removeTeamMembers","description":"Remove members from a team.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["members"],"properties":{"members":{"type":"array","items":{"type":"object","required":["people_id"],"properties":{"people_id":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"members_removed":{"type":"array","items":{"type":"string"}}}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"error":{"type":"object","properties":{"code":{"type":"integer"},"message":{"type":"string"}}},"identifier":{"type":"string"}},"required":["success","error","identifier"]}}}}}}}}}
```


# Connections API

## GET /connections

> Retrieve a list of connections or a specific connection by ID.

```json
{"openapi":"3.0.3","info":{"title":"Connections API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/connections/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ConnectionApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"connection_from_entity":{"$ref":"#/components/schemas/ConnectionEntity"},"connection_to_entity":{"$ref":"#/components/schemas/ConnectionEntity"},"strength":{"type":"number"},"priority":{"type":"number"},"status":{"type":"string"},"configuration_id":{"type":"string"}},"additionalProperties":true},"ConnectionEntity":{"type":"object","properties":{"connection_entity_id":{"type":"string"},"connection_entity_type":{"type":"string","enum":["PERSON","TEAM","LABEL","ZONE","ROOM","SPACE","LOCATION","LAYER"]},"connection_entity_data":{"type":"object","additionalProperties":true}},"required":["connection_entity_id","connection_entity_type"],"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/connections":{"get":{"operationId":"getConnections","description":"Retrieve a list of connections or a specific connection by ID.","parameters":[{"name":"connection_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"connections":{"type":"array","items":{"$ref":"#/components/schemas/ConnectionApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}},"500":{"description":"Internal Server Error"}}}}}}
```

## POST /connections

> Create multiple connections in a single request.

```json
{"openapi":"3.0.3","info":{"title":"Connections API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/connections/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ConnectionApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"connection_from_entity":{"$ref":"#/components/schemas/ConnectionEntity"},"connection_to_entity":{"$ref":"#/components/schemas/ConnectionEntity"},"strength":{"type":"number"},"priority":{"type":"number"},"status":{"type":"string"},"configuration_id":{"type":"string"}},"additionalProperties":true},"ConnectionEntity":{"type":"object","properties":{"connection_entity_id":{"type":"string"},"connection_entity_type":{"type":"string","enum":["PERSON","TEAM","LABEL","ZONE","ROOM","SPACE","LOCATION","LAYER"]},"connection_entity_data":{"type":"object","additionalProperties":true}},"required":["connection_entity_id","connection_entity_type"],"additionalProperties":true}}},"paths":{"/connections":{"post":{"operationId":"createConnections","description":"Create multiple connections in a single request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["connections"],"properties":{"connections":{"type":"array","items":{"type":"object","required":["connection_from_entity_id","connection_to_entity_id","strength"],"properties":{"connection_from_entity_id":{"type":"string"},"connection_to_entity_id":{"type":"string"},"strength":{"type":"number"},"priority":{"type":"number","default":1},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"},"notes":{"type":"string"},"location_id":{"type":"string","nullable":true}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ConnectionApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"500":{"description":"Internal Server Error"}}}}}}
```

## PUT /connections

> Edit multiple connections in a single request.

```json
{"openapi":"3.0.3","info":{"title":"Connections API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/connections/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"ConnectionApiDTO":{"type":"object","properties":{"_id":{"type":"string"},"connection_from_entity":{"$ref":"#/components/schemas/ConnectionEntity"},"connection_to_entity":{"$ref":"#/components/schemas/ConnectionEntity"},"strength":{"type":"number"},"priority":{"type":"number"},"status":{"type":"string"},"configuration_id":{"type":"string"}},"additionalProperties":true},"ConnectionEntity":{"type":"object","properties":{"connection_entity_id":{"type":"string"},"connection_entity_type":{"type":"string","enum":["PERSON","TEAM","LABEL","ZONE","ROOM","SPACE","LOCATION","LAYER"]},"connection_entity_data":{"type":"object","additionalProperties":true}},"required":["connection_entity_id","connection_entity_type"],"additionalProperties":true}}},"paths":{"/connections":{"put":{"operationId":"editConnections","description":"Edit multiple connections in a single request.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["connections"],"properties":{"connections":{"type":"array","items":{"type":"object","required":["connection_id"],"properties":{"connection_id":{"type":"string"},"strength":{"type":"number"},"priority":{"type":"number"},"starts_at":{"type":"string","format":"date-time"},"ends_at":{"type":"string","format":"date-time"},"notes":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ConnectionApiDTO"}},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"500":{"description":"Internal Server Error"}}}}}}
```

## GET /labels

> Retrieve label definitions.

```json
{"openapi":"3.0.3","info":{"title":"Connections API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/connections/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"LabelApiDTO":{"type":"object","properties":{"connection_entity_id":{"type":"string"},"connection_entity_type":{"type":"string","enum":["PERSON","TEAM","LABEL","ZONE","ROOM","SPACE","LOCATION","LAYER"]},"entity_data":{"type":"object","additionalProperties":true},"flags":{"type":"object","properties":{"connectable":{"type":"boolean"}},"additionalProperties":true},"location_id":{"type":"string"},"configuration_id":{"type":"string"},"status":{"type":"string"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/labels":{"get":{"operationId":"getLabels","description":"Retrieve label definitions.","parameters":[{"name":"label_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"labels":{"type":"array","items":{"$ref":"#/components/schemas/LabelApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}},"500":{"description":"Internal Server Error"}}}}}}
```

## GET /labels/mapping

> Retrieve label mappings.

```json
{"openapi":"3.0.3","info":{"title":"Connections API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/connections/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"LabelMappingApiDTO":{"type":"object","properties":{"connection_entity_id":{"type":"string"},"label_definition_entity_id":{"type":"string"},"value":{"type":"string"},"entity_type":{"type":"string"},"visibility":{"type":"string"},"location_id":{"type":"string"},"configuration_id":{"type":"string"},"status":{"type":"string"}},"additionalProperties":true},"Pagination":{"type":"object","properties":{"current_results":{"type":"object","properties":{"from":{"type":"integer"},"to":{"type":"integer"}}},"total_results":{"type":"integer"}},"additionalProperties":true}}},"paths":{"/labels/mapping":{"get":{"operationId":"getLabelMappings","description":"Retrieve label mappings.","parameters":[{"name":"label_mapping_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"label_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"skip","in":"query","required":false,"schema":{"type":"integer","default":0}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","default":25}},{"name":"sort","in":"query","required":false,"schema":{"type":"string"}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"default":"asc"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","properties":{"label_mappings":{"type":"array","items":{"$ref":"#/components/schemas/LabelMappingApiDTO"}}}},"pagination":{"$ref":"#/components/schemas/Pagination"},"identifier":{"type":"string"}},"required":["success","data","pagination","identifier"]}}}},"500":{"description":"Internal Server Error"}}}}}}
```


# System API

## GET /country

> Retrieve all enabled countries.

```json
{"openapi":"3.0.3","info":{"title":"gospace system API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/gospace/v1"}],"paths":{"/country":{"get":{"operationId":"getAllCountries","description":"Retrieve all enabled countries.","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Country"}}},"required":["success","data"]}}}},"500":{"description":"Internal Server Error"}}}}},"components":{"schemas":{"Country":{"type":"object","properties":{"_id":{"type":"string"},"country_id":{"type":"string"},"name":{"type":"string"},"iso2":{"type":"string"},"iso3":{"type":"string"},"currency":{"type":"string"},"calling_code":{"type":"string"},"timezones":{"type":"array","items":{"type":"string"}}},"additionalProperties":true}}}}
```

## GET /upload

> Retrieve uploads by status, upload ID, or process.

```json
{"openapi":"3.0.3","info":{"title":"gospace system API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/gospace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"UploadStatus":{"type":"string","enum":["PENDING","PROCESSING","COMPLETE","FAILED","CANCELED","EXPIRED"]},"UploadProcess":{"type":"string","enum":["floorplan","profile-image","location-image","layer-image","room-image","space-image","teams-data","teams-settings-data","people-data","people-settings-data","occupancy-data"]}}},"paths":{"/upload":{"get":{"operationId":"getUploads","description":"Retrieve uploads by status, upload ID, or process.","parameters":[{"name":"status","in":"query","required":false,"schema":{"$ref":"#/components/schemas/UploadStatus"}},{"name":"upload_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"upload_process","in":"query","required":false,"schema":{"$ref":"#/components/schemas/UploadProcess"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","additionalProperties":true},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request"},"500":{"description":"Internal Server Error"}}}}}}
```

## POST /upload

> Create an upload session for a file.

```json
{"openapi":"3.0.3","info":{"title":"gospace system API","version":"2.0"},"servers":[{"url":"https://api.gospace.app/gospace/v1"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key"}},"schemas":{"FileType":{"type":"string","enum":["image/png","image/jpg","image/jpeg","text/csv","text/dxf","text/pdf","application/json","application/geo+json","application/dxf","application/acad"]},"UploadProcess":{"type":"string","enum":["floorplan","profile-image","location-image","layer-image","room-image","space-image","teams-data","teams-settings-data","people-data","people-settings-data","occupancy-data"]}}},"paths":{"/upload":{"post":{"operationId":"uploadFile","description":"Create an upload session for a file.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["file_type","upload_process","binding_id"],"properties":{"file_type":{"$ref":"#/components/schemas/FileType"},"upload_process":{"$ref":"#/components/schemas/UploadProcess"},"binding_id":{"type":"string"},"meta":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"data":{"type":"object","additionalProperties":true},"identifier":{"type":"string"}},"required":["success","data","identifier"]}}}},"400":{"description":"Bad Request"},"500":{"description":"Internal Server Error"}}}}}}
```


# Overview

The **gospace Floorplan SDK** (`@gospace-ai/floorplan`) lets you embed fully interactive, real-time floorplans into your web or native applications. Users can explore, visualise, and interact with workplace spaces such as desks, private offices, meeting rooms, and zones — all within a secure, framework-agnostic integration.

Hosted at [**https://floorplan.gospace.app**](https://floorplan.gospace.app/), the SDK works with any JavaScript environment and supports deep integration with your workplace management workflows.

***

### What It Does

* Displays a **live, interactive floorplan** directly inside your app.
* Shows **real-time space allocations** for people, teams, or departments.
* Allows **secure, filtered views** of specific locations, layers, rooms, zones, or spaces.
* Sends user interaction events back to your application for custom handling.

***

### Rendering Modes

The SDK supports two rendering modes, configured at initialisation:

* **2D Mode** – A top-down floorplan for fast navigation and clear allocation visualisation.
* **3D Mode** – A richer, more immersive environment for showcasing layouts and spaces.

***

### Key Features

**Cross-Platform Compatibility**\
Works with any JavaScript framework (React, Vue, Nuxt, Angular) or plain JS. Supports both browser and native webview integrations.

**Interactive Floorplan Embedding**\
Embeds an iframe-based floorplan (built with Nuxt UI) into your application, allowing intuitive pan, zoom, and click interactions.

**Space Allocation Visualisation**\
Highlights user-specific or filter-based allocations for desks, rooms, and other spaces, with the option to focus on selected areas.

**Secure Communication**\
Uses `postMessage` for safe, cross-origin communication. Passes parameters like:

* `access_token`
* `location_id`
* `layer_id`
* `room_id`
* `zone_id`
* `spaces` (array of space IDs)

**Event Handling**\
Emits `SPACE_CLICKED` events when users click a space, returning its `space_id` for your application to handle.

**TypeScript Support**\
Includes full type definitions for strong typing, autocompletion, and IDE hints.


# Installation

The **gospace Floorplan SDK** (`@gospace-ai/floorplan`) can be installed via npm/yarn for use in modern JavaScript projects, or loaded directly in the browser via a public CDN.

***

### 1) Install via npm or yarn

```bash
npm install @gospace-ai/floorplan
```

or

```bash
yarn add @gospace-ai/floorplan
```

***

### 2) Import the SDK

**ESM (recommended)**

```ts
import Floorplan from "@gospace-ai/floorplan";
```

**CommonJS**

```js
const Floorplan = require("@gospace-ai/floorplan");
```

***

### 3) Use via CDN in Browser Environments

You can load the SDK without installing by using a public npm CDN such as **jsDelivr** or **unpkg**:

```html
<!-- Latest (auto-updates to the newest version) -->
<script src="https://cdn.jsdelivr.net/npm/@gospace-ai/floorplan@latest/dist/floorplan.umd.js"></script>

<!-- Or pin a specific version -->
<script src="https://cdn.jsdelivr.net/npm/@gospace-ai/floorplan@2.14.0/dist/floorplan.umd.js"></script>

<!-- unpkg alternative -->
<script src="https://unpkg.com/@gospace-ai/floorplan/dist/floorplan.umd.js"></script>
```

When loaded this way, the SDK is available as a global `Floorplan` object.

***

### 4) Requirements

* Node.js v18+ for local development
* A valid **access token** from gospace
* Supported browsers: Chrome, Edge, Safari, Firefox (latest two versions)
* Internet access to load the hosted floorplan at [**https://floorplan.gospace.app**](https://floorplan.gospace.app/)


# Configuration

The Floorplan SDK is configured during initialisation by passing an options object. These options control what is displayed, how it is displayed, and which parts of the plan are interactive.

***

### Required parameters

| Key            | Type                  | Description                                                                         |
| -------------- | --------------------- | ----------------------------------------------------------------------------------- |
| `key`          | `string`              | DOM element ID where the floorplan will be mounted.                                 |
| `access_token` | `string`              | Short-lived access token generated via the gospace API. Required for secure access. |
| `location_id`  | `string`              | Unique ID of the location to render.                                                |
| `layer_id`     | `string` *(optional)* | Floor/layer to render. If omitted, defaults to the first available.                 |

***

### Optional parameters

| Key           | Type                | Description                                                              |
| ------------- | ------------------- | ------------------------------------------------------------------------ |
| `room_id`     | `string`            | Restrict view to a specific room.                                        |
| `zone_id`     | `string`            | Restrict view to a specific zone/neighbourhood.                          |
| `spaces`      | `string[]`          | Array of space IDs to highlight or restrict view to.                     |
| `mode`        | `"2D" \| "3D"`      | Rendering mode. Defaults to `"2D"`.                                      |
| `highlight`   | `boolean`           | Whether to highlight allocated spaces. Defaults to `true`.               |
| `readonly`    | `boolean`           | Disables interactions if `true`. Defaults to `false`.                    |
| `theme`       | `"light" \| "dark"` | Floorplan theme. Defaults to match system preference.                    |
| `labels`      | `boolean`           | Toggle space labels. Defaults to `true`.                                 |
| `fit_to_view` | `boolean`           | Automatically fit plan to available container space. Defaults to `true`. |
| `debug`       | `boolean`           | Enables console logging for development. Defaults to `false`.            |

***

### Example – minimal

```ts
import Floorplan from "@gospace-ai/floorplan";

const sdk = new Floorplan({
  key: "floorplan-root",
  access_token: "<short-lived-access-token>",
  location_id: "loc_123",
});

sdk.init();
```

***

### Example – advanced

```ts
import Floorplan from "@gospace-ai/floorplan";

const sdk = new Floorplan({
  key: "floorplan-root",
  access_token: "<short-lived-access-token>",
  location_id: "loc_123",
  layer_id: "layer_001",
  mode: "3D",
  highlight: true,
  theme: "dark",
  readonly: false,
  spaces: ["space_a1", "space_a2"],
  labels: true,
  fit_to_view: true,
  debug: true,
});

sdk.init();
```

***

### Access tokens

* Access tokens are **short-lived** and must be generated server-side using your gospace API key.
* Tokens should be scoped to the required resources (location, layer, etc.).
* Never expose your API key directly in the browser — use your backend to request tokens securely.

***

### Container requirements

* The container element (`key`) must exist in the DOM before calling `init()`.
* Set a fixed height or flexible layout so the iframe renders correctly (e.g., `height: 720px` or `height: 100%`).


# Event Handing

The Floorplan SDK emits **global events** for interactions inside the embedded plan. Each event delivers a **unified payload** describing the targeted entity (space, room, wall perimeter, or area/background) and its position.

***

### Event names

```ts
export type FloorPlanEvents =
  | "click"
  | "right-click"
  | "double-click"
  | "hover"
  | "blur"
  | "plan-right-click"
  | "outside-click";
```

* **click / double-click / right-click** — Interaction on an entity.
* **hover / blur** — Pointer enters/leaves an entity.
* **plan-right-click** — Context menu on the plan canvas (not on a specific entity).
* **outside-click** — Click detected outside interactive entities (background).

***

### Payload shape

```ts
export type FloorPlanEntityType = "SPACE" | "WALL_PERIMETER" | "ROOM" | "AREA";

export type Center = {
  x: number;        // absolute pixels in canvas coords
  y: number;
  relativeX?: number; // 0..1 within canvas
  relativeY?: number; // 0..1 within canvas
};

export interface FloorPlanEntity<T extends Record<string, any> = {}> {
  id: string;
  type: FloorPlanEntityType;   // "SPACE" | "ROOM" | "WALL_PERIMETER" | "AREA"
  center?: Center;
  properties?: T & { locationId: string; layerId: string };
}

export type SpaceMetadata = any;
export type RoomMetadata = any;
export type WallPerimeterMetadata = any;
export type FloorPlanEntityMetadata =
  | SpaceMetadata
  | RoomMetadata
  | WallPerimeterMetadata;

interface FloorPlanEvent {
  event: FloorPlanEvents;
  id: string; // mirrors metadata.id
  metadata: FloorPlanEntity<FloorPlanEntityMetadata>;
}
```

* `metadata.type` identifies the target: **SPACE**, **ROOM**, **WALL\_PERIMETER**, or **AREA** (background).
* `properties.locationId` and `properties.layerId` help you route events per site/floor.
* `center` provides both pixel and relative coordinates for precise UI placement (e.g., tooltips, context menus).

***

### Subscribing & unsubscribing

```ts
// Subscribe
sdk.on(eventName: FloorPlanEvents, handler: (e: FloorPlanEvent) => void);

// Unsubscribe a specific handler
sdk.off(eventName: FloorPlanEvents, handler: (e: FloorPlanEvent) => void);

// Unsubscribe all handlers for an event
sdk.off(eventName: FloorPlanEvents);
```

***

### Vanilla JS example

```html
<div id="floorplan-root" style="width:100%;height:720px;"></div>
<script type="module">
  import Floorplan from "/node_modules/@gospace-ai/floorplan/dist/floorplan.es.js";

  const sdk = new Floorplan({
    key: "floorplan-root",
    access_token: "<short-lived-access-token>",
    location_id: "loc_123",
    layer_id: "layer_001",
  });

  const onClick = (e) => {
    const { event, id, metadata } = e;
    // Example: SPACE/ROOM selection
    if (metadata.type === "SPACE" || metadata.type === "ROOM") {
      console.log(`[${event}]`, id, metadata);
      // open details panel, booking flow, etc.
    }
  };

  const onPlanContext = (e) => {
    // Show a context menu at e.metadata.center
    console.log("[plan-right-click]", e.metadata.center);
  };

  sdk.on("click", onClick);
  sdk.on("double-click", onClick);
  sdk.on("right-click", onClick);
  sdk.on("plan-right-click", onPlanContext);

  // Optional: hover/blur for highlighting
  sdk.on("hover", (e) => {
    // highlight e.metadata.id
  });
  sdk.on("blur", (e) => {
    // remove highlight for e.metadata.id
  });

  // Outside clicks (background)
  sdk.on("outside-click", (e) => {
    // clear selections
  });

  sdk.init();

  // later:
  // sdk.off("click", onClick);
  // sdk.destroy?.();
</script>
```

***

### Filtering & patterns

**By entity type**

```ts
sdk.on("click", ({ metadata }) => {
  switch (metadata.type) {
    case "SPACE": /* handle desk/seat */ break;
    case "ROOM":  /* handle room      */ break;
    case "WALL_PERIMETER": /* ignore or inspect */ break;
    case "AREA":  /* background */ break;
  }
});
```

**Coordinate‑based UI**

```ts
sdk.on("right-click", ({ metadata }) => {
  const { x, y } = metadata.center || { x: 0, y: 0 };
  // position a context menu at (x, y)
});
```

**Debounce high‑frequency events**

```ts
let hoverT;
sdk.on("hover", (e) => {
  clearTimeout(hoverT);
  hoverT = setTimeout(() => {
    // lightweight hover preview
  }, 80);
});
```

***

### Security

Events are delivered from the embedded iframe via `postMessage`. The SDK validates the origin internally. If you attach your own `window.message` listeners, verify `event.origin === "https://floorplan.gospace.app"` before using payloads.


# 3D Mode

### Overview

{% columns %}
{% column width="58.333333333333336%" %}
In 3D Mode, the floorplan is rendered as an interactive, three-dimensional view, providing an elevated perspective of the space. Users can dynamically adjust the viewing angle by dragging, offering a more immersive experience for visualising layouts.

### Key Features

* **Elevated 3D View**: Displays the floorplan from an elevated angle, giving a realistic sense of depth.
* **Interactive Angle Adjustment**: Users can drag to rotate and change the viewing angle.
* **Space Allocations**: Displays none, one, or multiple space allocations (e.g., desks, private offices, meeting rooms) based on the provided spaces array.
* **No Layer-Specific Focus**: Shows the entire location without focusing on a specific layer.

### Configuration

* Trigger: Activated when layer\_id is not provided in the SDK configuration.
* Required Parameters:
  * **key**: ID of the container element.
  * **access\_token**: Valid JWT for authentication.
  * **location\_id**: Unique identifier for the location.
* Optional Parameters:
  * **zone\_id**: Highlights a specific zone if provided.
  * **room\_id**: Highlights a specific room if provided.
  * **spaces**: Array of space IDs to highlight (e.g., \['space1', 'space2']).
  * **dark\_mode**, **class\_name**, **title**: For UI customisation and accessibility.
    {% endcolumn %}

{% column %}

<div align="right"><figure><img src="/files/bWIDddo1yclrHiX4vWCZ" alt=""><figcaption></figcaption></figure></div>
{% endcolumn %}
{% endcolumns %}

### Behavior

* The floorplan renders in 3D, showing the entire location specified by location\_id.
* Users can interact by dragging to adjust the angle, providing a flexible view of the space.
* Highlighting of zones or rooms occurs if zone\_id or room\_id is provided.
* Space allocations are visualised if the spaces array is included.

### Use Case

Ideal for scenarios where users need a comprehensive, visually engaging view of a location, such as showcasing an entire office layout to clients or employees.

### Example

```javascript
const sdk = new gospaceFloorplan.FloorplanSDK({
  key: 'floorplan-container',
  access_token: 'client-specific-access-token',
  location_id: '12345',
  spaces: ['space1', 'space2'],
  dark_mode: true
});
sdk.init();
```


# 2D Mode

Overview

{% columns %}
{% column %}
In 2D Mode, the floorplan is rendered as a bird’s-eye view, providing a flat, top-down perspective of a specific layer of the location. This mode is optimised for detailed navigation and interaction with individual spaces.Key Features

* **Bird’s-Eye View**: Displays a 2D top-down view of the specified layer.
* **Zoom and Pan Navigation**: Users can zoom in/out and pan across the floorplan for detailed exploration.
* **Space Interaction**: Clicking a space triggers the **SPACE\_CLICKED** event, returning the space\_id.
* **Zone/Room Highlighting**: Highlights a specific zone or room if zone\_id or room\_id is provided.
* **Space Allocations**: Displays none, one, or multiple space allocations based on the spaces array.

### Configuration

* Trigger: Activated when layer\_id is provided in the SDK configuration.
* Required Parameters:
  * **key**: ID of the container element.
  * **access\_token**: Valid JWT for authentication.
  * **location\_id**: Unique identifier for the location.
  * **layer\_id**: Unique identifier for the specific layer (e.g., a floor).
    {% endcolumn %}

{% column %}

<figure><img src="/files/PiwMafLdRhChzf8GX5He" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

*
* Optional Parameters:
  * **zone\_id**: Highlights a specific zone if provided.
  * **room\_id**: Highlights a specific room if provided.
  * **spaces**: Array of space IDs to highlight (e.g., \['space1', 'space2']).
  * **dark\_mode**, **class\_name**, **title**: For UI customisation and accessibility.

### Behavior

* The floorplan renders a 2D view of the specified layer (layer\_id).
* Users can zoom and pan to navigate the floorplan.
* Clicking a space emits a **SPACE\_CLICKED** event with the space\_id:

  ```javascript
  sdk.on('SPACE_CLICKED', ({ space_id }) => {
    console.log('Space clicked:', space_id);
  });
  ```
* Specific zones or rooms are highlighted if zone\_id or room\_id is provided.
* Space allocations are visualised if the spaces array is included.

### Use Case

Perfect for applications requiring precise interaction with spaces, such as desk booking, meeting room selection, or space management within a specific floor.

### Example

```javascript
const sdk = new gospaceFloorplan.FloorplanSDK({
  key: 'floorplan-container',
  access_token: 'client-specific-access-token',
  location_id: '12345',
  layer_id: 'abc123',
  zone_id: 'abc1234',
  spaces: ['space1', 'space2']
});
sdk.on('SPACE_CLICKED', ({ space_id }) => {
  console.log('Space clicked:', space_id);
});
sdk.init();
```


# Dark Mode

The gospace Floorplan SDK ([@gospace-ai/floorplan](https://www.npmjs.com/package/@gospace-ai/floorplan)) supports a Dark Mode feature, allowing developers to enable a dark-themed user interface for the embedded floorplan. This enhances accessibility, improves visibility in low-light environments, and aligns with modern design preferences.

{% columns %}
{% column %}

<figure><img src="/files/MeHqM9dJo7A8SqLNEi4O" alt=""><figcaption></figcaption></figure>
{% endcolumn %}

{% column %}

<figure><img src="/files/0pwonDI0OTCf9AfQL8Ps" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

### Key Features

* Optional Dark Mode: Toggle a dark-themed UI for the floorplan to match your application’s aesthetic or user preferences.
* Seamless Integration: Applied via a single configuration parameter, with no additional setup required.
* Consistent Experience: Works in both 2D Mode and 3D Mode, ensuring a cohesive look across rendering modes.
* User-Friendly: Enhances readability and reduces eye strain for users in dark environments.

### Configuration

To enable Dark Mode, set the dark\_mode parameter to true when initialising the SDK:

### Example

```javascript
const sdk = new gospaceFloorplan.FloorplanSDK({
  key: 'floorplan-container',
  access_token: 'client-specific-access-token',
  location_id: '12345',
  layer_id: 'abc123', // Optional: Triggers 2D Mode
  dark_mode: true // Enables Dark Mode
});
sdk.init();
```

### Parameter Details

<table data-header-hidden><thead><tr><th width="111.26171875"></th><th width="86.5703125"></th><th width="328.84765625"></th><th width="93.046875"></th><th></th></tr></thead><tbody><tr><td>Parameter</td><td>Type</td><td>Description</td><td>Required</td><td>Default</td></tr><tr><td>dark_mode</td><td>boolean</td><td>Enables dark-themed UI for the floorplan</td><td>No</td><td>false</td></tr></tbody></table>

### Behavior

* When dark\_mode: true, the floorplan iframe (hosted at <https://floorplan.gospace.app>) renders with a dark color scheme, including darker backgrounds and adjusted text/icon colors.
* When dark\_mode: false (or omitted), the default light-themed UI is used.
* Dark Mode applies consistently in both 2D Mode (with layer\_id) and 3D Mode (without layer\_id).

### Use Case

* Aesthetic Alignment: Match the floorplan’s appearance to a dark-themed application.
* Accessibility: Improve usability for users in low-light settings or with visual preferences for darker interfaces.
* Branding: Create a cohesive look for applications targeting modern, dark-mode-friendly designs.

### Best Practices

* Dynamic Toggling: Allow users to toggle Dark Mode by reinitialising the SDK with updated dark\_mode values based on user preferences.
* Testing: Preview the floorplan in both light and dark modes to ensure visual clarity for all space allocations (e.g., desks, offices, meeting rooms).
* CSS Integration: Use the class\_name parameter to apply custom styles that complement Dark Mode.


# Use cases

* Workspace Management: Embed floorplans to display and manage desk assignments or office allocations for employees.
* Meeting Room Booking: Allow users to select and book meeting rooms directly from the floorplan.
* Space Utilisation Analytics: Highlight specific spaces (via spaces) to visualize occupancy or availability.


