connections array; users manage their accounts in Settings → Linked accounts.
Configure linking
The piece factory accepts your developer credential asauth and your OAuth app as oauth; see factory options. Factory auth is used when the caller has no connection for the piece, and factory oauth is available as instance.oauth for reuse. A connection entry controls what users can link:
Set
secret, oauth, or both.
connections and collections: [Users] to your root config. Reuse these instances wherever you call their actions or assign them as agent tools. google supplies login identity; each product instance supplies its own actions and connection. Sharing google.oauth shares app credentials, not tokens or product access.
Sheets, Drive, and Calendar are native packages: install their @frogbotai/piece-* packages without an Activepieces runtime or provider plugin. Each supports factory auth: { accessToken, refreshToken? } and optional user-entered tokens through secret: true. The example enables only OAuth for these products. Configure each entry’s methods explicitly; there is no shared google connection group or source/secret policy.
Every entry needs at least one enabled method. OAuth requires both a piece recipe and factory app credentials. Static linking requires a user-enterable schema. Enable both methods only when the piece supports both. Duplicate entries for the same piece are rejected, including instances with different custom slugs.
Credential combinations
These seven combinations apply to credential-requiring pieces. OAuth combinations require factoryoauth; static combinations require a supported form schema.
“Otherwise” means no connection row exists. An existing row must resolve successfully. Invalid credentials, revoked or error states, missing scopes, and expiry that cannot be refreshed throw
ConnectionError and block fallback.
Link an account in Settings
- Sign in to the admin panel and open Settings → Linked accounts.
- Select New Connection, then choose an integration.
- Authorize with OAuth or enter the requested credential fields. When both methods are enabled, choose OAuth or Static credentials.
- View the linked account and its status in the list. Use the row menu’s Disconnect action to remove it.
/admin/settings/connections with the default admin route. FrogBot adds it automatically when connections is non-empty, and the same view is the default view of the connections collection at /admin/collections/connections. Linking another account or switching methods replaces the existing connection for that owner and piece.
Each integration shows the logo URL from its piece’s admin.icon, or a link icon when the piece has none or the image fails to load.
Connection endpoints
The paths below use the defaultroutes.api: '/api'. If you configure another API prefix, use it in requests and provider redirect URIs. Callback origins use serverURL when configured, otherwise the request origin.
:piece is the piece’s built-in slug, such as gmail or linear, rather than a custom instance slug. Owners belong to the auth collection selected by admin.user. Static writes, deletion, and OAuth authorization require authentication from that collection: anonymous requests receive 401, and users from another auth collection receive 403.
Submit a static credential
Send the raw JSON input expected by the piece’sauth schema. Linear accepts an object with apiKey:
400; a piece without static linking enabled returns 404. The authenticated user determines ownership.
Static forms support primitive values, nested objects, and arrays with supported item schemas. The piece’s input schema defines the body shape; credentials do not use a common envelope.
Configure OAuth redirects
For the example above, enable the Google Sheets, Drive, Calendar, and Gmail APIs and register these redirect URIs in the shared Google OAuth app:/api/connections/:piece/authorize, replacing :piece with google-sheets, google-drive, google-calendar, or gmail. Start login at /api/users/sign-in/google. Login creates a FrogBot session without storing provider tokens or creating a connection; linking requires a signed-in user and stores only that product’s credential. The default linking return destination is the configured admin route plus /settings/connections. An optional returnTo selects a same-origin destination.
OAuth state is encrypted, browser-bound, single-use, and expires after ten minutes. It binds the piece, OAuth app, collection, callback, and link intent to the original owner. PKCE is used when the piece recipe enables it. The callback validates that intent before storing credentials.
Choose OAuth scopes
Each piece requests its default scopes plus the scopes its account lookup and token refresh need. Change the list with the factory’sscopes option, beside oauth. A function receives the defaults and adds to them; an array replaces them:
gmail.labels for https://www.googleapis.com/auth/gmail.labels. Your editor autocompletes them, and an unknown name fails to compile. Each OAuth piece exports its catalog as <piece>Scopes, for example gmailScopes, and its page lists the names. The required scopes are always requested, and no form removes them. For the Google products these are openid, userinfo.email and userinfo.profile.
scopes belongs to one instance. Sharing an OAuth app between pieces reuses only the app credentials, so a scope added to Gmail never reaches Drive or Google sign-in. Each piece still has its own consent flow, callback, and connection. Selecting fewer agent actions does not narrow OAuth scopes.
The Google product recipes add these scopes to the identity scopes:
When you add a scope, accounts linked earlier lack it. Every action for that piece then throws
ConnectionError with code scopes, and missingScopes lists the provider strings. Settings → Linked accounts shows those rows as needs re-link, and frogbot.connections.authorizations() lists the piece with its authorizeUrl. Linking again asks for the full list and replaces the row.
Resolve credentials on the server
Piece actions andpiece.client({ req }) resolve credentials automatically. Pass req to use the caller’s linked account. For direct resolution and account management:
resolve accepts optional scopes to require specific grants. It returns the piece’s parsed auth value, converting stored OAuth tokens through the recipe’s toAuth when provided. list returns IDs, owner, piece, method, account, scopes, expiry, status, and timestamps, without plaintext or encrypted credentials.
Expired OAuth connections refresh lazily during resolution, using the recipe’s refresh function or a refresh-token grant at its tokenUrl. Concurrent refreshes are serialized per owner and piece. A failed refresh marks the connection error and throws; it never silently switches to factory auth. Reconnect to replace the failing credential. Disconnecting removes the row, allowing factory fallback again if configured; it does not revoke access at the provider.
ConnectionError.code is missing, revoked, expired, error, or scopes. Scope errors include missingScopes. frogbot.connections.authorizations({ pieces, req }) returns linking requirements keyed by piece, including enabled methods and an OAuth authorizeUrl when available.
Storage and access
FrogBot creates its reservedconnections collection only when the root list is non-empty. A unique (owner, piece) constraint permits one row per user and piece. Rows contain method, encrypted credential, account metadata, scopes, expiry, and status.
Static input and OAuth token sets are encrypted as JSON with AES-256-GCM using a key derived from the root secret. Keep that secret stable: changing it makes existing credentials unreadable. Factory auth stays in your configuration and is never copied into connection storage.
Collection reads are owner-scoped. Ordinary collection creates, updates, and deletes are disabled; use the connection endpoints. The credential field is hidden and denies field-level reads. Deleting a user also deletes every connection that user owns.
Connections authorize outbound calls to providers. OAuth sign-in establishes a FrogBot session, while API keys authenticate inbound requests to FrogBot.