Add historic attendance

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

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

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”).

1) Send a single batch (no session)

Create add-historic-attendance.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:

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

Last updated

Was this helpful?