# SmartphoneKey API ## English - [SmartphoneKey API Documentation](https://smartphonekey.documentationai.com/introduction.md): API reference for the SmartphoneKey B2C API — secure, app-free access control for multifamily properties and short-term rentals using Apple Wallet and Google Wallet. - [Partner Portal](https://smartphonekey.documentationai.com/partner-portal.md): Self-service web UI where partners view their API key, rotate it, and configure their webhook URL. - [Partner Onboarding](https://smartphonekey.documentationai.com/partner-onboarding.md): How partners onboard themselves via the Partner Portal, plus the Admin API for scripted/automated onboarding. - [Common Workflows](https://smartphonekey.documentationai.com/common-workflows.md): Minimal step-by-step recipes for the most common B2C API operations — adding a key to a lock, making a lock appear in the mobile app, sending a wallet pass, and adding a resident to a doorbell. - [Matter Clusters](https://smartphonekey.documentationai.com/matter-clusters.md): Matter cluster attributes, device info fields, and supported commands for SmartphoneKey Matter devices. - [Reset 3dEye provisioning for a user](https://smartphonekey.documentationai.com/post-admin-threedeye-users-userid-reset.md): Clears the local threedeye_users/recovery rows (force re-provision) and optionally deletes the remote 3dEye account when visible in our customer. Requires dual auth: X-Admin-API-Key + JWT. - [Delete hub aggregate](https://smartphonekey.documentationai.com/delete-admin-cleanup-hubs-hubid.md): Admin-only endpoint for deleting a hub aggregate. Supports two modes: DELETE_DO_ONLY removes the Durable Object instance while preserving R2 events (state restored on next access), and DELETE_DO_AND_EVENTS archives all events then permanently removes the DO instance. Requires dual authentication: X-Admin-API-Key header and a JWT with @smartphonekey.com email domain. - [Delete lock aggregate](https://smartphonekey.documentationai.com/delete-admin-cleanup-locks-lockid.md): Admin-only endpoint for deleting a lock aggregate. Supports two modes: DELETE_DO_ONLY removes the Durable Object instance while preserving R2 events (state restored on next access), and DELETE_DO_AND_EVENTS archives all events then permanently removes the DO instance and D1 entries. The cascadeDeleteKeys parameter controls whether associated key_assignments are also removed. Requires dual authentication: X-Admin-API-Key header and a JWT with @smartphonekey.com email domain. - [Delete user aggregate](https://smartphonekey.documentationai.com/delete-admin-cleanup-users-userid.md): Admin-only endpoint for deleting a user aggregate. Supports two modes: DELETE_DO_ONLY removes the Durable Object instance while preserving R2 events (the state will be restored on next access), and DELETE_DO_AND_EVENTS archives all events to a timestamped folder then permanently removes the DO instance and D1 entries. Requires dual authentication: X-Admin-API-Key header and a JWT with @smartphonekey.com email domain. - [3dEye provisioning diagnostics for a user](https://smartphonekey.documentationai.com/get-admin-threedeye-users-userid.md): Read-only snapshot of a user's 3dEye provisioning state across D1 and 3dEye: the b2c user row, the threedeye_users mapping, any recovery row, and a live customer-scoped probe (user count + whether the email is visible). Requires dual auth: X-Admin-API-Key + JWT. - [Delete all aggregates (dev only)](https://smartphonekey.documentationai.com/post-admin-cleanup-delete-all.md): Admin-only endpoint that performs a complete environment wipe. Deletes all events from R2, removes all aggregates from D1 (users, locks, temp_keys), and cleans up Durable Object instances. API keys are preserved so subsequent tests still work. ONLY permitted in the dev environment — returns 403 Forbidden on stage or production. Requires dual authentication: X-Admin-API-Key header and a JWT with @smartphonekey.com email domain. - [Get in-memory decorator registries](https://smartphonekey.documentationai.com/get-admin-debug-registry.md): Admin-only debug endpoint that returns the current state of the in-memory decorator registries (routes registered by @Route, event handlers registered by @EventHandler, and projectors registered via registerProjector). Useful for verifying decorator pickup at runtime — e.g. to confirm a refactor did not silently drop routes. Requires dual authentication (X-Admin-API-Key + JWT with @smartphonekey.com email domain), same as /admin/cleanup/*. - [Force-sync every named shadow on a Thing through the EventBridge pipeline](https://smartphonekey.documentationai.com/post-admin-shadow-sync-thingname.md): Enumerates every named shadow on the target Thing (via AWS IoT `ListNamedShadowsForThing` + `GetThingShadow`), then invokes the `shadow_to_eventbridge` Lambda once per shadow with a synthetic Topic-Rule-SQL-shaped event. Lambda → EventBridge → `/admin/shadow-webhook` → SpacetimeDB populates `device_named_shadow` as if the hub had organically republished. Auth: X-Admin-API-Key + @smartphonekey.com JWT. - [Backfill 3dEye accounts for existing users](https://smartphonekey.documentationai.com/post-admin-backfill-threedeye.md): Finds users without 3dEye accounts and creates them. Requires admin auth. - [Test error handling](https://smartphonekey.documentationai.com/get-admin-test-error.md): Admin-only debug endpoint that intentionally throws different types of errors to verify Sentry integration and error reporting pipelines. Supports synchronous errors, asynchronous errors, TypeError (property access on undefined), and validation errors. This endpoint should never return a 200 response in normal usage. Requires dual authentication: X-Admin-API-Key header and a JWT with @smartphonekey.com email domain. - [Trigger projection resync for all aggregates via Workflow](https://smartphonekey.documentationai.com/post-admin-resync-projections.md): Lists all aggregate IDs from R2 and starts a Cloudflare Workflow that processes DOs in small batches with configurable delays to avoid overwhelming SpacetimeDB. Returns the workflow instance ID for status tracking. Optionally filter by aggregate type. Requires dual auth: X-Admin-API-Key + JWT. - [Get 3dEye credentials for a user](https://smartphonekey.documentationai.com/get-users-id-3deye-credentials.md): Returns the stored 3dEye user GUID and password for the b2c user. Lazy-creates the 3dEye account on first call. Auth: JWT or B2B X-API-Key, same as the rest of the user-scoped routes. - [Get MQTT debug messages](https://smartphonekey.documentationai.com/get-locks-id-debug-messages.md): Get captured MQTT messages for a lock (used for smoke tests) - [Add key to lock](https://smartphonekey.documentationai.com/post-locks-id-addkey.md): Adds a key to the lock and sends command to device via AWS IoT Shadow - [Add resident to doorbell list](https://smartphonekey.documentationai.com/post-locks-id-addresident.md): Adds a resident who will receive notifications when doorbell is activated. The resident must already exist in user_state (call GET /users/by-email first if not). - [Change lock UUID (super API key only)](https://smartphonekey.documentationai.com/post-locks-id-changelockuuid.md): Changes the hardware/device UUID of an existing lock. Restricted to super API keys only (SmartphoneKey internal use). Non-super API keys receive 403 Forbidden. - [Create new lock](https://smartphonekey.documentationai.com/post-locks-id-createlock.md): Creates a new lock aggregate - [Open lock](https://smartphonekey.documentationai.com/post-locks-id-openlock.md): Sends unlock command to device via AWS IoT Shadow. Returns 502 if shadow update fails. - [Remove key from lock](https://smartphonekey.documentationai.com/post-locks-id-removekey.md): Removes a key from the lock and sends command to device via AWS IoT Shadow - [Remove resident from doorbell list](https://smartphonekey.documentationai.com/post-locks-id-removeresident.md): Removes a resident from the doorbell notification list. - [Set lock organization](https://smartphonekey.documentationai.com/post-locks-id-setorganization.md): Assigns an organization to a lock - [Set lock owner](https://smartphonekey.documentationai.com/post-locks-id-setowner.md): Assigns a user as the owner of the lock - [Write key to lock firmware](https://smartphonekey.documentationai.com/post-locks-id-writekey.md): Sends write-key command to device via AWS IoT Shadow to write key data to physical lock hardware. Returns 502 if shadow update fails. - [Bulk add keys to a lock via workflow](https://smartphonekey.documentationai.com/post-locks-id-bulkaddkeys.md): Starts a Cloudflare Workflow that adds multiple keys to a lock. Keys are added sequentially with a 1-second delay between commands. Each key addition is a durable step that retries on failure. - [Create temporary web access key](https://smartphonekey.documentationai.com/post-locks-id-create-temp-key.md): Creates a temporary web key for time-limited, shareable lock access. B2C requires lock owner, B2B requires org match. - [Delete temporary web access key](https://smartphonekey.documentationai.com/post-locks-id-delete-temp-key.md): Deletes a temporary web key. B2C requires lock owner, B2B requires org match. - [Get basic lock info](https://smartphonekey.documentationai.com/get-locks-id-basic-info.md): Get basic lock information without keys and residents - [Get lock details](https://smartphonekey.documentationai.com/get-locks-id-details.md): Get full lock details including keys and residents - [Get lock event history](https://smartphonekey.documentationai.com/get-locks-id-events.md): Returns paginated event history from R2. Default: last 10 events. Use ?page=N for older events. - [Get residents list](https://smartphonekey.documentationai.com/get-locks-id-residents.md): Get residents list for doorbell notifications (public endpoint) - [List temporary keys for lock](https://smartphonekey.documentationai.com/get-locks-id-temp-keys.md): Returns all temporary keys for the lock with computed status (valid, expired, used-up, not-yet-valid). - [Update temporary web access key](https://smartphonekey.documentationai.com/post-locks-id-update-temp-key.md): Updates a temporary web key. Can modify dates, max uses, whitelist, and access mode. B2C requires lock owner, B2B requires org match. - [Record temporary web access key usage](https://smartphonekey.documentationai.com/post-locks-id-use-temp-key.md): Appends a TempKeyUsed audit event to the lock event stream (partner fan-out). Internal command issued by the temp-key open flow. - [Get a single physical key by number](https://smartphonekey.documentationai.com/get-users-id-physicalkeys-number.md): Returns the user's physical-key entry with the given number, or 404 if no such entry exists. - [Get wallet install URL](https://smartphonekey.documentationai.com/get-users-id-wallet-link.md): Returns a URL the user can open to install their existing wallet key into Apple Wallet or Google Wallet. Returns 404 if no wallet key is set. - [Get camera role details](https://smartphonekey.documentationai.com/get-camera-roles-id-details.md): Get full camera role details including users and cameras arrays - [Get camera details](https://smartphonekey.documentationai.com/get-cameras-id-details.md): Get full camera details including status and 3dEye identifiers - [Get camera streaming URLs](https://smartphonekey.documentationai.com/get-cameras-id-stream.md): Fetches live streaming URLs (HLS, DASH, RTMP, thumbnail, snapshot) from 3dEye for a specific camera. Requires the authenticated user to have View permission on the camera. - [Get LPR event history](https://smartphonekey.documentationai.com/get-cameras-id-lpr-events.md): Returns paginated license plate recognition audit history for a camera. Supports from/to date filters. - [Get hub status](https://smartphonekey.documentationai.com/get-hubs-id-status.md): Get hub status including real-time online/offline from Thing Shadow - [Get accessible locks](https://smartphonekey.documentationai.com/get-users-id-accessible-locks.md): Get locks accessible by the user - [Get license plates](https://smartphonekey.documentationai.com/get-users-id-license-plates.md): Get the user's registered license plates for LPR automation - [Get locks owned by the user](https://smartphonekey.documentationai.com/get-users-id-owned-locks.md): Returns locks where `LockAggregate.state.ownerId === user.userId`, sourced from the SpacetimeDB `device_state` read model. - [Get devices linked to a user](https://smartphonekey.documentationai.com/get-users-id-devices.md): Returns the user's linked devices. Optional `?type=` query param filters by device kind. API-key (B2B) requests are auto-scoped to the key's orgId; JWT (B2C) callers see all of the user's devices. - [Get user keys](https://smartphonekey.documentationai.com/get-users-id-keys.md): Get user's physical and digital keys - [Get a user's phone number](https://smartphonekey.documentationai.com/get-users-id-phone-number.md): Returns the user's phone number from D1 (null if none on file). - [Get user profile](https://smartphonekey.documentationai.com/get-users-id-profile.md): Get user's profile information (name, email, status) - [Get user wallet status](https://smartphonekey.documentationai.com/get-users-id-wallet.md): Get user's wallet status and wallet key details - [List / search the user's physical keys](https://smartphonekey.documentationai.com/get-users-id-physicalkeys.md): Lists physical-key entries for the user. Optional filters: `orgId` (exact), `orgName` (exact), `q` (case-insensitive substring match on `note`). Filters combine with AND. Capped at 100 entries; `total` reflects filtered count before the cap. - [List cameras accessible to the authenticated user](https://smartphonekey.documentationai.com/get-cameras-my.md): Returns all cameras the authenticated B2C user can access via their camera role memberships. Permissions from multiple roles for the same camera are merged into a single entry. - [Find user by email address](https://smartphonekey.documentationai.com/get-users-by-email.md): Looks up a user by email address. If the user does not exist, creates them in both D1 (read model) and UserAggregate (event sourcing). This endpoint is idempotent — safe to call multiple times for the same email. - [Find user by phone number](https://smartphonekey.documentationai.com/get-users-by-phone.md): Looks up a user by their phone number in D1. Returns 404 if no user has that number. Unlike /users/by-email this never creates a user — a phone number alone is not enough to provision one. - [Grant lock access to user](https://smartphonekey.documentationai.com/post-users-id-addaccessiblelock.md): Grants a user access to a lock with specified access level (OWNER, ADMIN, USER, GUEST). - [Link a device to a user](https://smartphonekey.documentationai.com/post-users-id-adddevice.md): Records a cross-reference between a user and a device aggregate (Matter bridge or 3dEye camera) along with the device's org. - [Add license plate to user](https://smartphonekey.documentationai.com/post-users-id-addlicenseplate.md): Adds a license plate to the user profile for LPR automation. Plates are normalized (uppercase, no spaces/dashes) and deduplicated. - [Add a physical key to the user inventory](https://smartphonekey.documentationai.com/post-users-id-addphysicalkey.md): Records that a physical key has been issued to the user by some organisation. Server assigns a per-user autoincrement `number` (returned in the response) which is never reused after removal. - [Add wallet key to user](https://smartphonekey.documentationai.com/post-users-id-addwalletkey.md): Prepares a wallet key for a user (Apple Wallet or Google Wallet). The server generates the wallet keyId (UUID) inside the command handler and returns it in the response; clients must not send keyId in the request body. - [Create new user](https://smartphonekey.documentationai.com/post-users-id-createuser.md): Creates a new user aggregate with initial profile data. - [Revoke lock access from user](https://smartphonekey.documentationai.com/post-users-id-removeaccessiblelock.md): Revokes a user's access to a lock. - [Unlink a device from a user](https://smartphonekey.documentationai.com/post-users-id-removedevice.md): Removes the cross-reference between a user and a device aggregate. The device aggregate itself is not touched. - [Remove license plate from user](https://smartphonekey.documentationai.com/post-users-id-removelicenseplate.md): Removes a license plate from the user's profile. - [Remove a physical key from the user inventory](https://smartphonekey.documentationai.com/post-users-id-removephysicalkey.md): Removes the physical-key entry with the given `number` from the user's inventory. The next-number counter is NOT decremented — numbers are never reused after removal. - [Set or remove a user's phone number](https://smartphonekey.documentationai.com/post-users-id-updatephonenumber.md): Writes the phone number (PII) to D1 and emits a UserPhoneNumberUpdated audit event carrying only a masked (last-4) form — the raw number never enters the event log. Pass phoneNumber as a string to set it, or null to remove it. - [Webhook: create user from external event](https://smartphonekey.documentationai.com/post-users.md): Handles Auth0 webhook events for user sign-up or first-time login. Ensures the user exists in both D1 (read model) and UserAggregate (event sourcing). Called automatically by Auth0 post-login/post-registration flows. - [Assign camera to role](https://smartphonekey.documentationai.com/post-camera-roles-id-assigncamera.md): Assigns a camera with permissions to the role in 3dEye and persists the assignment event. - [Assign user to camera role](https://smartphonekey.documentationai.com/post-camera-roles-id-assignuser.md): Assigns a user to the role in 3dEye and persists the assignment event. - [Create camera role](https://smartphonekey.documentationai.com/post-camera-roles-id-createcamerarole.md): Creates a role in 3dEye and persists the creation event. - [Delete camera role](https://smartphonekey.documentationai.com/post-camera-roles-id-deletecamerarole.md): Deletes the role from 3dEye and persists the deletion event. - [Remove camera from role](https://smartphonekey.documentationai.com/post-camera-roles-id-removecamera.md): Removes a camera from the role in 3dEye and persists the removal event. - [Remove user from camera role](https://smartphonekey.documentationai.com/post-camera-roles-id-removeuser.md): Removes a user from the role in 3dEye and persists the removal event. - [Delete camera](https://smartphonekey.documentationai.com/post-cameras-id-deletecamera.md): Deletes the camera from 3dEye and persists the deletion event. - [Disable camera](https://smartphonekey.documentationai.com/post-cameras-id-disablecamera.md): Soft-disables a camera without deleting it from 3dEye. - [Link camera to lock](https://smartphonekey.documentationai.com/post-cameras-id-linkcameratolock.md): Links a camera to a lock for LPR automation (camera sees plate, lock opens). - [Register camera](https://smartphonekey.documentationai.com/post-cameras-id-registercamera.md): Registers a camera in 3dEye and persists the registration event. - [Unlink camera from lock](https://smartphonekey.documentationai.com/post-cameras-id-unlinkcamerafromlock.md): Removes the lock association from a camera. - [Update camera](https://smartphonekey.documentationai.com/post-cameras-id-updatecamera.md): Updates camera details in 3dEye and persists the update event. - [Claim hub](https://smartphonekey.documentationai.com/post-hubs-id-claimhub.md): Claims a provisioned hub and binds it to Organization and Site - [Commission device on hub](https://smartphonekey.documentationai.com/post-hubs-id-commissiondevice.md): Sends a commission_with_code command to the hub via AWS IoT Shadow. The hub performs Matter device commissioning and reports the result asynchronously. - [Provision hub](https://smartphonekey.documentationai.com/post-hubs-id-provisionhub.md): Registers a manufactured hub in the backend. The IoT Thing must already exist in AWS IoT (created during manufacturing). - [Re-claim hub](https://smartphonekey.documentationai.com/post-hubs-id-reclaimhub.md): Re-claims a hub to a different Organization and Site - [Send hub command](https://smartphonekey.documentationai.com/post-hubs-id-sendhubcommand.md): Sends hub-level commands (get_nodes, server_info, set_wifi_credentials) - [Set hub role](https://smartphonekey.documentationai.com/post-hubs-id-sethubrole.md): Sets whether the hub is primary or secondary - [Suspend hub](https://smartphonekey.documentationai.com/post-hubs-id-suspendhub.md): Suspends a hub temporarily - [Create matter device](https://smartphonekey.documentationai.com/post-matter-devices-id-creatematterdevice.md): Registers a new Matter device in the system - [Update reported shadow](https://smartphonekey.documentationai.com/post-matter-devices-id-updatereportedshadow.md): Stores the reported shadow state received from the device via AWS IoT - [Update desired shadow](https://smartphonekey.documentationai.com/post-matter-devices-id-updatedesiredshadow.md): Sets desired shadow state and pushes to AWS IoT Core - [Delete an RTSP camera](https://smartphonekey.documentationai.com/post-rtsp-cameras-id-deletertspcamera.md): Soft-deletes an RTSP camera aggregate (status transitions to Deleted) - [Register a new RTSP camera](https://smartphonekey.documentationai.com/post-rtsp-cameras-id-registerrtspcamera.md): Creates a new RTSP camera aggregate for a simple plug-and-play camera - [Open lock via temp key](https://smartphonekey.documentationai.com/post-temp-keys-uuid-open.md): Validates a temporary key (expiration, usage limits, authorization) and sends an OpenLock command to the LockAggregate Durable Object. On success, increments the usage counter and redirects back to the temp key page. Public keys need no auth; user-whitelist keys require a JWT with a whitelisted userId. - [Render temp key confirmation page](https://smartphonekey.documentationai.com/get-temp-keys-uuid-confirmation.md): Returns an HTML page confirming the door open command was sent. Displays lock info and a link back to the temp key page. - [Render temp key web page](https://smartphonekey.documentationai.com/get-temp-keys-uuid.md): Returns an HTML page for a temporary key link. Validates the key status (expiration, usage limits, user authorization) and renders the appropriate UI. Public keys are accessible without authentication; user-whitelist keys require a valid JWT. - [Events Overview](https://smartphonekey.documentationai.com/events-overview.md): How SmartphoneKey uses EventBridge to publish real-time events for partner integrations. - [Event Catalog](https://smartphonekey.documentationai.com/events-catalog.md): Reference documentation for SmartphoneKey EventBridge events available to partners. - [Partner Webhooks](https://smartphonekey.documentationai.com/events-webhooks.md): How to receive SmartphoneKey events via HTTP webhooks — configuration, authentication, delivery, and retry behavior. ## Ελληνικά - [Τεκμηρίωση API SmartphoneKey](https://smartphonekey.documentationai.com/el/introduction.md): Αναφορά API για το B2C API της SmartphoneKey — ασφαλής έλεγχος πρόσβασης χωρίς εφαρμογή για συγκροτήματα κατοικιών και βραχυχρόνιες μισθώσεις, με χρήση Apple Wallet και Google Wallet. - [Partner Portal](https://smartphonekey.documentationai.com/el/partner-portal.md): Self-service web περιβάλλον όπου οι εταίροι βλέπουν το API key τους, το περιστρέφουν (rotate) και ρυθμίζουν το webhook URL τους. - [Onboarding Εταίρων](https://smartphonekey.documentationai.com/el/partner-onboarding.md): Πώς οι εταίροι κάνουν onboarding μόνοι τους μέσω του Partner Portal, καθώς και το Admin API για αυτοματοποιημένο/scripted onboarding. - [Συνηθισμένες Ροές Εργασίας](https://smartphonekey.documentationai.com/el/common-workflows.md): Ελάχιστες, βήμα-προς-βήμα συνταγές για τις πιο συνηθισμένες λειτουργίες του B2C API — προσθήκη κλειδιού σε κλειδαριά, εμφάνιση κλειδαριάς στην εφαρμογή, αποστολή wallet pass και προσθήκη ενοίκου σε κουδούνι. - [Matter Clusters](https://smartphonekey.documentationai.com/el/matter-clusters.md): Attributes των Matter clusters, πεδία πληροφοριών συσκευής και υποστηριζόμενες εντολές για τις συσκευές Matter της SmartphoneKey. - [Επισκόπηση Events](https://smartphonekey.documentationai.com/el/events-overview.md): Πώς η SmartphoneKey χρησιμοποιεί το EventBridge για να δημοσιεύει real-time events για ενσωματώσεις εταίρων. - [Event Catalog](https://smartphonekey.documentationai.com/el/events-catalog.md): Τεκμηρίωση αναφοράς για τα events του EventBridge της SmartphoneKey που είναι διαθέσιμα στους εταίρους. - [Partner Webhooks](https://smartphonekey.documentationai.com/el/events-webhooks.md): Πώς να λαμβάνετε events της SmartphoneKey μέσω HTTP webhooks — ρύθμιση, αυθεντικοποίηση, παράδοση και συμπεριφορά retry.