VEGA ACCESS

Vega Access API v0.1.0

Vega Access connects the access-control system of a property (doors, readers, keypads) to partner platforms such as guest-messaging, property-management and access-orchestration services. Every door is exposed as a lock with live state, remote lock/unlock, and scheduled guest PIN codes.

Partner credentials (client_id, client_secret, redirect URIs) are issued by Vega Access on request.

Authentication (OAuth 2.0 authorization code)

  1. Redirect the property operator to the authorization URL. prompt=login always forces a fresh sign-in; state is returned unchanged. PKCE (code_challenge, S256) is supported and optional.
  2. The operator signs in and approves the requested scopes.
  3. We redirect to your registered redirect_uri with code and state. Several redirect URIs can be registered per client (production, staging, localhost).
  4. Exchange the code at the token endpoint (client authentication via HTTP Basic or form fields).
GET https://connect.vhostico.com/oauth/authorize?response_type=code&client_id=YOUR_CLIENT_ID
  &redirect_uri=https%3A%2F%2Fpartner.example.com%2Foauth%2Fcallback
  &scope=locks.read%20locks.write&prompt=login&state=xyz123
POST https://api.vhostico.com/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=CODE&redirect_uri=https://partner.example.com/oauth/callback
&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET
{"access_token": "vat_...", "token_type": "Bearer", "expires_in": 3600,
 "refresh_token": "vrt_...", "scope": "locks.read locks.write", "user_id": "acct_4f0d2a9c61b7e835"}

user_id is a permanent account identifier: it never changes and does not depend on e-mail addresses. Access tokens live one hour. Refresh with grant_type=refresh_token: you get a new access token and the same refresh token; previously issued access tokens stay valid until they expire, so parallel workflows are never interrupted. Revoke a grant with POST /oauth/revoke (token=...).

Scopes:

Call the API with Authorization: Bearer <access_token>.

API reference

OAuth2

GET /oauth/authorize

Start authorization (login + consent page)

Host: https://connect.vhostico.com

POST /oauth/token

Exchange an authorization code or refresh token

Host: https://api.vhostico.com

POST /oauth/revoke

Revoke a refresh or access token (RFC 7009)

Host: https://api.vhostico.com

Locks

GET /locks

List all locks the account can access

Response

{"locks": [{"device_id": "lck_9f2c41d0a7b3e655", "lock_id": "lck_9f2c41d0a7b3e655", "name": "Room 101",
  "device_type": "smart_lock", "device_model": "Vega Access Door Controller", "online": true,
  "battery_level": null, "power_source": "wired", "timezone": "America/Toronto",
  "device_time": "2026-10-30T06:00:00Z", "lock_state": "locked", "door_state": "closed",
  "bridge_id": "site_2b8e0c71d9a4f312", "site_name": "Vega Demo Hotel", "address": "..."}]}

Host: https://api.vhostico.com

GET /locks/{lock_id}

Get one lock

Path: lock_id

Host: https://api.vhostico.com

POST /locks/{lock_id}/actions

Lock or unlock; result follows as lock.action_completed

Path: lock_id

FieldTypeRequiredNotes
actionstring one of lock, unlockyes
custom_idstring

Request

{"action": "unlock", "custom_id": "req_98aa221"}

Response

{"action_id": "act_23d1c0a95e7f4b18", "custom_id": "req_98aa221", "status": "pending",
 "lock_id": "lck_9f2c41d0a7b3e655", "action": "unlock"}

Host: https://api.vhostico.com

GET /actions/{action_id}

Get the status of a lock action

Path: action_id

Host: https://api.vhostico.com

Access codes

GET /locks/{lock_id}/access_codes

List codes on a lock

Path: lock_id

Host: https://api.vhostico.com

POST /locks/{lock_id}/access_codes

Create a PIN code; result follows as access_code.created

Path: lock_id

FieldTypeRequiredNotes
namestringyes
codestringyes4-8 digits, unique per property
starts_atstring (date-time)
ends_atstring (date-time)

Request

{"name": "Jane Lo", "code": "4829",
 "starts_at": "2026-11-02T20:00:00Z", "ends_at": "2026-11-05T16:00:00Z"}

Response

{"access_code_id": "ac_55301c2e9b0d7a41", "lock_id": "lck_9f2c41d0a7b3e655", "name": "Jane Lo",
 "code": "4829", "starts_at": "2026-11-02T20:00:00Z", "ends_at": "2026-11-05T16:00:00Z", "status": "pending"}

Host: https://api.vhostico.com

GET /access_codes/{access_code_id}

Get one code

Path: access_code_id

Host: https://api.vhostico.com

PATCH /access_codes/{access_code_id}

Change PIN, name or schedule; result follows as access_code.updated

Path: access_code_id

FieldTypeRequiredNotes
namestring
codestring
starts_atstring (date-time)
ends_atstring (date-time)

Request

{"ends_at": "2026-11-06T16:00:00Z"}

Response

{"access_code_id": "ac_55301c2e9b0d7a41", "status": "pending", ...}

Host: https://api.vhostico.com

DELETE /access_codes/{access_code_id}

Remove a code; result follows as access_code.deleted

Path: access_code_id

Response

{"access_code_id": "ac_55301c2e9b0d7a41", "status": "pending"}

Host: https://api.vhostico.com

Webhooks

GET /webhooks

Show the registered webhook

Host: https://api.vhostico.com

POST /webhooks

Register (or replace) the single webhook endpoint for this environment

FieldTypeRequiredNotes
urlstringyes
eventsarrayEvent types to receive; empty = all

Request

{"url": "https://partner.example.com/events",
 "events": ["lock.action_completed", "access_code.created", "access_code.used"]}

Response

{"webhook_id": "wh_11828a0c3f5e9d27", "url": "https://partner.example.com/events", "status": "active",
 "events": [...], "signing_secret": "whsec_..."}

Host: https://api.vhostico.com

DELETE /webhooks/{webhook_id}

Disable the webhook

Path: webhook_id

Host: https://api.vhostico.com

Service

GET /health

Liveness check

Host: https://api.vhostico.com

Webhooks & events

Register one webhook URL per environment with POST /webhooks, authenticated with your client credentials (HTTP Basic client_id:client_secret). Registering again replaces the URL and rotates the signing secret. Events for every account that has authorized your client are delivered to that URL; use user_id to route them.

{"event_id": "evt_7c1e5a0b93d24f68", "event_type": "lock.action_completed", "user_id": "acct_4f0d2a9c61b7e835",
 "device_id": "lck_9f2c41d0a7b3e655", "lock_id": "lck_9f2c41d0a7b3e655", "timestamp": "2026-10-30T06:00:02Z",
 "action_id": "act_23d1c0a95e7f4b18", "custom_id": "req_98aa221", "action": "unlock",
 "status": "success", "performed_via": "remote_api",
 "data": {"action_id": "...", "custom_id": "...", "action": "unlock", "status": "success", "performed_via": "remote_api"}}

Event types: device.added, device.removed, device.online, device.offline, bridge.online, bridge.offline, device.time_wrong, device.low_battery, lock.locked, lock.unlocked, lock.action_completed, door.opened, door.closed, access_code.created, access_code.updated, access_code.deleted, access_code.used, access_code.incorrect_attempt.

access_code.created / updated carry the full access_code object and status success or failed (with error_code). access_code.used includes access_code_id; access_code.incorrect_attempt includes the entered pin. performed_via is one of pin_code, mobile_app, remote_api, fob_card, bluetooth_key, manual_turn.

Errors

Errors use HTTP status codes and a JSON body:

{"error_code": "DEVICE_OFFLINE", "message": "The device is currently offline and cannot accept commands."}
error_codeHTTPMeaning
UNAUTHORIZED401Missing, expired or revoked access token
INSUFFICIENT_SCOPE403Token lacks the required scope
NOT_FOUND404Unknown lock, access code or action (or not in your account)
INVALID_REQUEST400Malformed body or missing field
INVALID_PIN_FORMAT400PIN must be 4-8 digits
INVALID_SCHEDULE400ends_at before starts_at, or in the past
PIN_CONFLICT409The PIN is already used on this door or by another guest at the property. The same guest (same name and schedule) may use one PIN on several doors.
DEVICE_OFFLINE409The door or the property controller is offline
CODE_BEING_REMOVED409The code is being deleted
RATE_LIMITED429Too many attempts

OAuth endpoints return standard OAuth errors ({"error": "invalid_grant", "error_description": "..."}).

PIN codes are unique per property. Updating a code that the same guest holds on several doors applies the change to all of those doors.