# Keyspace Smart Building API > Keyspace is a smart-building platform (Bangkok, TH) providing meeting-room and desk booking, access control, and building automation. This server hosts the third-party REST API that partner applications use to search rooms/desks, create and manage bookings, handle payments, and run check-in/check-out — authenticated with OAuth 2.0 client credentials (app_id / app_secret). Key facts for integrators: - Base URLs: https://api.keyspace-dev.com (dev), https://api.keyspace-qat.com (UAT), https://api.keyspace.tech (production). Credentials are per-environment. This file is served by each environment — the documents linked below always describe the environment you fetched them from. - Auth: POST /auth/accessToken with {app_id, app_secret, grant_type: "app_credentials"}; refresh with grant_type "refresh_token". Derive expiry from expires_in — lifetimes are environment config. Advanced: grant_type "act_as" (+ subject = your own user id) exchanges app credentials for a SHORT-LIVED member-scoped token (per-user quotas/roles; scope = member ∩ app; no refresh token — re-run the grant; errors 403 KS221 / 401 KS223). Coordinated feature — details in /llms-full.txt. - Partner-managed members (apps that own their users, card numbers and face photos): PUT/GET/DELETE /partner/members/{yourUserId} + PUT /partner/members/{yourUserId}/credentials {cards?, face?, faceConsentAt?}. App-token only, single-project apps, own members only (403 KS221). PUT resolves to an EXISTING member first — link → email → phone → employeeId, first hit wins — and creates one only when nothing matches; a conflicting key is 409 KS006 with data.conflictKey. Office apps send employeeId (valid alone, no login); condo apps bind the home with unit {addressNo, zoneId?} (first resident = owner, later = participant; a unit never identifies a person). Access groups are fixed on the app at provisioning — never chosen via API. Card numbers default to Hikvision decimal-reversed; face = base64 JPEG/PNG ≤ 10 MB and REQUIRES faceConsentAt; a member with a face and no physical card gets ONE auto-generated card (generated: true) to print. Details in /llms-full.txt §5. - Every response except the token endpoint is wrapped as {code, success, message, data, meta?}; "KS000" = success. Errors carry a KSxxx code — 409 KS012 is a booking time-slot conflict (expected under contention; recoverable). - Availability search: GET /meeting-rooms?projectId=…&startDateTime=…&endDateTime=… returns rooms free for the window; per-day operating hours live in config.dayConfig. Desks: GET /desks with startDateTime plus exactly one of timePeriod (morning/afternoon/allDay) or endDateTime. - Booking: POST /meetings with meetingRoomId OR deskId. Paid rooms return status "unpaid" plus a webPaymentUrl/QR — payment is a human web flow with a ~5-minute window. pinCode in the create response is required for later operations by non-organizers; treat it as a secret. - No idempotency key on create — never blind-retry a timed-out POST /meetings; reconcile with GET /meetings. - Webhooks: register a listener server (via your Keyspace contact) and lifecycle events are POSTed to it — HMAC-SHA256 signed (X-Keyspace-Signature over timestamp.rawBody), 2xx-in-10s ack, 5 retries, unique X-Keyspace-Delivery id for dedupe. Endpoint auth: signature-only (default) / bearer / custom-header (one or many) / jwt (short-lived HS256 over the shared secret) on top of the always-sent signature. Catalog: ROOM_/DESK_ BOOK, MODIFY, CANCEL (cancelReason distinguishes user / no-show / payment-lapse), REMINDER, NO_SHOW_WARNING, ENDING_SOON; plus visitor events VMS_INVITE_SENT (carries qrCardCode = visitor access QR to relay), VMS_VISITOR_CHECKED_IN, VMS_HOST_CANCELLED. Details in /llms-full.txt. - Statuses change WITHOUT an API call: an unpaid booking auto-cancels when its ~5-minute payment window lapses, and an active booking nobody checks in to auto-cancels ~15 minutes after start (per-asset config.meetingConfig; postStartExpireMinutes -1 disables). A checked-in booking can NOT be cancelled — end it with check-out (organizer or pinCode). Re-fetch bookings around start/end times to reconcile. ## Docs - [Getting Started](/docs/onboarding.md): Platform start-here — credentials, token, response envelope, `act_as`, webhooks, and the index of per-module guides - [Meeting rooms & desks guide](/docs/guides/meeting.md): Booking journey (auth → find → book → pay → check-in/out), error strategy, timezones, sandbox + go-live checklists - [Members & credentials guide](/docs/guides/members.md): Partner-managed members — identity keys (office employeeId / condo unit), PUT member, cards + face (+ auto-generated card), offboarding, sandbox + go-live checklists - [Full API documentation](/llms-full.txt): Complete reference — authentication, `act_as`, partner members, meeting rooms, desks, meeting lifecycle (create/list/detail/update/cancel/check-in/check-out), webhooks, error codes - [OpenAPI 3.0 specification](/docs/openapi.json): Machine-readable spec of the third-party API surface — generate clients, mock servers, or agent tool definitions