ctx.connections.get(name) and uses the token.
A connection belongs to one of two owners:
- A user (the default). Each signed-in user links their own account, for example their Google Calendar.
- The app (
owner: "app"). One account for the whole app, for example the business’s Square account. Any server function can read it, including one that serves an anonymous visitor. Only an admin can connect or remove it.
kind: "api_key").
Declare a connection
app.ts
buildManifest({ connections: [calendar, square, toast] }).
Boot fails when a declaration is wrong: an unknown owner or kind, fields on an OAuth connection, or a name declared twice.
Providers
Every sign-in provider in OAuth also works as a connection provider (Google, GitHub, Slack, Microsoft, Notion, and others).
For an API-key connection with a known provider, Pylon calls the provider to check the key before it stores it. For any other provider, declare the field names with
fields; the default is one field, apiKey.
Configuration
Use a connection
functions/listCatalog.ts
get returns:
Connect an account
For a user connection, any signed-in user starts their own flow. For an app connection, the function must run as an admin.functions/connectSquare.ts
/api/connections/square/callback. Pylon stores the tokens and sends the browser to postRedirect.
Store keys with ctx.connections.setCredentials(name, { ...fields }). Remove a connection with ctx.connections.disconnect(name).
Hosted connections
A platform that hosts many Pylon apps can run the OAuth flow for their app connections with its own client credentials, so each app holds no client secret. Pylon Cloud and Stack0 do this.
With the broker set,
authorizeUrl on an app connection throws CONNECTION_MANAGED. The platform hands over the result through the management API:
GET /_pylon/connectionslists the app connections: name, provider, kind, key fields,declared_scopes,connected,account_id, and expiry. It never returns a token or a key.PUT /_pylon/connections/<name>stores tokens{ accessToken, refreshToken?, expiresAt?, scope?, accountId?, metadata? }, or keys{ credentials: { ... } }.DELETE /_pylon/connections/<name>removes the stored connection.
{ connection, provider, accountId, refreshToken } to the broker URL and stores the { accessToken, refreshToken?, expiresAt?, scope? } it gets back.
Errors
ctx.connections is available in mutations and actions, not queries.