# 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://developer.gospace.com/start-building/create-a-location/create-a-layer.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
