Skip to content
Anlyon
Esc
↑↓navigate↵open⌘Jpreview
On this page

Connected accounts

Connect an account at a provider such as Stripe, GitHub or Notion with an API key. It becomes a secret bound to that provider's API, never shown to you or to an agent.

The ten integrations that connect with an API key are available now. The integrations you sign in to (HubSpot, Slack and Google Calendar) are coming one at a time in later releases; this page already describes how signing in works.

A connected account is a secret connected for one integration and bound to that integration’s API hosts. There are two ways to connect, and each integration uses one:

  • Sign in (coming: HubSpot, Slack, Google Calendar). You approve Anlyon’s access on the provider’s own consent page. The secret is of kind connection: instead of a value, it holds the account. When an action that references it runs, Anlyon fetches the account’s current access token, puts it in the request header, sends the request, and forgets it.
  • API key. You create a key in the provider’s own settings and paste it (Stripe, GitHub, Intercom, Attio, Notion, Sentry, PagerDuty, Asana, Discord, Resend). Anlyon checks the key with the provider before storing it. The secret is of kind static, with integrationId set.

Actions use either exactly like any secret:

"headers": { "Authorization": "Bearer {{secret:HUBSPOT}}" }

Where the credential lives, and who sees it

  • A sign-in token is held by Anlyon’s connector service, a separate component Anlyon operates on its own infrastructure. It stores the token encrypted and refreshes it when it expires. It is fetched at dispatch, for that one request.
  • An API key is held in Anlyon’s secret store, encrypted, like any secret you store. The connector service is not involved.
  • Either is redacted from every response and error Anlyon records.
  • No API returns it. Not to you, not to the console, and not to an agent. The secret’s metadata says which integration it is and, in health, whether it still works, for a key and a sign-in alike.
  • It can only go where the provider’s API is. A connected account is bound to the integration’s API hosts, which Anlyon sets, and it may appear only in a header. An action that addresses any other host is refused. For an API key these are set from the integration and cannot be chosen when you connect.

GET /api/v2/secrets/{name} shows a connected account like this. Signed in:

{
  "name": "HUBSPOT",
  "kind": "connection",
  "connection": { "integrationId": "hubspot", "status": "active" },
  "integrationId": "hubspot",
  "health": { "status": "active", "checkedAt": "2026-10-15T08:00:00.000Z", "reason": null },
  "allowedHosts": ["api.hubapi.com"],
  "allowedPlacements": ["header"]
}

Connected with an API key:

{
  "name": "GITHUB",
  "kind": "static",
  "connection": null,
  "integrationId": "github",
  "health": { "status": "active", "checkedAt": "2026-10-15T08:00:00.000Z", "reason": null },
  "allowedHosts": ["api.github.com"],
  "allowedPlacements": ["header"]
}

`health` is the same record for both. `status` is `active`, or `needs_reauth` once the account stopped working; `checkedAt` is when Anlyon last asked the provider; `reason` says why it stopped. See [Does it still work?](#does-it-still-work) below.

Connect an account

In the console: Actions → Integrations. Choose the integration, press Connect, and give the secret a name.

  • For a sign-in integration, Anlyon shows the access it will ask for and the hosts the token may reach, then opens the provider’s consent page in a window. When you approve, the account appears under the integration.
  • For an API-key integration, Anlyon shows where in the provider’s settings to create the key and which permissions to give it, with a link to that page, and a field to paste it into. When the provider accepts the key, the account appears under the integration.

From the CLI:

anlyon connections integrations                 # what can be connected, and how
anlyon connections add hubspot --secret HUBSPOT # sign-in: opens the consent page, waits, prints the secret
anlyon connections add github --secret GITHUB   # API key: shows the instructions, then asks for the key without echoing it
anlyon connections list

The same command works for both kinds. An API key is never a command-line argument, so it does not reach your shell history. In a script, pipe it:

printf %s "$GITHUB_TOKEN" | anlyon connections add github --secret GITHUB --api-key-stdin --yes

From an SDK or the API, sign-in: POST /api/v2/connections/sessions with { "integrationId": "hubspot", "secretName": "HUBSPOT" } returns a connectUrl to open in a browser. Then call POST /api/v2/connections/sessions/{sessionId}/complete until it answers status: "completed". A session expires after 15 minutes.

From an SDK or the API, API key: POST /api/v2/connections/keys with { "integrationId": "github", "secretName": "GITHUB", "apiKey": "..." } answers 201 with the secret’s metadata. In the SDKs this is connections.connectWithApiKey(...) (TypeScript) and connections.connect_with_api_key(...) (Python).

GET /api/v2/connections/integrations says which way each integration is connected, in auth.kind (oauth or api_key), and for an API key gives the provider’s instructions and link.

Connecting needs secrets:write. Listing needs secrets:read. A connected account counts as one secret toward your plan’s secret quota. At most 10 connections may be started per minute per workspace.

What happens to a key you paste

Before anything is stored, Anlyon sends the key to the provider once, in one read-only request to the integration’s own API host, to ask whether the provider accepts it.

  • The provider accepts it: the key is stored and the account is connected.
  • The provider refuses it (CONNECTION_KEY_REJECTED): nothing is stored. Check that you copied the whole key and gave it the permissions listed.
  • The provider could not be reached (CONNECTION_KEY_CHECK_FAILED): nothing is stored. Try again.

Create a key with the fewest permissions the operations need. Anlyon does not narrow a key: what the key allows at the provider is what an action using it can do, inside the limits and approvals you set. To replace a key, reconnect the account (below): the new key is checked the way the first one was, and the secret keeps its name and hosts. PUT /api/v2/secrets/{name} also replaces the value, without the check.

Choose what your agent may do

A connected account on its own does nothing. In the console, connecting continues to What may your agent do here?: the integration’s operations, one switch each, in two groups. The same screen opens later from the account’s row (Operations).

Each integration is a full toolset: the reads and writes an agent routinely needs on that product’s objects, so your agent needs no other tool for it and never holds the key. Account administration (members, billing, permissions, webhooks) is left out.

  • Reads return what the provider answers and change nothing: search, list and get. Each list returns one page, sized so the answer fits, and takes the provider’s cursor for the next. A read has no limit and no receipt. It is logged like any call, and an approval policy can still match it. Turn on all reads switches them on together.

  • Writes are governed. Each declares what one call changes, which counts against your limits, and can be held for an approval. Where the provider has a read that shows the change, Anlyon reads it back and the receipt is graded confirmed. Where it has none, the write’s description says why, and its receipt is graded acknowledged.

  • Turning an operation on creates one declared action in your workspace, named <integration>-<operation> (for example hubspot-update-contact-stage), that sends this account’s credential. Its suggested approval policy is installed off. The switch shows on only once the action exists. An operation that needs settings first (the Stripe account and currency for refunds, the sending domain for email) asks for them, and they are fixed into the action.

  • Turning it off disables the action. It is never deleted, so its receipts and pinned versions stay.

  • Approval policies suggested for the operations you turned on are listed with an Enable switch.

  • Limits are suggested with an amount you can change, and created only when you press Create limit. Creating a limit needs permission to manage impact limits; without it the screen says so and creates nothing.

Then Add to your agent lists the operations that are on by tool name and gives the setup for Claude Code, Cursor, Codex, the AI SDK, LangChain or curl. MCP clients sign in with a browser. The others need an agent key, which the screen can create with actions:invoke, actions:read and approvals:read only, shown once. A tool for the same provider already in your own code is not governed by Anlyon until you replace it with one of these.

Integration Reads Writes
GitHub Search and list issues; issue comments and labels; pull requests, their files, reviews and review comments; repository, branches, commits and file contents; code search Open, update, close and reopen issues; comment, edit and delete comments; add and remove labels and assignees; create and delete labels; open a pull request, review it, request reviewers, merge it
Notion Search pages and databases; get a page, a property, a block and its children; get and query a database; list comments Create a page, a database and a database row; update page properties; append paragraphs and blocks; update and delete a block; archive and restore a page; add, reply to, update and delete comments
Intercom Search and list contacts and conversations; get a contact, a conversation, a company, an admin; list tags, admins, teams and companies; search and get Help Center articles Create, update and delete contacts; tag and untag a contact; attach and detach a company; start a conversation; reply, add a note, assign to an admin or a team, snooze, close, reopen, tag
Attio Query people, companies and list entries; get a record, a note, an entry, a task; list attributes, notes, lists and tasks Create people and companies; update a job title, a company, a description; delete a record; add and delete notes; add to a list, update an entry, remove it; create, reschedule, complete and delete tasks
Asana Workspaces, projects, sections, tasks in a project or section, a task, its subtasks and stories, tags Create, update, complete, reopen and delete tasks; create subtasks; comment; move to a section; add and remove followers and tags; create and delete sections
Discord A server’s channels and active threads; a channel’s messages, pins and archived threads; a message; a thread’s messages Post, reply, edit and delete messages; post in a thread; add and remove a reaction; pin and unpin; start, join and archive a thread (as your bot)
PagerDuty Incidents, their notes, log entries and alerts; services; who is on call; escalation policies; schedules; users; maintenance windows Open, acknowledge, resolve, reassign, snooze and merge incidents; change urgency; add a note; create and end a maintenance window
Sentry Projects, teams, releases; issues with a search query; an issue, its events, one event Resolve, resolve in the next release, reopen, archive (with or without a time), assign to a member or a team, unassign, set priority, bookmark, mark seen
Stripe Customers (list, search, get); payment intents; charges; refunds; invoices; subscriptions; balance and balance transactions Refund a payment (the stripe.refund adapter, counted in money); create, update and delete customers; cancel a subscription or end it at period end; finalize and void an invoice
Resend Emails, domains, contacts, segments, a contact’s segments Send an email (the resend.email_send adapter, counted per recipient); reschedule and cancel a scheduled email; create, rename, delete and (un)subscribe contacts; add and remove a contact from a segment

More integrations are being added. To use an API that is not here, import its OpenAPI spec or declare the action yourself.

Each operation’s limitations are in its description, which a reviewer sees in the preview. The same operations install from the CLI with anlyon packs install ./packs/hubspot --action <operation>; see Install a pack.

What Anlyon asks for

For a sign-in integration, Anlyon requests the smallest set of scopes its packs need, and shows them before the consent window opens. The provider’s consent page shows Anlyon’s name, because the app you approve is Anlyon’s.

Sign-in integration Token may be sent to Provider review for Anlyon’s app
HubSpot (coming) api.hubapi.com None for a public app used outside the marketplace

Review times are the providers’ published expectations, not promises. An integration is offered once its review clears.

For an API-key integration there is no Anlyon app and nothing to review. You decide what the key may do when you create it.

API-key integration Key may be sent to What to create at the provider
GitHub api.github.com A fine-grained personal access token, limited to the repositories your agent should work in, with Issues and Pull requests: Read and write and Contents: Read. Merging needs Contents: Read and write
Notion api.notion.com An internal integration with Read, Update and Insert content and Read and Insert comments, then share each page with it
PagerDuty api.pagerduty.com An API access key that is not read-only
Resend api.resend.com An API key with Full access (a sending-only key cannot read an email back)
Stripe api.stripe.com A restricted key with Customers, Refunds, Invoices and Subscriptions: Write, and Payment Intents, Charges and Balance: Read. Leave out what your agent should not touch; those operations are refused
Intercom api.intercom.io An access token from an app you create in the Developer Hub. US-hosted workspaces only
Attio api.attio.com An access token with Records, List entries, Notes and Tasks: Read-write, and Object configuration, List configuration and User management: Read
Sentry sentry.io An auth token with org:read, project:read and event:write
Asana app.asana.com A personal access token. It acts as the person who made it
Discord discord.com A bot token, with the bot invited to your server and given View Channel, Send Messages, Send Messages in Threads, Read Message History, Create Public Threads, Add Reactions and Pin Messages

Does it still work?

A connected account can stop working without anyone changing anything in Anlyon: a key expires or is deleted at the provider, or the person who signed in withdraws Anlyon’s access there. Anlyon treats both the same way. Every connected account carries a health record, Anlyon asks the provider whether the account still works, and an account that does not is marked needs_reauth with a reason:

health.reason What happened Which kind
key_rejected The provider refused the stored key API key
access_revoked The provider no longer honours the account’s grant: access withdrawn, or the token can no longer be renewed Sign-in
refresh_failed Anlyon’s connector service tried to renew the token and could not Sign-in

Once an account is marked, the next action that uses it fails before anything is sent, with the error code CONNECTION_NEEDS_REAUTH. Nothing reaches the provider with a credential Anlyon knows is dead.

When Anlyon asks

  • When you press Check. In the console, on the account’s row under Integrations. From the CLI, anlyon connections check GITHUB. From the API, POST /api/v2/connections/{name}/check, or connections.check(name) in an SDK. The answer is the secret with its health; an account that does not work is an answer, not an error.
  • Once a day. Anlyon checks every connected account that has not been checked for a day. An account already marked waits for you, not for the next check.
  • After a 401. When the provider answers an action with 401, Anlyon checks the connected accounts the action used, and marks one only if the check confirms it. A request the provider refused for its own reasons leaves a working account alone.

What a check is depends on the kind, and that is the only place the kinds differ. For a key, it is the same single read-only request to the provider’s own API host that was made when you connected it. For a sign-in, Anlyon asks its connector service to renew the token, so the provider itself says whether the grant is still honoured. Neither returns the credential. A check that could not be made (CONNECTION_KEY_CHECK_FAILED, CONNECTION_PROVIDER_ERROR) leaves the status as it was.

Reconnect

Reconnecting makes a needs_reauth account work again under the same name, so nothing that references {{secret:NAME}} changes: not the actions, not the policies, not the limits.

  • In the console: Reconnect on the account’s row. It opens the same dialog as Connect, for that account. For a key integration you paste the new key; for a sign-in integration the provider’s consent page opens again.
  • From the CLI: anlyon connections reconnect GITHUB asks for the new key without echoing it (--api-key-stdin reads it from a pipe); anlyon connections reconnect HUBSPOT opens the consent page and waits.
  • From the API: POST /api/v2/connections/{name}/reconnect. For a key integration, send { "apiKey": "..." }: Anlyon checks it with the provider the way it checked the first one, replaces the stored value, and answers status: "completed" with the secret. For a sign-in integration, send an empty body: Anlyon answers status: "pending" with a session to open and complete exactly as for a first connect. In the SDKs this is connections.reconnect(name, { apiKey }) (TypeScript) and connections.reconnect(name, api_key=...) (Python).

You can also reconnect an account that still works, for example to rotate a key before it expires. Checking and reconnecting need secrets:write and count toward the limit of 10 connect sessions per minute per workspace.

Disconnect

Delete the secret: Disconnect in the console, DELETE /api/v2/secrets/{name}, or secrets.delete(name) in an SDK. For an API key, that deletes Anlyon’s copy; delete the key at the provider as well to end its access. For a sign-in, Anlyon revokes its access to the account first, then deletes the secret. If revoking fails, the secret is kept and the request answers CONNECTION_REVOKE_FAILED, so you are never told access is gone while it is still live. In a protected environment, deleting needs confirmProtected: true.

Revoking at the provider is what ends access. You can also remove Anlyon’s access from the provider’s own settings at any time.

Errors

Code Status Meaning
CONNECTIONS_UNAVAILABLE 501 Sign-in connections are not configured on this deployment. API-key connections do not need them
CONNECTION_KEY_REJECTED 422 The provider did not accept the API key. Nothing was stored
CONNECTION_KEY_CHECK_FAILED 502 The API key could not be checked with the provider. Nothing was stored
CONNECTION_SESSION_EXPIRED 410 The session expired, or belongs to another workspace or environment
CONNECTION_NEEDS_REAUTH 424 The account’s access was revoked. Nothing was sent
CONNECTION_PROVIDER_ERROR 502 The connected-account service did not answer. Nothing was sent
CONNECTION_REVOKE_FAILED 502 Revoking failed, so the secret was kept
SECRET_KIND_MISMATCH 409 PUT /secrets/{name} cannot turn a connected account into a stored value, or the other way round. Delete it first

What it is not

  • Not per end user. A connected account belongs to a workspace environment. An agent acting as one of your own users, with that user’s account, is not supported.
  • Not a way around governance. A connected account is a credential. Limits, approvals, previews and read-backs apply to the actions that use it exactly as to any other.

To set up a whole workflow at once, see Packs.

Was this page helpful?