# 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 %}
