REST API
Best for first-party backend integrations you directly control.
HAL now supports reusable public OAuth apps for widget hosting flows, plus the older private per-project client flow for one-off integrations.
Best for first-party backend integrations you directly control.
Best for external AI clients that should use HAL through tools.
Best for delegated third-party app access.
HAL-managed public apps are the default choice when an external backend needs to let many customers connect one HAL project at a time. The granted scope is intentionally narrow: widget:serve.
After the user approves the connection, the external backend receives an access token and refresh token. It can use that access token to ask HAL to sign widget identities without ever learning the project’s permanent identity_secret.
client_id, redirect_uri, scope=widget:serve, and the target project_id if you already know it./oauth/token./api/oauth/widget/sign-identity with the returned bearer token whenever you need a user_hash for widget identify().The public app token exchange returns:
access_tokenrefresh_tokentoken_type = Bearerexpires_inscope = widget:serveproject_idwidget_script_urlapi_base_url1. Redirect user to HAL authorize
2. Exchange code at POST /oauth/token
3. Sign identities at POST /api/oauth/widget/sign-identity
4. Pass user_hash into HalWidget.identify({ user_id, user_hash })
The older project-level OAuth client flow is still supported for private, one-off integrations created directly in HAL project settings. That legacy token exchange returns app_id and widget_secret instead of bearer tokens.
Use the private client flow only when the integration is owned by the same HAL customer and does not need a reusable public app registration.