Reference

Endpoints

HTTP endpoint contract exposed by the server plugin.

The server plugin exposes these endpoints under endpointPrefix. The default prefix is /cross-device.

EndpointMethodPurpose
/cross-device/startPOSTStart a new order.
/cross-device/claimPOSTClaim an order from the approving device.
/cross-device/challengePOSTRead the challenge envelope.
/cross-device/approvePOSTSubmit a verified proof.
/cross-device/rejectPOSTReject from the approving device.
/cross-device/cancelPOSTCancel from the initiating device.
/cross-device/finalizePOSTFinalize an approved order.
/cross-device/eventsGETSubscribe to server-sent order events.

Start

Creates the order on the initiating device.

client.ts
await authClient.crossDevice.start({
  kind: "login",
  adapterId: "passkey",
  returnTo: "/dashboard",
  displayTitle: "Sign in",
  displaySummary: "Approve this sign-in on your phone.",
})

Returns:

FieldMeaning
orderIdPublic order id used by every later call.
claimTokenToken embedded in the approving-device claim URL.
claimUrlURL you show as a QR code, deep link, or copyable link.
eventTokenToken for the initiating device event stream.
desktopTokenToken for cancel and finalize from the initiating device.
expiresAtUnix timestamp in milliseconds.

Claim

Exchanges the claim token for a challenge token on the approving device.

claim-page.ts
await authClient.crossDevice.claim({
  orderId,
  claimToken,
})

Returns challengeToken.

Challenge

Reads the challenge envelope that your adapter prepared.

claim-page.ts
const challenge = await authClient.crossDevice.challenge({
  orderId,
  challengeToken,
})

The response includes action, nonce, origin, expiresAt, display text, adapter metadata, and the adapter-generated message.

Approve

Submits the adapter proof.

claim-page.ts
await authClient.crossDevice.approve({
  orderId,
  challengeToken,
  proof,
})

Returns { ok: true, orderId, status: "approved" }.

Reject

Rejects the order from the approving device.

claim-page.ts
await authClient.crossDevice.reject({
  orderId,
  challengeToken,
})

Returns { ok: true, orderId, status: "rejected" }.

Cancel

Cancels the order from the initiating device.

client.ts
await authClient.crossDevice.cancel({
  orderId,
  desktopToken,
})

Returns { ok: true, orderId, status: "cancelled" }.

Finalize

Consumes an approved order from the initiating device.

client.ts
await authClient.crossDevice.finalize({
  orderId,
  desktopToken,
})

For login orders, finalization applies the resolved Better Auth session and may return a token. For sign and transaction orders, finalization returns the approved proofArtifact.

Events

Subscribes to server-sent events for the initiating device.

client.ts
const source = authClient.crossDevice.subscribe({
  orderId,
  eventToken,
  onEvent(event, payload) {
    console.log(event, payload.status)
  },
})

Events: claimed, waiting_user, approved, rejected, expired, cancelled, finalized.

Errors

Client helpers return { data, error }. Endpoint errors include a message and may include a Better Auth status code.

CaseTypical result
Missing or wrong tokenUnauthorized response.
Expired orderConflict or not-ready response after lifecycle refresh.
Invalid proofUnauthorized response from CrossDeviceProofError.
Invalid transitionBad request or conflict response.
Copyright © 2026