PINs API
Overview
Section titled “Overview”PINs provide anonymous, shared-device access. Each project can have up to 10 active PINs.
List PINs
Section titled “List PINs”GET /admin/projects/:projectId/pinsAuthorization: Bearer <admin_token>Response
Section titled “Response”{ "pins": [ { "id": "pin_abc123", "label": "Living room TV", "status": "active", "privileges": ["view", "date-spots"], "created_at": "2025-04-01T12:00:00Z", "revoked_at": null }, { "id": "pin_def456", "label": "Old tablet", "status": "revoked", "privileges": ["view"], "created_at": "2025-02-15T09:00:00Z", "revoked_at": "2025-05-01T10:00:00Z" } ]}Create PIN
Section titled “Create PIN”POST /admin/projects/:projectId/pinsAuthorization: Bearer <admin_token>Content-Type: application/jsonRequest Body
Section titled “Request Body”| Field | Type | Required | Description |
|---|---|---|---|
pin | string | Yes | Numeric PIN (minimum 5 digits) |
label | string | Yes | Human-readable label |
privileges | string[] | No | Array of privilege strings (default: []) |
Example
Section titled “Example”curl -X POST https://auth.beshoy.ai/admin/projects/proj_trip/pins \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{ "pin": "84291", "label": "Bedroom tablet", "privileges": ["view", "edit", "date-spots"] }'Response
Section titled “Response”{ "id": "pin_xyz789"}Constraints
Section titled “Constraints”- PIN must be at least 5 digits (numeric only)
- Maximum 10 active PINs per project
- Label is required (helps identify which device/user)
Revoke PIN
Section titled “Revoke PIN”PATCH /admin/projects/:projectId/pins/:pinIdAuthorization: Bearer <admin_token>Content-Type: application/jsonRequest Body
Section titled “Request Body”{ "status": "revoked"}Response
Section titled “Response”{ "ok": true }Revocation Effects
Section titled “Revocation Effects”- Immediate: new PIN authentication attempts with this PIN are rejected
- On next refresh: existing sessions using this PIN receive
403 PIN revoked - Within 5 min: current access tokens expire naturally
Privileges
Section titled “Privileges”Privileges are arbitrary strings that your app interprets. The auth service embeds them in the PIN token but doesn’t enforce them. Common patterns:
["view"] // Read-only access["view", "edit"] // Full access["view", "date-spots"] // Read + specific feature accessYour app checks these in middleware or route handlers:
const { payload } = await jwtVerify(token, secret);const privileges: string[] = payload.privileges || [];
if (!privileges.includes('edit')) { return new Response('Forbidden', { status: 403 });}