Hosted connect flow

Linking a customer's lock-vendor account happens on lockapi-hosted pages, so your integration never handles vendor OAuth tokens, API keys, or passwords. It's the same shape as Stripe Connect's or Plaid's hosted onboarding: create a short-lived session, redirect the customer to it, get them back when it's done. This page drills into step 1 of Connect → devices → access codes.

1. Create a connect webview

Call this from your backend with your API key. The session is valid for 30 minutes — create a fresh one per linking attempt.

POST /v1/connect_webviews
Authorization: Bearer sk_live_...

{
  "provider": "NUKI",
  "customerRedirectUrl": "https://yourapp.com/properties/123/locks?linked=1"
}

provider picks the vendor and therefore which authentication method the hosted page shows (OAuth redirect, API token, username + password, 2FA, or device-claim — see Vendors). customerRedirectUrl is optional and is where the customer is sent when the flow ends — put your own context (property id, reservation ref) in its query string to pick things back up.

The response depends on the API key's mode:

// live key
{ "id": "cwv_...", "status": "PENDING", "url": "https://lockapi.dev/connect/<token>", "expiresAt": "..." }

// test key — no vendor to contact, so it's already done
{ "id": "cwv_...", "status": "COMPLETED", "connectedAccountId": "acc_...", "expiresAt": "..." }

2. Redirect the customer to url

Open it in the customer's browser (full-page redirect or a popup). They authenticate with the vendor on the hosted pages; lockapi stores the resulting credentials encrypted and pulls in the account's devices. Nothing sensitive passes through your app.

3. Handle completion

When the customer finishes they're sent to customerRedirectUrl(or a hosted result screen if you didn't set one). That redirect is a UX signal, not a trusted one — confirm the outcome server-side one of two ways:

GET /v1/connect_webviews/<id>

{
  "id": "cwv_...",
  "status": "COMPLETED",        // PENDING | COMPLETED | FAILED | EXPIRED
  "connectedAccountId": "acc_...",  // set once COMPLETED
  "failureReason": null,            // set when FAILED
  "expiresAt": "..."
}

Poll that endpoint until status leaves PENDING, or — better — subscribe to the connect_webview.completed and connect_webview.failed webhooks and skip polling. On COMPLETED, list the account's devices with GET /v1/devices?connected_account_id=<id> and start issuing access codes.

Test mode

With a sk_test_ key there is no vendor and no redirect: the webview is created already COMPLETED against the mock adapter, with a connectedAccountId and a handful of simulated devices. Use this to build and test the whole flow end to end before touching real hardware.