HappierDocs
Accounts, machines and sharing

Connected services

Link provider subscriptions and API keys to Happier, reuse them across supported backends, and monitor quota snapshots where available.

Connected services let you store provider credentials once in Happier and then reuse them across supported backends and sessions.

They are different from provider authentication in provider settings:

  • Connected services are stored in Happier and can be reused across compatible backends
  • Provider authentication reflects the native login state of a provider CLI on one specific machine

See Provider authentication.

They exist so you can:

  • connect subscriptions and API keys without manually re-entering them for every backend
  • keep credentials encrypted in Happier Cloud and decrypt them only on the client / daemon
  • choose per-service auth at session start instead of relying only on each backend's native auth
  • monitor usage / quota snapshots for supported services
  • make multi-machine workflows easier when the target machine should reuse the same Happier-managed credential

What a connected service is

Happier models different credential types as distinct connected services:

  • openai-codex: OpenAI Codex subscription auth
  • openai: OpenAI API key auth
  • claude-subscription: Claude subscription auth
  • anthropic: Anthropic API key auth
  • gemini: Gemini OAuth auth
  • github: GitHub token auth for source-control workflows

This split is intentional. Subscription auth and API-key auth have different provider behavior, billing paths, and backend materialization requirements, so Happier does not merge them into a single generic "Claude" or "OpenAI" credential type.

GitHub is the first connected service that is not an agent/backend credential. It is used by source-control features such as GitHub repository publishing and GitHub pull request operations.

Where you manage them

In the app:

  • Settings -> Connected services

From there you can:

  • add one or more profiles for the same service
  • give profiles custom labels
  • set a default profile per service
  • inspect profile details such as provider email, account id, and quota meters
  • disconnect individual profiles

In the CLI:

  • happier connect status
  • happier connect codex ...
  • happier connect claude ...
  • happier connect gemini

Model-capacity retries

In development builds, a terminal model-capacity failure such as Codex server_overloaded keeps the same session and selected model. Happier waits before retrying, with longer delays for consecutive capacity failures: the initial delay is about five seconds and the exponential schedule levels off at about five minutes. Each delay varies by up to 20% to spread retries across sessions. A provider-supplied retry time can extend the wait.

Capacity retries have no attempt limit. A continuation being accepted or queued does not reset the delay; a successfully completed model turn does. Authentication failures and exhausted subscription quota follow their separate recovery paths. Stopping retries or stopping the session takes precedence over automatic recovery.

Automatic quota resets for Codex pools

In development builds with a supporting relay, a Codex subscription pool's Behavior section includes Automatically use quota resets. It is off by default. Enabling it authorizes spending a banked reset only after ordinary recovery finds no ready pool account and a quota-exhausted account is eligible for a reset. Normal account selection and session continuation still apply; the setting does not authorize resets for authentication failures or unrelated cooldowns.

The option is hidden on older relays and for services without banked resets. Turning it off prevents future automatic spending; it cannot restore a reset already consumed. If a reset response is lost or cannot confirm the outcome, Happier pauses further automatic resets for that account for the current daemon lifetime; a newer quota observation alone does not authorize another credit.

Confirmed automatic spending sends a notification through your enabled quota-recovery notification channels, identifying the account and pool. This reports that a reset was used; session recovery may still be in progress. Uncertain outcomes do not send a success notification, and replaying the same receipt does not send another one.

Connection methods

OpenAI Codex

Supported methods:

  • device code
  • paste redirect URL
  • in-app browser on native only

OpenAI Codex can also be connected with an API key, but that is modeled as the separate openai service.

OpenAI API key

Supported methods:

  • manual API key entry

Use this when you want OpenAI-backed backends to run against your own API key instead of your Codex subscription login.

Claude subscription

Supported methods:

  • setup-token
  • paste redirect URL
  • in-app browser on native only

Setup-token is the recommended default. Generate it on any machine already logged into Claude Code:

claude setup-token

Then paste it into Happier.

Anthropic API key

Supported methods:

  • manual API key entry

This is the Anthropic Console API-key path. It is separate from claude-subscription.

Gemini

Supported methods:

  • paste redirect URL
  • in-app browser on native only

GitHub

Supported methods:

  • token / Personal Access Token entry
  • local GitHub CLI auth outside Connected services

A connected GitHub token lets Happier use GitHub REST APIs for:

  • publishing a local repository to GitHub
  • listing and opening pull requests for the current branch
  • creating or reusing pull requests

The local gh CLI is not stored as a connected service. If gh is already installed and authenticated with gh auth login, Happier can use it as an optional fallback for GitHub source-control workflows.

Current GitHub OAuth note:

  • GitHub OAuth/device flow is not enabled in this build.
  • Use a GitHub token in Connected services, or authenticate the local gh CLI.

GitLab is not currently a connected service in Happier. GitLab merge-request workflows use an authenticated local glab CLI when available, or a no-auth compare URL fallback.

Why web behaves differently

Happier does not use embedded OAuth capture on web. Web falls back to paste-based flows because a browser app cannot reliably auto-capture provider redirects to localhost.

Backend compatibility

Connected services are not global "works everywhere" credentials. Each backend declares which service ids and credential kinds it can consume.

BackendSupported connected services
Claudeclaude-subscription (setup-token or OAuth), anthropic (API key)
Codexopenai-codex (OAuth), openai (API key)
Geminigemini (OAuth)
OpenCodeopenai-codex (OAuth), openai (API key), claude-subscription (setup-token only), anthropic (API key)
Piopenai-codex (OAuth), openai (API key), claude-subscription (OAuth or setup-token), anthropic (API key)

Important limitations:

  • OpenCode accepts claude-subscription only when the profile is a setup-token profile, not a Claude OAuth profile.
  • Pi accepts claude-subscription OAuth and setup-token profiles. Claude subscription OAuth is materialized into Pi's isolated auth.json; setup-token profiles are materialized as Pi API-key credentials.
  • anthropic is API-key only in Happier.
  • github is not consumed by agent backends. It is consumed by source-control workflows.

Source-control compatibility

Source-control workflowPreferred credentialFallback
Publish repository to GitHubConnected github tokenAuthenticated gh CLI
GitHub pull requestsConnected github tokenAuthenticated gh CLI, then compare URL
GitLab merge requestsNot a connected service todayAuthenticated glab CLI, then compare URL
Bitbucket pull requestsNot a connected service todayCompare URL only

This means a user who already has gh installed and authenticated can use GitHub PR/publish features without connecting GitHub in Happier first. Connecting GitHub is still the preferred cross-machine path because the credential can be reused by the daemon on the target machine.

Using connected services in the new-session flow

If the selected backend supports connected services, the new-session screen shows an auth picker.

That picker is dynamic:

  • it appears only for backends that support connected services
  • it shows only services compatible with the selected backend
  • it shows only connected profiles that are valid for that backend
  • it lets you choose native auth or connected auth for each compatible service

If no compatible connected profile exists for a service, Happier keeps that service on native auth and offers a shortcut to open Connected services settings.

Claude configuration sharing

In development builds with the configuration-sharing correction, Claude connected accounts and pools honor the configured sharing mode. Linked configuration is the default: shareable entries such as skills, hooks and settings point to the machine's native Claude configuration, including a custom CLAUDE_CONFIG_DIR when configured. File changes are visible through those links without reconnecting the account. Claude may still need to reload a setting before using its new value.

Copied configuration is refreshed whenever Happier materializes the account home, even when its credential has not changed. Isolated configuration imports none of these entries. On systems where a configuration link cannot be created, Happier falls back to copying that entry.

Credentials and account metadata remain separate from configuration sharing. Session-history sharing follows its own setting; changing configuration sharing does not opt in to workspace trust or change that history policy.

Instructions, plugins, and hook trust in development builds

The development correction for missing configuration also includes Claude's user-level CLAUDE.md and Codex's installed plugins directory in linked and copied configuration. Existing managed homes receive these entries the next time Happier materializes them; isolated configuration does not import them.

Codex hook decisions use the path of the file defining the hook. When copying home-level hooks into a managed home, Happier translates those path keys and preserves the existing trust hashes and disabled choices. Decisions already made in that managed home take precedence. Codex still checks the hook contents: an edited hook is not automatically trusted. This applies to hooks in hooks.json and config.toml, without changing project-level trust.

Connected services and browsing sessions (Codex)

For some providers, your connected-service choice affects which provider “home” Happier should use for session browsing.

The most important example is Codex:

  • With native auth, Happier browses sessions from the machine’s standard Codex home.
  • With a connected service profile selected for Codex, Happier browses sessions from that connected-service-backed Codex home.

This matters in two places:

  • Direct → Browse provider sessions: you can explicitly choose a source/home when browsing.
  • Browse sessions: the picker is locked to the effective Codex home implied by your new-session selection, so the session you choose is one that can actually resume under that auth.

If you need to browse a different Codex home, switch the auth choice first and then browse again.

Connected services and session handoff

Connected services are often the easiest way to preserve session continuity across machines.

Why:

  • the credential is stored in Happier, not only in one machine-local provider login
  • compatible backends can materialize that credential again on another machine
  • you can hand off the same Happier session and continue without depending only on native provider CLI auth on the destination

This is especially useful for:

  • moving a session from one desktop/laptop to another
  • moving between a host machine and a VM
  • keeping continuity when only one side had previously been set up through the app

Connected services do not replace every native provider login flow. Some providers and runtimes still depend on machine-local authentication. But for supported backends, connected services are the preferred path for cross-machine continuity.

See:

Profiles, defaults, and labels

Each connected service can have multiple profiles, for example:

  • a personal OpenAI subscription and a work OpenAI subscription
  • multiple Anthropic API keys
  • multiple Claude setup-token profiles

For each service you can:

  • set one default profile
  • override the default at session start
  • assign a friendly label so the auth picker can show something clearer than just work or default

Account pools

A pool groups several accounts for the same service and decides which one should be handling work right now. It is the answer to running out of quota mid-turn: instead of the session stopping until a reset, the pool moves to another account and carries on.

Pools are shared by every session using them. When one session discovers the active account is exhausted, the pool selects a replacement and the other sessions bound to that pool adopt it, rather than each rediscovering the same dead account.

Choosing which account is active

StrategyWhat it does
Expiring quota first (development default)Prefers usable quota whose allowance resets or non-renewing subscription ends soonest, with enough headroom.
Least limitedPicks whichever member has the most quota left.
PriorityUses your ordering, falling back down the list.
ManualNever chooses for you; you pick.

The expiry-first choice requires a server advertising connectedServices.poolExpiryFirst. It is the default for new pools in development builds; existing saved strategies are preserved. It prefers accounts above the pool's low-quota threshold before comparing dates, using the longest selected usage window rather than an incidental short reset. Missing or stale dates are neutral. It chooses on the next needed switch, without adding scheduled swaps or restarting the agent.

Reorder members to set the fallback order, and enable or disable individual accounts without removing them.

If a provider reports more than one independent allowance, the pool's Usage limits row can either track every allowance reported by enabled pool accounts now or later (the default) or a selected set. While enabled-account usage is refreshing, the selector marks the reported-limit list as potentially incomplete. For example, a separate Spark or Fable allowance can have its own pool without changing the model of any running session. Limits that an enabled account is not currently reporting stay visible in the selection and are treated as unknown, rather than silently falling back to every allowance.

Pool member capacity, usage rows, and session usage badges use the pool's selected allowances. Account-wide facts such as the plan, subscription identity, and reset credits remain visible because selecting limits does not change the account itself. When the provider reports a window duration, the selector shows that duration (for example, 5h + 7d) instead of a generic window count; a single window with no reported duration is left unlabeled rather than shown as “1 window”.

When it switches

Automatic switching is off by default — turn it on per pool. Once on, it reacts to:

TriggerDefault
The account hit a usage limitOn
Authentication expiredOn
The active account changed unexpectedlyOn
A credential refresh failedOff

It can also move before a hard limit: when the active account drops below 15% remaining and a better member is available. That threshold is configurable.

Bounds that stop it thrashing

A broken pool or a repeated authentication failure must not become a switching loop, so switching is bounded:

  • at most 1 switch per turn
  • at most 3 switches per session per hour
  • a 30-second cooldown between switches
  • provider reset times are honoured, so a member known to be resetting shortly is not treated as permanently dead

Recovery after a hard limit

When a session does hit a wall, what happens next is configurable:

ModeBehaviour
Switch or wait (default)Move to another account; wait for a reset if there is none.
Switch then resumeMove and continue immediately.
Wait until resetStay on this account and wait.
OffStop and let you decide.

When it resumes, it can send Happier's standard continuation prompt, a prompt you write, or nothing at all.

Freshness

Quota snapshots older than five minutes are re-probed before a turn. By default Happier probes only when the snapshot is stale, checking the current account first and candidates after — you can make it probe every turn, or never, and reverse that order.

Every switch appears as an event in the session transcript, saying which account became active and why. Routine low-quota observations stay out of the transcript so they do not bury the conversation.

Quotas

Quota / usage surfaces are behind the connectedServices.quotas feature gate.

Current quota snapshots are available for:

  • openai-codex
  • claude-subscription
  • gemini

GitHub connected accounts do not currently expose quota meters in Happier.

They appear in:

  • the Connected services list as badges on the effective profile
  • per-profile detail screens
  • the new-session auth picker for connected profiles

Each profile detail view lets you:

  • refresh the snapshot
  • inspect the provider plan label when available
  • pin specific meters so the same meters appear as summary badges elsewhere in the UI

Composer gauges in development builds

Choose Gauge windows under Settings → Connected services → Provider usage or Settings → Session → Provider limits and usage → Provider usage. Both locations edit the same preference for all accounts. The default is one Most constrained gauge; select several windows, such as Daily and Weekly, to display one gauge for each available window.

For pooled sessions, gauges use only the allowances selected in that pool. A pool that tracks only Fable allowances shows Fable's selected windows, even if the account reports other allowances. Missing windows do not produce extra gauges. Short window includes allowances such as a five-hour window; Daily means a daily allowance.

Account favorites select summary meters in account views and add extra composer gauges for the account currently used by the session, alongside the global windows. Favorites respect the pool’s selected limits and need a reliable percentage to produce a ring. Show usage labels and the provider-gauge visibility toggle are available in both locations too.

When you hit a usage limit

Reaching a provider's usage limit does not silently stall the session. Happier shows a banner explaining what it is waiting for and what you can do about it, with a status of Limit reached, Temporarily throttled, or Ready to resume.

What it offers depends on what is actually possible:

ActionWhen it helps
Check limit nowYou think the limit has already lifted and want to re-probe rather than wait.
Apply resetYour account has usage-reset credits available — see below.
Switch account nowAnother account in the pool can take over immediately.
Switch fallback nowMove to the configured fallback without waiting for the pool to decide.
Resume when limit resetsWait it out; Happier resumes for you when the window opens.
Retry nowThe block was a temporary throttle rather than a hard limit.
Stop waitingGive up on automatic recovery and handle it yourself.

Always wait and resume remembers your choice for that account so the banner stops asking, and Ask each time puts the question back.

Usage-reset credits

Some Codex accounts receive usage-limit reset credits from the provider. Where they exist, the banner says how many are available and when the next one expires, and Apply reset consumes one without leaving Happier — no separate account page, no session restart.

Happier reports back what actually happened rather than assuming success: the reset applied, there was nothing to reset, no credit remained, or the credit had already been used. A blocked session continues once the provider starts accepting requests again.

Security model

For OAuth-based services, Happier clients do not exchange provider codes for tokens directly.

Instead:

  1. the client receives an OAuth code through device auth, paste, or embedded browser capture
  2. the client calls Happier server /v2/connect/<serviceId>/oauth/exchange
  3. the server exchanges the code with the provider
  4. the server returns an encrypted bundle sealed to the client public key
  5. the client decrypts the bundle locally and stores the resulting credential record

This keeps provider secrets, including server-side OAuth client secrets, out of the UI bundle.

Token-based services, including GitHub token profiles, are stored as connected-service credentials and decrypted only where the client/daemon needs to use them. They do not require Happier to run a GitHub OAuth application in the current build.

When a session starts, the daemon decrypts the selected records locally and materializes only the backend-specific auth it needs for that spawn.

Feature gates and overrides

Connected services uses the canonical feature-gating system.

Server feature flags:

  • connectedServices
  • connectedServices.quotas

UI build gates:

  • EXPO_PUBLIC_HAPPIER_FEATURE_CONNECTED_SERVICES__ENABLED
  • EXPO_PUBLIC_HAPPIER_FEATURE_CONNECTED_SERVICES_QUOTAS__ENABLED

See:

Advanced server overrides

Most users should not need these. They are mainly for self-hosted deployments and drift reduction.

Global server exchange timeout:

  • HAPPIER_CONNECTED_SERVICES_OAUTH_EXCHANGE_TIMEOUT_MS

OpenAI Codex OAuth:

  • HAPPIER_CONNECTED_SERVICES_OPENAI_CODEX_OAUTH_CLIENT_ID
  • HAPPIER_CONNECTED_SERVICES_OPENAI_CODEX_OAUTH_TOKEN_URL

Gemini OAuth:

  • HAPPIER_CONNECTED_SERVICES_GEMINI_OAUTH_CLIENT_ID
  • HAPPIER_CONNECTED_SERVICES_GEMINI_OAUTH_CLIENT_SECRET
  • HAPPIER_CONNECTED_SERVICES_GEMINI_OAUTH_TOKEN_URL

Claude subscription OAuth:

  • HAPPIER_CONNECTED_SERVICES_CLAUDE_SUBSCRIPTION_OAUTH_CLIENT_ID
  • HAPPIER_CONNECTED_SERVICES_CLAUDE_SUBSCRIPTION_OAUTH_TOKEN_URL

Quota fetchers:

  • HAPPIER_CONNECTED_SERVICES_QUOTAS_STALE_AFTER_MS
  • HAPPIER_CONNECTED_SERVICES_QUOTAS_USER_AGENT
  • HAPPIER_CONNECTED_SERVICES_OPENAI_CODEX_USAGE_URL
  • HAPPIER_CONNECTED_SERVICES_CLAUDE_SUBSCRIPTION_USAGE_URL
  • HAPPIER_CONNECTED_SERVICES_ANTHROPIC_USAGE_URL

HAPPIER_CONNECTED_SERVICES_ANTHROPIC_USAGE_URL remains accepted as a fallback override for Claude subscription quota fetching, but the primary service identity is claude-subscription.

On this page