# A day with a worker Source: https://docs.ergoly.ai/a-day-with-a-worker One worker, two clients, one morning. What it looks like from inside Slack. Your agency is on Ergoly with one worker, Nora, who handles account management for two clients, Acme and Globex. Here is a Tuesday. ## 9:00 — a routine runs Nora has a routine that runs every weekday morning for each client: pull what moved in the project tracker and post a status note. Nobody asked for it today. It runs because it was scheduled once. Your agency Channels Workers # acme A routine posts where it was told to. Globex gets its own note, from its own copy of Nora. ## 10:40 — a client asks Daniel at Acme asks for something in the shared channel. Nora answers in a thread, as your agency, from everything it knows about Acme and nothing else. Your agency Channels Workers # acme ## 11:15 — you correct it You read the thread and want the one-pager shorter. You say so, once. Nora fixes it and keeps the rule. Your agency Channels Workers # acme-internal The rule is filed with Acme. Globex's one-pagers are unchanged. ## 14:00 — it asks before acting Nora is set to get approval before anything goes to a client's mailing list. It drafts, then asks. Your agency Channels Workers # globex-internal Whoever presses the button is recorded with the decision. ## 16:30 — it hands something off A question comes up that needs a person. Nora opens a task, hands it to the account lead, and waits. Your agency Channels Workers # acme-internal A task waits for its holder. Nothing goes to the client until you answer. That is the whole loop: routines run, clients ask, you correct, it asks when it should, and it hands off what is not its call. Each of those has a page of its own. > [card] [Routines](/work/routines) > > Tasks that repeat, across clients. > [card] [Memory](/workers/knowledge/memory) > > How a correction becomes a rule, and where it is kept. > [card] [Approvals](/work/approvals) > > Asking first, and the record of who decided. > [card] [Tasks](/work/tasks) > > Handing work to a worker, or to a person. # Get the activity feed Source: https://docs.ergoly.ai/api-reference/activity/get-the-activity-feed /openapi.json get /api/v1/activity `?kind=` is exact. `?domain=` matches the leading segment of `kind`, so `?domain=api` is every write made through this API. `?actor=` takes a user id, or the literal `system` for rows with no person behind them — which is where your keys' own writes appear. # Classify a channel Source: https://docs.ergoly.ai/api-reference/channels/classify-a-channel /openapi.json patch /api/v1/workers/{id}/channels/{channel} `internal` writes a mapping row with a null client and routes the room to the Worker's existing core ework — nothing is minted, and it answers **200**, because the row is the whole of the change. `client` binds the room and brings up that pair's ework, so it answers **202** and the agent may still be coming up behind it. Use this rather than a delete to mark a room internal: an unmapped room routes nowhere, which is a different thing. **A `client` classification brings up that Client's ework and spends one of your organization's daily provisioning slots. An `internal` classification mints nothing and spends none.** # Create a Slack channel Source: https://docs.ergoly.ai/api-reference/channels/create-a-slack-channel /openapi.json post /api/v1/channels Opens a Slack channel on the CALLING worker's own identity, so only a worker's key can call it. It creates the room, maps the caller, maps then invites each of `workers`, and invites the person who asked — the sender of the caller's running turn, never a body field — then `people`. With no person asking it is a 409 before any room exists. Each of `people` must be a person of the org's own Slack, else a 409 (`person_outside_org`, `person_not_a_person`, `person_lookup_failed`) before any room exists. Anyone who could not be brought in is reported, not failed. **A `client` mapping brings up that Client's ework for each Worker mapped to the room, and spends one of your organization's daily provisioning slots. An `internal` room mints nothing.** # Invite a worker to a channel Source: https://docs.ergoly.ai/api-reference/channels/invite-a-worker-to-a-channel /openapi.json post /api/v1/workers/{id}/channels/{channel}/invite Mapping a channel decides where its traffic routes; this puts the bot in the room, which is the other half and the one Slack will not do by itself. Only a worker's own key can call it, and the invite is made on that worker's own bot token and nothing else. The Worker being added must already be mapped to the room — map first, then invite; an unmapped room is a 409 `channel_not_mapped`. It acts only for a member: the room must already hold the calling worker's bot AND the person who asked — the sender of the calling worker's running turn, read on control, never named in the request. The calling worker never joins a room. Otherwise the call is a 409 whose `reason` says which: `inviter_not_in_channel`, `requester_not_in_channel`, `no_human_requester` (nobody's request is running — a scheduled run, a webhook) or `requester_unclear` (more than one is). A person in the room can then add the worker themselves: `/invite @worker` in the channel, or the channel's settings, then Integrations, then Add apps. A bot that is already there answers 200 with `invited: false`, so a retry is safe. The call takes no body; a body naming any field is a 400. # List channel mappings Source: https://docs.ergoly.ai/api-reference/channels/list-channel-mappings /openapi.json get /api/v1/workers/{id}/channels Each row names the Slack channel and the Client it routes to. A `client` of `null` is a room marked internal, which routes to the Worker's core ework — not a row with data missing. # List Slack channels Source: https://docs.ergoly.ai/api-reference/channels/list-slack-channels /openapi.json get /api/v1/channels Every public room in the workspace — including the ones none of your Workers is in, which is what makes it a directory rather than a roster — plus the private rooms a Worker has been invited into. `?query=` ranks by name with an exact match first, so "#ops" never resolves to "#ops-archive". `memberWorkerIds` is empty for a room no bot is in; that is the normal state of a public channel and the reason `inviteWorkerBot` exists. `seenAt` says when Slack last confirmed the room: the directory is re-read from Slack when it goes stale, so the answer is current rather than live. A workspace that has never been read and cannot be reached now is a 502, never an empty list — "we could not find out" and "you have no channels" are opposite answers. # Map a channel Source: https://docs.ergoly.ai/api-reference/channels/map-a-channel /openapi.json post /api/v1/workers/{id}/channels The bot joins the channel and its traffic routes to that Client's ework. Moving a channel already mapped to a different Client needs `confirm: true`, without which it is a `conflict`. A DM id (`D…`) is refused: a direct message routes by who is in it. **Mapping a channel brings up that Client's ework if it is not already running. It costs money and spends one of your organization's daily provisioning slots.** # Unmap a channel Source: https://docs.ergoly.ai/api-reference/channels/unmap-a-channel /openapi.json delete /api/v1/workers/{id}/channels/{channel} Removes the routing row and asks the bot to leave the room. `leftSlack` says whether Slack accepted that; a refusal there does not fail the call, because the routing decision is the durable half and it has already landed. To mark a room internal instead, classify it — an unmapped room routes nowhere. **The Worker stops answering in that channel. Nothing that was said there is lost, but the room is no longer routed to anybody.** # Assign a client to a worker Source: https://docs.ergoly.ai/api-reference/clients/assign-a-client-to-a-worker /openapi.json post /api/v1/workers/{id}/clients Creates that pair's client-tier ework and, in the same call, optionally maps channels and binds people to it. The routing rows are durable when this returns; `activation` says whether the agent behind them came up. A channel or a person already bound to a different Client is refused rather than re-pointed. Channels the bot could not join are reported in `joinFailures` and do not fail the call. **Binding brings up a client-tier ework — a sandbox and an agent. It costs money and spends one of your organization's daily provisioning slots.** # Create a client Source: https://docs.ergoly.ai/api-reference/clients/create-a-client /openapi.json post /api/v1/clients Complete when it returns: the Client exists and its memory tier repository has been made, along with a private instance tier for each active Worker. No ework is created — that happens when you bind the Client to a Worker. A create that cannot make its repositories is rolled back rather than left half-made, and answers `upstream_error`; retry it unchanged. **Creating a Client makes repositories on a shared installation, so it spends one of your organization's daily provisioning slots even though no sandbox is involved.** # Get a client Source: https://docs.ergoly.ai/api-reference/clients/get-a-client /openapi.json get /api/v1/clients/{id} Another organization's id answers 404, exactly as an unknown one does. # List clients Source: https://docs.ergoly.ai/api-reference/clients/list-clients /openapi.json get /api/v1/clients Newest first. Every Client of your organization, bound or not. # Update a client Source: https://docs.ergoly.ai/api-reference/clients/update-a-client /openapi.json patch /api/v1/clients/{id} Send only what changes. `websiteUrl` and `shortDescription` take `null` to clear them. The slug is fixed once created. # Add a host Source: https://docs.ergoly.ai/api-reference/connections/add-a-host /openapi.json post /api/v1/connections/{id}/hosts The hostname must be bare: no scheme, path, port, userinfo or wildcard. It is lowercased and any trailing dot dropped before it is stored, so what you send and what the gateway matches are the same thing. A host already mapped to another connection in this organization is a `conflict` — one host resolves to exactly one credential. Answers the connection with its new host list. # Add a placement Source: https://docs.ergoly.ai/api-reference/connections/add-a-placement /openapi.json post /api/v1/connections/{id}/placements A placement is where a connected app may be used — the whole company, one Worker, one Client, or one Worker for one Client — and a connection may have several. Adding one changes which eworks' sessions carry the app, and the answer's `sessions` reports each one reached: what it gained, what it lost, and whether its session could be updated. The credential itself is untouched. A placement already present is a `conflict`; an Ergoly-provided connection refuses every change. A placement no ework could read — `instance` on a Worker that has no active ework for that Client, or `client` for a Client no Worker has one for — is a `conflict` too, and its message names the pair ("Smith has no ework for Gumshoe."): nothing is written, and the remedy is to set that Worker up for the Client from its Worker page, not a different placement. # Connect an MCP server Source: https://docs.ergoly.ai/api-reference/connections/connect-an-mcp-server /openapi.json post /api/v1/connections/mcp Ergoly discovers the server's metadata, registers itself dynamically, and starts consent. Read `mode` before doing anything else: `oauth` means open `authorizeUrl` and nothing is connected yet, while `no-auth` means the server wanted no credential and the connection is ALREADY complete — handshaken, tools listed, skill installed — so waiting for a callback would wait forever. A server that offers no dynamic registration, or rejects our redirect URI, is a `conflict` whose message carries the server's own explanation and, where there is one, the exact URI its owner has to allow. # Create a connection Source: https://docs.ergoly.ai/api-reference/connections/create-a-connection /openapi.json post /api/v1/connections Two shapes, told apart by `app`. WITHOUT it, this stores a secret: `value` is write-only, it goes in here and no route gives it back; give at least one host unless the key already has some — a credential no host points at is never injected by the gateway, so it would sit there doing nothing; a key already taken at the same scope is a `conflict`, as is a host already mapped to another connection. WITH `app` — a catalog slug or a tool server's URL — this connects an app and places it: omit `auth` and the answer carries `connectUrl`, a hosted sign-in to open in a browser, with the connection `pending` until consent finishes and `active` after (poll `GET /api/v1/connections/{id}`); send `auth.mode: "key"` with the key in `value` and it is stored at Composio and checked with one real call, `verified` reporting the verdict; a tool server that takes a key names the header it goes in with `auth.header` (absent is `Authorization`, sent as `Bearer `; any other header carries the key on its own); a tool server that takes no credential is `auth.mode: "none"`, and gets a row and a placement with nothing stored anywhere. A `placement` no ework could read — `instance` on a Worker with no active ework for that Client, `client` for a Client no Worker has one for — is a `conflict` naming the pair, refused before a key or a sign-in reaches Composio. The check is made once, up front: an ework removed while Composio is being called can still leave the placement in place, and adding or moving a placement later is checked again at the write. `connectUrl` is shown once — a replay under the same `Idempotency-Key` withholds it — and the pasted key is never in any response. `sessions` says which eworks can use the app now. # Delete a connection Source: https://docs.ergoly.ai/api-reference/connections/delete-a-connection /openapi.json delete /api/v1/connections/{id} What this does depends on what the connection is. A plain secret is deleted, and its host mappings come down with it if no other variant of the key survives. A connected OAuth account is DISCONNECTED: the token is revoked with the provider first, which is the part that matters, then the row and its hosts go. A provider app is refused — remove it through its own route, which also cleans up every account connected with it. A CONNECTED APP is revoked at Composio first and then removed with every placement it had; `outcome` is `revoked` or `removed` (matching `revoked`), and `sessions` says which eworks lost it. An app Composio cannot revoke programmatically (Exa; a tool server's own sign-in) is still `removed`, with `revokeNotSupported: true`: revoke the credential at the vendor. Any other revoke Composio could not confirm is an `upstream_error`, and the connection stays. **This removes a credential your agents may be using. A disconnect also revokes the token at the provider, which cannot be undone — reconnecting means going through consent again.** # Delete a provider app Source: https://docs.ergoly.ai/api-reference/connections/delete-a-provider-app /openapi.json delete /api/v1/connections/provider-apps/{provider} Cascades. Every account connected through this app is torn down first, because the client secret their tokens are refreshed with is about to stop existing and leaving them would leave connections nothing can renew. `removedConnections` says how many went. **This disconnects every account connected through this provider app, revoking their tokens. Anyone using them will have to connect again once a new app is configured.** # Delete your OAuth client Source: https://docs.ergoly.ai/api-reference/connections/delete-your-oauth-client /openapi.json delete /api/v1/oauth-apps/{app} Deletes the client id and secret from Composio, and hosted sign-ins for the app go back through Ergoly's client. Refused with `conflict` while any connection still signs in through it — the response names them — because Composio takes every account made through the client down with it: remove or reconnect those connections first. A connection of the app that had already expired or failed keeps its row and connects again through whatever client is configured next; `cleared` lists them. Not configured is a 404. # Finish an MCP connection Source: https://docs.ergoly.ai/api-reference/connections/finish-an-mcp-connection /openapi.json post /api/v1/connections/mcp/{id}/finish A connection reporting `mcpStatus: "needs_reconnect"` holds a valid registration but no address to send anything to, so it can never work as it stands. This tries to work the address out and proves it with a real handshake. If it answers `conflict`, retrying will not help — disconnect and connect again with the server URL. # Get a connect URL Source: https://docs.ergoly.ai/api-reference/connections/get-a-connect-url /openapi.json post /api/v1/connections/oauth/{provider}/connect-url A consent screen needs a browser and a person, so this returns a link to open rather than claiming to finish. The link carries a single-use nonce instead of an Ergoly session, which means it can be opened in a private window signed into whichever account should be connected — usually the reason you are doing this. It expires; build another if it goes stale. Nothing exists in the vault until consent completes, at which point the connection appears in the list. # Get a connection Source: https://docs.ergoly.ai/api-reference/connections/get-a-connection /openapi.json get /api/v1/connections/{id} Everything the Connections page shows for it, in whichever of the two shapes the id names: a stored secret's scope, hosts and connection state by `type`; or a connected app's `app`, `status` and `placements`. Nothing it does not: no stored value, no client secret, in any form. A well-formed id belonging to another organization is the same 404 as a malformed one, whichever store it lives in. # Get a provider app Source: https://docs.ergoly.ai/api-reference/connections/get-a-provider-app /openapi.json get /api/v1/connections/provider-apps/{provider} The client id and the redirect URI to register with the provider. The client secret is write-only and has no field here. A provider with nothing configured is a 200 saying `configured: false`, not a 404 — the question has an answer either way. # Get a sign-in link Source: https://docs.ergoly.ai/api-reference/connections/get-a-sign-in-link /openapi.json post /api/v1/connections/{id}/connect-url For an account that expired, a consent that never finished, or a failed one. The old account is taken down first — revoked if it still works — and a new hosted sign-in is minted into the same connection, which keeps its id, name and placements. Until the person finishes consent the connection is `pending` and no ework can use it; open `connectUrl` in a browser to finish. It is shown once and a replay withholds it. A connection holding a pasted key refuses this: delete it and connect again with the new key. # Get your OAuth client Source: https://docs.ergoly.ai/api-reference/connections/get-your-oauth-client /openapi.json get /api/v1/oauth-apps/{app} Whether you have brought your own OAuth client for this catalog app, and the one redirect URI to register on it at the provider. Nothing about the client's credentials is here or anywhere on this API. Not configured is a 200 saying `configured: false`, not a 404. # List connections Source: https://docs.ergoly.ai/api-reference/connections/list-connections /openapi.json get /api/v1/connections Newest first, across all four types. `workerId` and `clientId` narrow to connections scoped to exactly that Worker or Client — they do not answer what that Worker can resolve, so org-wide connections it also reaches are not included. `?view=apps` lists the CONNECTED APPS instead: each is an app a person signed in to or pasted a key for, placed at one or more tiers, and its `placements` say where it may be used. That view takes no scope filter. No entry in either list carries a stored value. # List hosts Source: https://docs.ergoly.ai/api-reference/connections/list-hosts /openapi.json get /api/v1/connections/{id}/hosts Every host in one answer — a credential has a handful, not a stream, so there is no cursor. Hosts attach to the connection's key, so every scoped variant of that key returns the same list. # Remove a host Source: https://docs.ergoly.ai/api-reference/connections/remove-a-host /openapi.json delete /api/v1/connections/{id}/hosts/{host} Addressed by hostname, canonicalized the same way it was when added. A host mapped to a different connection answers 404 rather than a refusal: it is not this connection's to remove, and saying more would confirm it exists elsewhere. **The gateway stops injecting this credential on that host immediately. Any agent call relying on it will start failing authentication.** # Remove a placement Source: https://docs.ergoly.ai/api-reference/connections/remove-a-placement /openapi.json delete /api/v1/connections/{id}/placements/{pid} Removes one placement and leaves the rest. The eworks that lose the app have their sessions updated before this answers, and `sessions` names them. A placement that belongs to a different connection answers 404 rather than a refusal — it is not this connection's to remove. Removing the last placement leaves a connection nobody can use, which is allowed: place it again when you know where it goes. # Rotate a connection Source: https://docs.ergoly.ai/api-reference/connections/rotate-a-connection /openapi.json post /api/v1/connections/{id}/rotate The key and every host mapping are unchanged, so anything already naming this credential keeps working. The new value is write-only, like the original. Rotation is refused on a system-managed connection. # Set a provider app Source: https://docs.ergoly.ai/api-reference/connections/set-a-provider-app /openapi.json put /api/v1/connections/provider-apps/{provider} `clientSecret` is required the first time and optional afterwards: send it to rotate, omit it to keep the stored one. The redirect URI is derived by Ergoly and returned for you to register with the provider — it is never something you set. 201 when this created the app, 200 when it rotated one. # Set your OAuth client Source: https://docs.ergoly.ai/api-reference/connections/set-your-oauth-client /openapi.json put /api/v1/oauth-apps/{app} Every hosted sign-in for this app then goes through your client rather than Ergoly's, so the consent screen shows your name and the tokens are yours. Register `redirectUri` on the client at the provider first. Both fields are required every time: the secret is handed to Composio and held nowhere on Ergoly's side, so there is no stored one to keep on a rotation. 201 when this configured the client, 200 when it replaced one. An app that only takes a key has no OAuth sign-in and is a 400. # Update a connection Source: https://docs.ergoly.ai/api-reference/connections/update-a-connection /openapi.json patch /api/v1/connections/{id} Name one or more of `key`, `kind`, `scope` and `internalOnly`. Each is a separate guarded write applied in that order, and the first refusal stops the rest — so a body naming several fields can land some of them and then be refused, and the message says which already applied. `internalOnly` and a client `scope` cannot be combined, in one call or across two: the flag hides a connection from every client-tier agent and a client-scoped one resolves only for a client, so together they resolve for nobody. The stored value is never touched here; use rotate for that. A system-managed connection refuses every change. # Get a copy Source: https://docs.ergoly.ai/api-reference/eworks/get-a-copy /openapi.json get /api/v1/eworks/{id} Tier, status, sandbox class, sleep state and the snapshot it was provisioned from, plus the provider ids worth quoting in a support thread. `sleepingAt` set is normal and needs no action — the next turn wakes it. # List a worker's copies Source: https://docs.ergoly.ai/api-reference/eworks/list-a-workers-copies /openapi.json get /api/v1/workers/{id}/eworks One core ework plus one per bound Client. An empty list means this Worker has no eworks; a 404 means no such Worker for this credential. The two are kept apart deliberately — deriving the first from the second would report another tenant's Worker as one of yours that happens to be empty. # Introduction Source: https://docs.ergoly.ai/api-reference/introduction Read and change your own company's Ergoly environment from a terminal or a coding agent. One key, one header, one envelope. Anything you can click in control, a key can do from a terminal or from a coding agent: create workers, add clients, map channels, schedule tasks, connect tools, read the activity feed. Every call is scoped to the company the key belongs to, and there is no parameter that widens it. The pages in this section are generated from the API's own OpenAPI document, so they describe exactly what the API does today. Each page has a playground that sends a real request with your key. For the ideas behind the API, the words it uses and how they map to the words in control, read [The API](/technical/api) under Technical details. ## Base URL ```text theme={null} https://control.ergoly.ai/api/v1 ``` `GET /api/v1` is the front door. It answers without a key: what the API is, how to get a key, and where the reference lives. ## Authentication Every other route takes a company API key as a bearer token: ```text theme={null} Authorization: Bearer ``` An admin mints a key in control under **Settings**, on the **API keys** tab. It is shown once. A member cannot mint, revoke or rotate one; ask whoever administers your company on Ergoly. Every failure to authenticate answers one identical 401, with the front door's address in `error.docs`, so a caller with no credential at all is told where the way in is. Each operation names the one scope it is filed under, `:`, where the resource is the first path segment after `/api/v1/`. A key minted today carries all of them; scopes are recorded on the key and on every audit row, and are not yet enforced. ## Your first call Confirm which company a key belongs to before doing anything with it: ```bash theme={null} export ERGOLY_API_KEY="" curl -sS "https://control.ergoly.ai/api/v1/organization" \ -H "Authorization: Bearer $ERGOLY_API_KEY" ``` ## Responses * A single resource answers `{"data": …}`. A list answers `{"data": […], "page": …}`, and `page` is there even when there is nothing more. * Paging is by cursor: pass `limit` and the previous page's `nextCursor`. * Every refusal has one shape, `{"error": {"code", "message"}}`. Branch on `code`, never on `message`. | Code | Status | Notes | | - | - | - | | `unauthorized` | 401 | Every failure to authenticate reads alike. `error.docs` carries the front door's address. | | `not_found` | 404 | An id that belongs to another company answers the same 404 as an id that never existed. | | `invalid_request` | 400 | | | `conflict` | 409 | Also the answer to an `Idempotency-Key` reused with a different body. | | `quota_exceeded` | 429 | The body carries `limit` (provisioning runs per rolling day) and `resetsAt`; `Retry-After` carries the same wait as a header. | | `rate_limited` | 429 | | | `upstream_error` | 502 | | | `gone` | 410 | | The API also serves this contract itself, to the same key, as Markdown, JSON or OpenAPI. [The API](/technical/api) lists where. # Get a provisioning job Source: https://docs.ergoly.ai/api-reference/jobs/get-a-provisioning-job /openapi.json get /api/v1/jobs/{id} `status`, `currentStep` and the failure `error`. Poll after any 202 until `status` is terminal. A run sitting at `await_oauth_install` is waiting on a workspace admin, not stuck — open its `installUrl` in a browser as one. That install starts a SECOND run and leaves this one parked, so follow the rest on the Worker. `installUrl` is a string only while an install is genuinely owed, and null the moment it is not. # Delete a file or folder Source: https://docs.ergoly.ai/api-reference/memory/delete-a-file-or-folder /openapi.json delete /api/v1/eworks/{id}/memory `kind: "dir"` removes the directory and everything under it; uninstalling a skill is a `dir` delete of `skills/`. A directory containing a path control owns is refused whole, rather than emptied around it. **The files are removed from the tier and from every ework that mounts it. The git history keeps them; nothing in this API brings them back.** # Read a memory tier Source: https://docs.ergoly.ai/api-reference/memory/read-a-memory-tier /openapi.json get /api/v1/eworks/{id}/memory Three answers, chosen by the query and never by the state of anything. No `repoId` lists the tiers this ework can reach — start here, it is how you learn the ids. `repoId` alone lists what is at `path`, the repository root by default. Adding `read` returns the file itself, with the `sha` a later write can pass as `expectedSha`, and flags saying whether it is binary or was truncated. # Write a file Source: https://docs.ergoly.ai/api-reference/memory/write-a-file /openapi.json put /api/v1/eworks/{id}/memory Send exactly one of `content` (text) or `contentBase64` (bytes) — decoding bytes as text mangles them silently, so sending neither is refused rather than guessed. `changed: false` means the content was already identical and nothing was committed. Every running ework mounting the tier is told, and picks the change up in about twelve seconds. # Write several files Source: https://docs.ergoly.ai/api-reference/memory/write-several-files /openapi.json post /api/v1/eworks/{id}/memory What a skill install is: the files under `skills//` written together, so no ework ever sees half a skill. Each file takes `content` or `contentBase64`, the same way a single write does. Use this rather than a loop of single writes whenever the files only make sense together. # Get your company Source: https://docs.ergoly.ai/api-reference/organization/get-your-company /openapi.json get /api/v1/organization Needs no query of its own — authenticating the request already resolved the organization, so this hands back what the gate found. It is the cheapest way to confirm a key before doing anything with it. # Add a target Source: https://docs.ergoly.ai/api-reference/tasks/add-a-target /openapi.json post /api/v1/tasks/{id}/targets The job fires once per target. A target may override the expression, the instant, the zone and where it posts; anything it does not override folds against the job's own schedule. An override naming a field this job's schedule kind does not use is refused. # Cancel a scheduled job Source: https://docs.ergoly.ai/api-reference/tasks/cancel-a-scheduled-job /openapi.json delete /api/v1/tasks/{id} A soft delete: the job stops firing, drops out of the task list, and its run history survives. Its targets are left in place and fire nothing while the job is cancelled. **The job stops firing. There is no route here that brings it back — a cancelled job is replaced by scheduling a new one.** # Change a task's state Source: https://docs.ergoly.ai/api-reference/tasks/change-a-tasks-state /openapi.json post /api/v1/tasks/{id}/state `in_progress` starts it; `resolved`, `declined` and `cancelled` close it with that outcome. Only the holder may decline, so a key never can. A task already in that state answers `changed: false`. # Comment on a task Source: https://docs.ergoly.ai/api-reference/tasks/comment-on-a-task /openapi.json post /api/v1/tasks/{id}/comments The comment is an entry on the log and wakes every Worker on the task. A closed task can still be commented on. # Create a task Source: https://docs.ergoly.ai/api-reference/tasks/create-a-task /openapi.json post /api/v1/tasks Without `scheduleKind`, opens a task held by the Worker in `workerId`, with an optional `description` and `dueAt`; the Worker is woken by it. With `scheduleKind`, schedules a job instead. `scheduleKind: "once"` takes an ISO `runAt`; `"cron"` takes a five-field `cronExpr` and a `timezone`. A `client`-tier job needs a `clientId`. An unrecognized zone is refused rather than replaced with a default — you meant a specific wall-clock time, and running a 09:00 job at 09:00 UTC instead is the kind of wrong nobody notices for a week. # Get a task Source: https://docs.ergoly.ai/api-reference/tasks/get-a-task /openapi.json get /api/v1/tasks/{id} The task as `listTasks` shows it, plus its log oldest first — the newest 200 entries, with `logOmitted` counting any older ones. An entry a key wrote shows the `platform` as its actor. # Hand off a task Source: https://docs.ergoly.ai/api-reference/tasks/hand-off-a-task /openapi.json post /api/v1/tasks/{id}/handoff Name exactly one of `workerId` or `slackUserId`. Handing it to the holder it already has changes nothing and answers `changed: false`. A task that is one client's work can go only to a Worker serving that client, or to a person. A closed task cannot be handed on. # List a job's runs Source: https://docs.ergoly.ai/api-reference/tasks/list-a-jobs-runs /openapi.json get /api/v1/tasks/{id}/runs Newest first, sorted and paged on the run's own start time. `success` is `null` while a run is still in flight — which is not the same as `false`. # List tasks Source: https://docs.ergoly.ai/api-reference/tasks/list-tasks /openapi.json get /api/v1/tasks Cancelled jobs, and jobs under deleted Workers, are both excluded. `?workerId=` narrows to one Worker; a malformed id there is a 400, while a well-formed one naming another organization's Worker answers an empty list. # Remove a target Source: https://docs.ergoly.ai/api-reference/tasks/remove-a-target /openapi.json delete /api/v1/tasks/{id}/targets/{targetId} Removing the last target is refused with `conflict` — a job with no target fires nowhere, which is what cancelling the job is for. **That Client stops receiving this job. The others keep firing.** # Update a scheduled job Source: https://docs.ergoly.ai/api-reference/tasks/update-a-scheduled-job /openapi.json patch /api/v1/tasks/{id} Every field is optional; send only what changes. `enabled: false` parks a job without cancelling it, and `true` starts it again. Changing the schedule re-arms every target. # Get usage Source: https://docs.ergoly.ai/api-reference/usage/get-usage /openapi.json get /api/v1/usage `?window=30d` and `?days=30` ask the same question; either is accepted. Longer than 90 days is clamped to 90. `?tz=` must be an IANA name and decides where a day starts; it defaults to `UTC`. A zone this system does not recognize is refused rather than swapped for the default. # Create a webhook Source: https://docs.ergoly.ai/api-reference/webhooks/create-a-webhook /openapi.json post /api/v1/webhooks Returns the URL to POST to and the secret to send with it. `surfaceKind: "channel"` needs a `channelId` already mapped to this Worker — an unmapped room, and a DM id, are both refused; `"dm"` needs the `slackUserId` of the person. On a room mapped to a client, `workClientId` names that client. For a sender that cannot set a header, `secretKind: "link"` with `linkAcknowledged: true` answers a `link` with the secret in it. **The `secret` in the response, and the `link` in link mode, are shown once and the secret is stored hashed. Nothing can read them back — if you lose them, your only option is to rotate, which breaks whatever is already using the old one. Treat a link like a password.** # Get a webhook Source: https://docs.ergoly.ai/api-reference/webhooks/get-a-webhook /openapi.json get /api/v1/webhooks/{id} The endpoint's configuration and its URL. Never its secret: the row holds a hash, so there is nothing here to return. # List deliveries Source: https://docs.ergoly.ai/api-reference/webhooks/list-deliveries /openapi.json get /api/v1/webhooks/{id}/deliveries Every inbound POST leaves a row, whether it was accepted, refused or rate-limited, so "it fired and nothing happened" is answerable here. Bodies are not stored — the ledger records that a delivery arrived and how big it was, and the payload went to the agent. # List webhooks Source: https://docs.ergoly.ai/api-reference/webhooks/list-webhooks /openapi.json get /api/v1/webhooks Every inbound endpoint your organization has, revoked ones included — a retired webhook keeps its row so its delivery history stays readable, and `enabled: false` beside a `revokedAt` is what says which. No response here carries a secret. `?workerId=` narrows to one Worker. # Revoke a webhook Source: https://docs.ergoly.ai/api-reference/webhooks/revoke-a-webhook /openapi.json delete /api/v1/webhooks/{id} The endpoint stops answering: every later delivery is a 410. The row stays, so its delivery history survives and the webhook keeps appearing in the list marked revoked. **A revoke is a one-way door — `enabled: true` does not undo it. Whatever is POSTing to this URL stops working the moment you call this, and getting it back means creating a new webhook with a new URL and a new secret.** # Rotate a webhook secret Source: https://docs.ergoly.ai/api-reference/webhooks/rotate-a-webhook-secret /openapi.json post /api/v1/webhooks/{id}/rotate Issues a new secret and shows it once. The URL does not change. `secretKind: "link"` with `linkAcknowledged: true` issues a link secret and answers its `link`; without `secretKind`, the new secret is a header one, even on a link webhook. **The previous secret, and any previous link, stop working immediately — there is no overlap. Whatever is POSTing to this URL fails until you give it the new secret or link.** # Update a webhook Source: https://docs.ergoly.ai/api-reference/webhooks/update-a-webhook /openapi.json patch /api/v1/webhooks/{id} Every field is optional; send only what changes. `enabled: false` makes every delivery answer 410 without retiring the endpoint, and `true` starts it again. A change takes effect on the next delivery. # Create a worker Source: https://docs.ergoly.ai/api-reference/workers/create-a-worker /openapi.json post /api/v1/workers The row exists when this returns and a provisioning run has started; poll `jobId` at `/api/v1/jobs/{id}`. When `currentStep` is `await_oauth_install`, open the job's `installUrl` in a browser as a Slack workspace admin — nothing here can finish that step for you. Approving it starts a second run, so follow the rest on `GET /api/v1/workers/{id}`, whose `latestProvisioningJob` is always the current one. `slug` must be unique in your organization, and a handful of words control uses in its own URLs are reserved. **Provisioning mints a Slack app, a sandbox and an agent. It costs money and spends one of your organization's daily provisioning slots.** # Delete a worker Source: https://docs.ergoly.ai/api-reference/workers/delete-a-worker /openapi.json delete /api/v1/workers/{id} The Worker stops serving immediately and drops out of every list here. Its Slack app configuration is left behind for an admin to remove by hand — the install is revoked, the app is not deleted. **This tears down real infrastructure and cannot be undone. Every ework under the Worker has its sandbox and its agent destroyed, the Slack install is revoked, and the Worker's scheduled jobs stop firing. Nothing here rebuilds it: a replacement is a new Worker, with a new agent that remembers none of this one's work.** # Get a worker Source: https://docs.ergoly.ai/api-reference/workers/get-a-worker /openapi.json get /api/v1/workers/{id} Carries `latestProvisioningJob` — the current step, and the error text of a failure — so a stuck Worker can be diagnosed in one call. Null when the Worker has never been provisioned. It is always the CURRENT run, which is why this is the call to poll after a Slack install: that install starts a fresh run rather than resuming the one that was waiting. `installUrl` mirrors the run's, so one call answers whether an install is still owed as well. It also carries the worker's two role lists, `responsibilities` and `behaviors`, as Markdown — read from the worker's own memory, null until it has been provisioned, and not editable through this resource. # Get the current worker Source: https://docs.ergoly.ai/api-reference/workers/get-the-current-worker /openapi.json get /api/v1/workers/me For a key that was minted for a Worker, this is that Worker — the same record and the same fields as `/api/v1/workers/{id}`, without needing the id. It is the call to make first, because a Worker's own id is what almost every other call takes: its channels and its eworks. A key held by a person rather than by a Worker answers 404: there is no Worker for it to be, which is not a permission that could be granted. Address a Worker by its id instead. # List chart placements Source: https://docs.ergoly.ai/api-reference/workers/list-chart-placements /openapi.json get /api/v1/company/placements Every place on your Company chart a Worker may sit under — a person's seat, a Worker's, a team, an open role — in the order the chart draws them, each with its title and the place it sits under. Pass one's `id` as `reportsTo.placementId` when you create a Worker. Nothing inside a vendor or a client is listed, because a Worker may not sit there. The whole chart comes back at once; it is not paged. # List workers Source: https://docs.ergoly.ai/api-reference/workers/list-workers /openapi.json get /api/v1/workers Newest first. Deleted Workers are excluded; their eworks and scheduled jobs are excluded everywhere else for the same reason. # Retry provisioning Source: https://docs.ergoly.ai/api-reference/workers/retry-provisioning /openapi.json post /api/v1/workers/{id}/retry The usual answer to a failed run, and the way back from a stop. It re-provisions in place: the previous sandbox keeps serving until the new one is up. Poll the `jobId` it returns. `phase` says which half of the pipeline ran — before the Slack install, or after it. **A re-provision mints a fresh sandbox and agent. It costs money and spends one of your organization's daily provisioning slots — which is what bounds an agent that reads “provisioning failed” and retries in a loop.** # Stop a worker Source: https://docs.ergoly.ai/api-reference/workers/stop-a-worker /openapi.json post /api/v1/workers/{id}/stop Takes the Worker out of service without deleting it. Its eworks stop taking traffic; the row, its mappings and its history all stay. Stopping a stopped Worker is fine — it answers the same way. Bring it back with a re-provision, which is the call that costs a slot; stopping costs none, because it mints nothing. **The Worker stops answering in Slack straight away, in every room it serves.** # Update a worker Source: https://docs.ergoly.ai/api-reference/workers/update-a-worker /openapi.json patch /api/v1/workers/{id} These columns are what the agent's identity file is composed from, so editing `displayName` changes who the agent says it is from its next turn. That is why editing the file by hand is refused and this is not. `roleTitle` and `description` take `null` to clear them. A change to any of the three is also pushed to the Worker's installed Slack app, with no re-install: Slack shows the new name within a couple of minutes, punctuation in it becomes spaces, and @mentions show the new name. `slackApp` says whether that push happened; the saved fields stand either way. # Changelog Source: https://docs.ergoly.ai/changelog New features, improvements and fixes, every week. **November 2, 2026** Efficient recurring tasks, clearer failures, and worker renames This week made recurring tasks more efficient, made problems easier to see from your side, and made new workers steadier at getting started. ## More efficient recurring tasks Each run of a scheduled task now starts its own conversation instead of carrying every earlier run's history. A task that has been running for months gives each run focused attention, and the 200th run is as efficient as the first, which means savings for you on long-running tasks. ## A clear notice when a connection stops working When a connected app's sign-in or key is no longer valid, the person talking to the worker is told plainly what failed and who can fix it. The connection's owner is told what to do next. ## No more silence after a failed turn When a worker can't be reached or a turn fails, the person who wrote to it now hears that something went wrong. Before, they could get silence or a misleading “complete”. ## Renames reach Slack Renaming a worker now updates the name of its installed Slack app within a couple of minutes, with no re-install. The worker introduces itself by its new name on its next turn. ## Fixes * **New workers more reliably go to work.** Setup is steadier, so a newly created worker is more likely to come up and start working the first time. [Link to this entry](/changelog/2026-11-02-scheduled-task-cost-and-reliability) **October 26, 2026** Tasks launch, and webhooks that start work Tasks are now the way work moves between workers and people, with a board in the web app to see where everything stands. Outside events can also start a worker's work through a webhook. ## Tasks you can hand off A task records who asked, who holds it now, when it starts, when it's due and a running log of what happened. Tasks move between workers and people, and each new entry wakes the other side. Your existing scheduled tasks now live on the same model. ## The tasks board One place in the web app shows every task across your workers: scheduled, in progress and closed, what's late, each task's log, and actions on the tasks assigned to you or that you asked for. ## Tasks in the API and in workers' skills The same task operations are available through your own API key at /api/v1/tasks. Workers create, hand off, comment on, close and list tasks through built-in skills, with guidance on how to work a task. ## Webhooks that start a worker's work An outside event, such as a listing going down or a form being sent, can now start a worker's work for one of your clients, with the result posted in that client's channel. Set one up by asking your worker in Slack or from the Tasks page. The secret is sent to you privately, once. Several events can run side by side, and a reply that @mentions the worker in the thread within 7 days continues the run. ## Improvements * **Custom tool servers pick up new tools.** Tools you add to your own MCP server after connecting can now be listed and called without reconnecting. ## Fixes * **Scheduled tasks run once.** Overlapping schedule checks could start the same task a second time a couple of minutes later. Each occurrence now runs once. * **Workers stay quiet when not addressed.** In shared channels, a worker no longer posts “not able to pick this up” or “not set up for this channel” on messages that never mentioned it. * **A clear message for an expired Slack token.** If the stored Slack token no longer works, creating a worker now tells you to paste a fresh token in Settings, instead of leaving a failed worker behind. * **Memory keeps saving after a wake.** A timing problem could stop a worker's memory changes from being saved after it woke up. That is fixed. [Link to this entry](/changelog/2026-10-26-tasks-launch-and-webhooks) **October 19, 2026** Hand work between workers, and safer key connections Work can now be handed between workers and people as a task, and connecting or replacing an API key gives clearer, more accurate results. ## Tasks as the unit of work A task is a record of work that one worker or person hands to another, with a log of what was asked, done and decided. It survives restarts and shows who holds it now. Slack is one place a worker can report, not the only place the work lives. Tasks with no activity are archived after 30 days by default. ## Improvements * **Clearer feedback when a key is refused.** The connection check now tells a key the vendor refused apart from an answer it couldn't interpret, and the connection card keeps the result. * **Reconnecting a key app tests the new key.** Reconnecting an expired key connection now checks the pasted key straight away, so a bad key is refused on the spot instead of showing Active and failing on the worker's first call. * **An accurate message when you replace a key.** After a successful swap, the sheet says “N agent(s) now use the new key” instead of “Nothing changed”. * **Only valid places to put a connection.** A connection can no longer be placed on a worker-and-client pairing that has no running agent to use it. Those options are greyed out, with the reason. ## Fixes * **Scheduled from a DM, answered in the DM.** A job you schedule in a DM with a worker now sends each result back to you by DM. Before, the worker promised a DM and nothing arrived. * **Working keys are no longer refused over a “not allowed” answer.** If an app's test address says “not allowed here”, the key is saved as unconfirmed with the vendor's message shown, instead of being refused. A working connection is never expired because one call was denied. A key the vendor actually rejects is still refused. [Link to this entry](/changelog/2026-10-19-tasks-and-key-connections) **October 12, 2026** Workers that see whole messages, know your org, and adopt your skills This week made workers more aware of the people and teams around them, and closed several gaps where a message could go unanswered. ## Workers see the whole Slack message Text, Block Kit blocks, attachments and files now reach the worker in full, no matter who posted them. A table someone pastes in is no longer dropped. ## Workers know your org chart A worker knows who it reports to, who the other workers are and what each is responsible for. It can point people to the right colleague instead of taking on someone else's job. ## Workers can adopt a skill you hand them Give a worker a skill from another platform, such as a Claude skill, and it turns it into one of its own. It agrees naming and placement with its manager, sets up the connections it needs with a person, and offers to test it. ## The Ergoly expert can set up an org from your skills Hand it your skills and it proposes a set of workers. It creates them once you approve, and gives each its skills. It also suggests the right channel for the work, and opens a new private one when none fits. ## Guides on how AI and human teams work Every worker, and anyone configuring one, can open Ergoly's principles on when to bring in a teammate, when a worker should become a team, and who approves what. ## Workers can turn themselves back up A worker you asked to go quiet in a room can now be asked to start answering again, and does so itself, without anyone going to the control panel. ## Improvements * **A cleaner Worker page.** The worker's profile now sits in the page header, and the overview is four editable, properly rendered sections. Use the pencil to edit one in place. * **New workers start on the latest model.** Newly created workers default to Claude Sonnet 5.5. ## Fixes * **No more lost messages while a worker wakes.** A message could be dropped if the worker was put to sleep at the exact moment it arrived. The turn now runs. * **No more unanswered messages when a conversation couldn't be created.** If a brief rate limit or timeout stopped a new thread's conversation from being created, the message went unanswered. The platform now waits and tries again, so people still get a reply. * **Slack reads work again.** Requests to read a thread, channel history or look up a person were failing quietly, and the worker carried on without that context. * **Clearer “unverified” key connections.** Creating a key connection now says why it came back unverified, so it is no longer mistaken for a rejected key. * **Friendlier missing pages.** A web address with no page now sends visitors to the home page instead of a generic error. [Link to this entry](/changelog/2026-10-12-smarter-workers-whole-messages) **October 5, 2026** Vendors on your org chart, and task runs that settle cleanly A smaller week: external companies can now appear on your org chart, and a task that fails at startup no longer gets stuck. ## Vendors on the org chart External companies can now be added to the Company org chart alongside your workers and people. Each vendor carries a logo, a website, a short description, a lead and a list of members, and can be shown or hidden per operator. ## Improvements * **Ongoing security hardening.** We shipped a round of security fixes and hardening measures. ## Fixes * **Stuck task runs.** A task that failed before it could start used to sit in a pending state indefinitely. It now settles as failed, posts a notice in the run's thread and clears. [Link to this entry](/changelog/2026-10-05-vendors-on-org-chart) **September 28, 2026** Artifacts, approvals, and workers that manage their own tools Four new capabilities change how workers interact with people, what they're permitted to do, and how they connect to outside tools — plus a new way to publish rich, shareable pages straight from a conversation. ## Artifacts Workers can now publish self-contained pages that live in the control panel at a stable URL. Each page is private to your organization by default, or shareable by public link. Ask your worker for a report, a dashboard, a chart — anything you'd want to pass around as a link — and it handles the rest. ## Approval flows Ask your worker to “get approval before” doing something and it posts Approve and Reject buttons in the conversation. Whoever presses one starts a new turn that records who decided and when, and the buttons retire the moment they're used. ## Workers manage their own tools Ask your worker in Slack to connect an app, take an API key, or reconnect a service. For sign-in apps it posts a link anyone in the conversation can approve; for key-based apps, paste the key and it's stored securely. Each worker stays in its own lane — organization-wide connections are still made on the Connections page. ## Responsibilities and behaviors Every worker now has two short, editable lists on its page in the control panel: what it's responsible for, and how it goes about its work. Both start empty and change nothing until you fill them in. Edit them yourself, or ask your worker to propose an update when you hand it something new to own. ## Slack's new agent experience New workers install as Slack's current agent experience. When you DM a worker you'll see just the conversation — no more separate Messages and History tabs. ## Improvements * **Rename connections.** Connections can now be renamed from the Connections page. * **Smarter channel onboarding.** Invite a worker to a channel and it privately suggests to you what the room might be for, based on its name and members. Workers leave immediately if added by a Slack Connect guest. * **Progress updates in place.** Each turn's status is posted once and updated as the turn runs, instead of occasionally splitting into several messages. * **Long turns no longer look frozen.** A turn running past five minutes now shows a clear error state rather than appearing stuck. * **Two accounts of the same app.** You can now connect a second account of an app you already use — two Attio workspaces on different workers, for example. ## Fixes * **API key field names.** Connecting an app by API key now sends the key under the field name that app expects. Apps that named the field differently were being refused. * **Apps that need extra fields.** Apps that need more than a key, like a region or subdomain, now get correct defaults when a worker connects them, and a failed check no longer leaves a stray account behind. [Link to this entry](/changelog/2026-09-28-approval-flows-self-managed-connections) **September 21, 2026** Workers can see images, and connections that stay connected Workers can look at what you send them for the first time, and third-party connections are both faster to set up and much harder to knock over. ## Workers can see images A photo, screenshot or diagram attached to a Slack message — or stored in a worker's memory — now reaches the worker as an image it can actually look at, rather than unreadable data. Ask about a chart, a mockup or a whiteboard photo and get a real answer. ## A faster Connect sheet The app catalog on the Connections page now opens instantly and caches what it loads, removing the four-to-six-second wait every time you opened it. ## Improvements * **Clearer direct API connections.** For services connected by base URL rather than from the catalog, workers now see the full registered address and know it's a direct API, so they build correct requests without guessing. ## Fixes * **Permission errors no longer disconnect.** When a service refused one specific call, the whole connection was being marked expired. Now only a genuinely invalid or revoked credential disconnects; a missing permission shows up as a clear “not permitted for this call” and the connection stays live. * **Reconnect links complete.** Reconnecting a key-based app through its link no longer lands on a mismatch error when the reconnect actually worked. * **Real @mentions.** Workers occasionally posted mention markup as plain text, so the person was never notified. Mentions now render as real Slack @mentions. * **Moving older API keys across.** Keys for services outside the app catalog now carry over correctly when an organization moves to the new connection system. * **Credentials kept out of logs.** A failed command in a worker's sandbox could write an internal access token into the sandbox log. It no longer can. [Link to this entry](/changelog/2026-09-21-connections-fixes-image-read) **September 14, 2026** Connections: hundreds of apps, one page This release is about how workers reach the rest of your stack. A new connections system gives every worker access to hundreds of ready-made apps — Google Sheets, HubSpot, Linear and many more — along with custom MCP servers and any service with an API key, all managed from one Connections page. ## A single Connections page Each connection now shows what it is, which account is signed in, where it's used and whether it's healthy. Click one to finish setting it up or change it. Older connections move to a Legacy tab and keep working exactly as before. ## The full app catalog Adding a connection opens a picker organized by category, with popular apps up front and the entire catalog one click away. Custom MCP servers, your own OAuth app and raw API keys are always options. ## Any API, by key A service that isn't in the catalog can be connected with its API key from the same page. The key is stored securely and the worker can use that service's full API through it. ## One way to use every tool Workers list, search and run whatever their connections provide through a single built-in skill, with no per-service setup. Every turn, a worker knows exactly what it has access to. ## Progress you can read Progress updates now read as narrated reasoning: each step in plain English, a header that describes the work, and a clean close when the turn ends. No more internal step names. ## Improvements * **DM anyone.** A worker asked to message a colleague can now DM anyone the bot can see, not only people tied to a client. If a delivery fails, the notice names the person rather than showing a Slack ID. * **Set the escalation contact.** Choose who a worker escalates to directly in its settings. * **Inbound webhooks.** Workers can create their own inbound webhook endpoints, so events from outside services can kick off work. ## Fixes * **Authenticated calls.** Some outbound requests — web searches among them — were going out without their credentials and failing. Every credentialed call is now authenticated correctly. * **API key page redirect.** Admins who hadn't finished setup were bounced to the setup flow when creating an API key. The settings page now stays put. [Link to this entry](/changelog/2026-09-14-composio-connections-launch) **September 7, 2026** Workers get their own email Email sending is live, and workers are substantially more reliable at reading the conversation they're in, finding their own skills and knowing who's in the room. ## Worker email Every worker now has its own address and can send email directly. The control panel shows your organization's sending domain, its DNS records, each worker's address and an on/off switch, and every message sent is logged. ## Workers know what they know Each turn, a worker sees an index of everything in its memory, with a description for every file. It can check what it knows before saying it doesn't — fewer invented or inconsistent answers. ## Better at Slack Workers look up who's in a channel, who a person is and what was said earlier directly, without a detour. They also report progress mid-turn without sending a reply, and escalations reliably reach a person. ## Scheduled tasks can do what a live turn can A scheduled run can now post into a thread, a DM or a new message — anything a worker can do when you're talking to it. ## Fixes * **Thread context.** Workers couldn't always read the thread they were replying in. They now have the full thread on every turn. * **Knowing itself.** Workers sometimes read their own @mention as someone else's and mixed up people in the room. They now know their own identity. * **Channel setup menu.** The menu shown when a worker first joins a channel wasn't appearing. It's back. * **Connections and new-worker setup.** Both pages could fail to load with an error. Fixed. * **Switching organizations.** Switching organization from the sidebar led to a missing page. It now lands where it should. * **Company page scrolling.** A wide org chart scrolled the whole page sideways. The chart now pans and zooms inside its own frame. * **Silent Slack failures.** When Slack rejected a reply, nobody found out. The worker now posts a notice that something went wrong. [Link to this entry](/changelog/2026-09-07-email-launch-v2-hardening) **August 31, 2026** The platform API, a simpler worker, and better scheduled tasks Three large changes this week — a public API, a simpler worker underneath every teammate, and scheduled tasks rebuilt — plus a sweep of reliability fixes. ## The platform API Everything in your Ergoly environment — workers, clients, channel mappings, tasks, spend and connections — can now be read and changed through an organization-scoped REST API. Create and set up workers, map channels, schedule tasks and write memory with an API key. The API reference is linked from the control panel. ## A simpler, more consistent worker Every worker now runs on the same small set of core tools, with everything else expressed as skills it reads and follows. Workers behave the same way across your organization and are easier to extend. ## Scheduled tasks, rebuilt Each run gets its own Slack thread and can be interrupted with a reply. Tasks run as a named person, can target several clients from one definition, and can be seen and managed in the control panel. ## The Company page A new page in the control panel shows your workers, people and teams as an org chart. Create teams and open roles, add people from Slack, and drag to reorganize. ## Workers can read app messages When an app posts a rich message in Slack — a Linear card, a form submission, an alert — the worker now receives the whole thing, not just the one-line preview. ## Improvements * **Choose your avatar style.** Pick your organization's avatar style in settings; it applies to every worker straight away. * **App icons set automatically.** Installing a worker into Slack now sets its icon for you, with a button to re-push it if it changes. ## Fixes * **Long turns complete.** A model step longer than a minute could derail a turn. Long turns now finish correctly. * **Separate conversations for parallel runs.** Runs of a scheduled task that fired at the same time could share one conversation. Each run now gets its own. * **Usage metering.** Per-customer usage was being under-recorded. It's now accurate. * **No more stuck approvals.** A stuck approval state could hold a worker indefinitely. The cause is fixed. * **Client channels recognized.** Workers sometimes treated a client channel as a private DM and declined to use that client's connections. Fixed. * **Timeouts named correctly.** A scheduled task that ran out of time now reports a timeout, not a generic failure. * **Control panel stability.** Crashes on the organization dashboard and the worker page are resolved. [Link to this entry](/changelog/2026-08-31-agent-surface-platform-api) **August 24, 2026** Streamed replies, richer output, and a reliability sprint The biggest change yet to how your worker speaks in Slack, plus a round of fixes aimed at the failures we heard about most. ## Live streamed replies Instead of sending several messages while it works, your worker now posts one message that updates in place. Named progress steps appear as they happen, then the answer streams in underneath. The channel stays readable and you always know where things stand. ## Tables and files Workers can send properly formatted tables and upload files directly into Slack. A comparison, a list of records or a report arrives as a real table instead of a wall of text. ## One place for memory The Knowledge tab in the control panel now shows a worker's memory as a single file tree with named folders, instead of four separate views. ## Improvements * **Faster long tasks.** Workers run longer scripts more efficiently, so big tasks finish sooner. ## Fixes * **No more phantom deliveries.** After a failed turn, a worker could claim work was waiting in a thread where nothing had been posted. It now knows whether its last reply landed. * **Quotes no longer cut replies short.** A reply containing a quotation mark was being truncated at the quote. * **Scheduled tasks get the full time.** Task runs were stopped after a minute. They now get the same 30 minutes as a live turn. * **Listen-only means listen-only.** Workers set to listen without speaking could still post in some cases. No longer. * **Accurate explanations.** Workers sometimes told people a message had been suppressed when it had been delivered. They now describe their own behavior correctly. * **Recovering from stuck states.** Many stuck-worker reports traced to one family of bugs, now reworked. Workers recover from these on their own instead of waiting for a reset. * **Messages during start-up.** Two messages arriving while a worker was waking could cause the second to fail. Both are now answered. [Link to this entry](/changelog/2026-08-24-streamed-turns-and-reliability) # Streamed replies, richer output, and a reliability sprint Source: https://docs.ergoly.ai/changelog/2026-08-24-streamed-turns-and-reliability Workers now reply in a single updating message instead of a stream of interruptions, tables and file attachments work, and a wave of fixes closes the most common causes of a stuck worker. *August 24, 2026* The biggest change yet to how your worker speaks in Slack, plus a round of fixes aimed at the failures we heard about most. ## Live streamed replies Instead of sending several messages while it works, your worker now posts one message that updates in place. Named progress steps appear as they happen, then the answer streams in underneath. The channel stays readable and you always know where things stand. ## Tables and files Workers can send properly formatted tables and upload files directly into Slack. A comparison, a list of records or a report arrives as a real table instead of a wall of text. ## One place for memory The Knowledge tab in the control panel now shows a worker's memory as a single file tree with named folders, instead of four separate views. ## Improvements * **Faster long tasks.** Workers run longer scripts more efficiently, so big tasks finish sooner. ## Fixes * **No more phantom deliveries.** After a failed turn, a worker could claim work was waiting in a thread where nothing had been posted. It now knows whether its last reply landed. * **Quotes no longer cut replies short.** A reply containing a quotation mark was being truncated at the quote. * **Scheduled tasks get the full time.** Task runs were stopped after a minute. They now get the same 30 minutes as a live turn. * **Listen-only means listen-only.** Workers set to listen without speaking could still post in some cases. No longer. * **Accurate explanations.** Workers sometimes told people a message had been suppressed when it had been delivered. They now describe their own behavior correctly. * **Recovering from stuck states.** Many stuck-worker reports traced to one family of bugs, now reworked. Workers recover from these on their own instead of waiting for a reset. * **Messages during start-up.** Two messages arriving while a worker was waking could cause the second to fail. Both are now answered. # The platform API, a simpler worker, and better scheduled tasks Source: https://docs.ergoly.ai/changelog/2026-08-31-agent-surface-platform-api A full API for managing your Ergoly environment in code, a leaner and more consistent worker, and a scheduled-task overhaul with a thread per run and multi-client targeting. *August 31, 2026* Three large changes this week — a public API, a simpler worker underneath every teammate, and scheduled tasks rebuilt — plus a sweep of reliability fixes. ## The platform API Everything in your Ergoly environment — workers, clients, channel mappings, tasks, spend and connections — can now be read and changed through an organization-scoped REST API. Create and set up workers, map channels, schedule tasks and write memory with an API key. The API reference is linked from the control panel. ## A simpler, more consistent worker Every worker now runs on the same small set of core tools, with everything else expressed as skills it reads and follows. Workers behave the same way across your organization and are easier to extend. ## Scheduled tasks, rebuilt Each run gets its own Slack thread and can be interrupted with a reply. Tasks run as a named person, can target several clients from one definition, and can be seen and managed in the control panel. ## The Company page A new page in the control panel shows your workers, people and teams as an org chart. Create teams and open roles, add people from Slack, and drag to reorganize. ## Workers can read app messages When an app posts a rich message in Slack — a Linear card, a form submission, an alert — the worker now receives the whole thing, not just the one-line preview. ## Improvements * **Choose your avatar style.** Pick your organization's avatar style in settings; it applies to every worker straight away. * **App icons set automatically.** Installing a worker into Slack now sets its icon for you, with a button to re-push it if it changes. ## Fixes * **Long turns complete.** A model step longer than a minute could derail a turn. Long turns now finish correctly. * **Separate conversations for parallel runs.** Runs of a scheduled task that fired at the same time could share one conversation. Each run now gets its own. * **Usage metering.** Per-customer usage was being under-recorded. It's now accurate. * **No more stuck approvals.** A stuck approval state could hold a worker indefinitely. The cause is fixed. * **Client channels recognized.** Workers sometimes treated a client channel as a private DM and declined to use that client's connections. Fixed. * **Timeouts named correctly.** A scheduled task that ran out of time now reports a timeout, not a generic failure. * **Control panel stability.** Crashes on the organization dashboard and the worker page are resolved. # Workers get their own email Source: https://docs.ergoly.ai/changelog/2026-09-07-email-launch-v2-hardening Every worker can now send email from its own address, and workers are noticeably better at knowing what they know, reading Slack threads and recovering from errors. *September 7, 2026* Email sending is live, and workers are substantially more reliable at reading the conversation they're in, finding their own skills and knowing who's in the room. ## Worker email Every worker now has its own address and can send email directly. The control panel shows your organization's sending domain, its DNS records, each worker's address and an on/off switch, and every message sent is logged. ## Workers know what they know Each turn, a worker sees an index of everything in its memory, with a description for every file. It can check what it knows before saying it doesn't — fewer invented or inconsistent answers. ## Better at Slack Workers look up who's in a channel, who a person is and what was said earlier directly, without a detour. They also report progress mid-turn without sending a reply, and escalations reliably reach a person. ## Scheduled tasks can do what a live turn can A scheduled run can now post into a thread, a DM or a new message — anything a worker can do when you're talking to it. ## Fixes * **Thread context.** Workers couldn't always read the thread they were replying in. They now have the full thread on every turn. * **Knowing itself.** Workers sometimes read their own @mention as someone else's and mixed up people in the room. They now know their own identity. * **Channel setup menu.** The menu shown when a worker first joins a channel wasn't appearing. It's back. * **Connections and new-worker setup.** Both pages could fail to load with an error. Fixed. * **Switching organizations.** Switching organization from the sidebar led to a missing page. It now lands where it should. * **Company page scrolling.** A wide org chart scrolled the whole page sideways. The chart now pans and zooms inside its own frame. * **Silent Slack failures.** When Slack rejected a reply, nobody found out. The worker now posts a notice that something went wrong. # Connections: hundreds of apps, one page Source: https://docs.ergoly.ai/changelog/2026-09-14-composio-connections-launch Workers can now connect to hundreds of third-party apps through a single Connections page, progress messages read like a person wrote them, and authenticated API calls go out correctly again. *September 14, 2026* This release is about how workers reach the rest of your stack. A new connections system gives every worker access to hundreds of ready-made apps — Google Sheets, HubSpot, Linear and many more — along with custom MCP servers and any service with an API key, all managed from one Connections page. ## A single Connections page Each connection now shows what it is, which account is signed in, where it's used and whether it's healthy. Click one to finish setting it up or change it. Older connections move to a Legacy tab and keep working exactly as before. ## The full app catalog Adding a connection opens a picker organized by category, with popular apps up front and the entire catalog one click away. Custom MCP servers, your own OAuth app and raw API keys are always options. ## Any API, by key A service that isn't in the catalog can be connected with its API key from the same page. The key is stored securely and the worker can use that service's full API through it. ## One way to use every tool Workers list, search and run whatever their connections provide through a single built-in skill, with no per-service setup. Every turn, a worker knows exactly what it has access to. ## Progress you can read Progress updates now read as narrated reasoning: each step in plain English, a header that describes the work, and a clean close when the turn ends. No more internal step names. ## Improvements * **DM anyone.** A worker asked to message a colleague can now DM anyone the bot can see, not only people tied to a client. If a delivery fails, the notice names the person rather than showing a Slack ID. * **Set the escalation contact.** Choose who a worker escalates to directly in its settings. * **Inbound webhooks.** Workers can create their own inbound webhook endpoints, so events from outside services can kick off work. ## Fixes * **Authenticated calls.** Some outbound requests — web searches among them — were going out without their credentials and failing. Every credentialed call is now authenticated correctly. * **API key page redirect.** Admins who hadn't finished setup were bounced to the setup flow when creating an API key. The settings page now stays put. # Workers can see images, and connections that stay connected Source: https://docs.ergoly.ai/changelog/2026-09-21-connections-fixes-image-read Workers can now read and respond to images. A permission refusal no longer disconnects an integration, and connection setup is noticeably faster. *September 21, 2026* Workers can look at what you send them for the first time, and third-party connections are both faster to set up and much harder to knock over. ## Workers can see images A photo, screenshot or diagram attached to a Slack message — or stored in a worker's memory — now reaches the worker as an image it can actually look at, rather than unreadable data. Ask about a chart, a mockup or a whiteboard photo and get a real answer. ## A faster Connect sheet The app catalog on the Connections page now opens instantly and caches what it loads, removing the four-to-six-second wait every time you opened it. ## Improvements * **Clearer direct API connections.** For services connected by base URL rather than from the catalog, workers now see the full registered address and know it's a direct API, so they build correct requests without guessing. ## Fixes * **Permission errors no longer disconnect.** When a service refused one specific call, the whole connection was being marked expired. Now only a genuinely invalid or revoked credential disconnects; a missing permission shows up as a clear “not permitted for this call” and the connection stays live. * **Reconnect links complete.** Reconnecting a key-based app through its link no longer lands on a mismatch error when the reconnect actually worked. * **Real @mentions.** Workers occasionally posted mention markup as plain text, so the person was never notified. Mentions now render as real Slack @mentions. * **Moving older API keys across.** Keys for services outside the app catalog now carry over correctly when an organization moves to the new connection system. * **Credentials kept out of logs.** A failed command in a worker's sandbox could write an internal access token into the sandbox log. It no longer can. # Artifacts, approvals, and workers that manage their own tools Source: https://docs.ergoly.ai/changelog/2026-09-28-approval-flows-self-managed-connections Workers can now publish shareable pages, handle approvals end-to-end in Slack, and connect their own tools — and each worker carries a responsibility scope and behaviors you control. *September 28, 2026* Four new capabilities change how workers interact with people, what they're permitted to do, and how they connect to outside tools — plus a new way to publish rich, shareable pages straight from a conversation. ## Artifacts Workers can now publish self-contained pages that live in the control panel at a stable URL. Each page is private to your organization by default, or shareable by public link. Ask your worker for a report, a dashboard, a chart — anything you'd want to pass around as a link — and it handles the rest. ## Approval flows Ask your worker to “get approval before” doing something and it posts Approve and Reject buttons in the conversation. Whoever presses one starts a new turn that records who decided and when, and the buttons retire the moment they're used. ## Workers manage their own tools Ask your worker in Slack to connect an app, take an API key, or reconnect a service. For sign-in apps it posts a link anyone in the conversation can approve; for key-based apps, paste the key and it's stored securely. Each worker stays in its own lane — organization-wide connections are still made on the Connections page. ## Responsibilities and behaviors Every worker now has two short, editable lists on its page in the control panel: what it's responsible for, and how it goes about its work. Both start empty and change nothing until you fill them in. Edit them yourself, or ask your worker to propose an update when you hand it something new to own. ## Slack's new agent experience New workers install as Slack's current agent experience. When you DM a worker you'll see just the conversation — no more separate Messages and History tabs. ## Improvements * **Rename connections.** Connections can now be renamed from the Connections page. * **Smarter channel onboarding.** Invite a worker to a channel and it privately suggests to you what the room might be for, based on its name and members. Workers leave immediately if added by a Slack Connect guest. * **Progress updates in place.** Each turn's status is posted once and updated as the turn runs, instead of occasionally splitting into several messages. * **Long turns no longer look frozen.** A turn running past five minutes now shows a clear error state rather than appearing stuck. * **Two accounts of the same app.** You can now connect a second account of an app you already use — two Attio workspaces on different workers, for example. ## Fixes * **API key field names.** Connecting an app by API key now sends the key under the field name that app expects. Apps that named the field differently were being refused. * **Apps that need extra fields.** Apps that need more than a key, like a region or subdomain, now get correct defaults when a worker connects them, and a failed check no longer leaves a stray account behind. # Vendors on your org chart, and task runs that settle cleanly Source: https://docs.ergoly.ai/changelog/2026-10-05-vendors-on-org-chart External companies can now appear on your org chart, and a task that fails at startup now settles cleanly instead of getting stuck. *October 5, 2026* A smaller week: external companies can now appear on your org chart, and a task that fails at startup no longer gets stuck. ## Vendors on the org chart External companies can now be added to the Company org chart alongside your workers and people. Each vendor carries a logo, a website, a short description, a lead and a list of members, and can be shown or hidden per operator. ## Improvements * **Ongoing security hardening.** We shipped a round of security fixes and hardening measures. ## Fixes * **Stuck task runs.** A task that failed before it could start used to sit in a pending state indefinitely. It now settles as failed, posts a notice in the run's thread and clears. # Workers that see whole messages, know your org, and adopt your skills Source: https://docs.ergoly.ai/changelog/2026-10-12-smarter-workers-whole-messages Workers now see every part of a Slack message, know your org chart, can adopt skills you hand them, and can turn themselves back up after being quieted. Several causes of missed or unanswered messages are fixed. *October 12, 2026* This week made workers more aware of the people and teams around them, and closed several gaps where a message could go unanswered. ## Workers see the whole Slack message Text, Block Kit blocks, attachments and files now reach the worker in full, no matter who posted them. A table someone pastes in is no longer dropped. ## Workers know your org chart A worker knows who it reports to, who the other workers are and what each is responsible for. It can point people to the right colleague instead of taking on someone else's job. ## Workers can adopt a skill you hand them Give a worker a skill from another platform, such as a Claude skill, and it turns it into one of its own. It agrees naming and placement with its manager, sets up the connections it needs with a person, and offers to test it. ## The Ergoly expert can set up an org from your skills Hand it your skills and it proposes a set of workers. It creates them once you approve, and gives each its skills. It also suggests the right channel for the work, and opens a new private one when none fits. ## Guides on how AI and human teams work Every worker, and anyone configuring one, can open Ergoly's principles on when to bring in a teammate, when a worker should become a team, and who approves what. ## Workers can turn themselves back up A worker you asked to go quiet in a room can now be asked to start answering again, and does so itself, without anyone going to the control panel. ## Improvements * **A cleaner Worker page.** The worker's profile now sits in the page header, and the overview is four editable, properly rendered sections. Use the pencil to edit one in place. * **New workers start on the latest model.** Newly created workers default to Claude Sonnet 5.5. ## Fixes * **No more lost messages while a worker wakes.** A message could be dropped if the worker was put to sleep at the exact moment it arrived. The turn now runs. * **No more unanswered messages when a conversation couldn't be created.** If a brief rate limit or timeout stopped a new thread's conversation from being created, the message went unanswered. The platform now waits and tries again, so people still get a reply. * **Slack reads work again.** Requests to read a thread, channel history or look up a person were failing quietly, and the worker carried on without that context. * **Clearer “unverified” key connections.** Creating a key connection now says why it came back unverified, so it is no longer mistaken for a rejected key. * **Friendlier missing pages.** A web address with no page now sends visitors to the home page instead of a generic error. # Hand work between workers, and safer key connections Source: https://docs.ergoly.ai/changelog/2026-10-19-tasks-and-key-connections Work can now be handed between workers and people as a task, and connecting or replacing an API key gives clearer, more accurate results. A task scheduled from a DM now delivers its result by DM. *October 19, 2026* Work can now be handed between workers and people as a task, and connecting or replacing an API key gives clearer, more accurate results. ## Tasks as the unit of work A task is a record of work that one worker or person hands to another, with a log of what was asked, done and decided. It survives restarts and shows who holds it now. Slack is one place a worker can report, not the only place the work lives. Tasks with no activity are archived after 30 days by default. ## Improvements * **Clearer feedback when a key is refused.** The connection check now tells a key the vendor refused apart from an answer it couldn't interpret, and the connection card keeps the result. * **Reconnecting a key app tests the new key.** Reconnecting an expired key connection now checks the pasted key straight away, so a bad key is refused on the spot instead of showing Active and failing on the worker's first call. * **An accurate message when you replace a key.** After a successful swap, the sheet says “N agent(s) now use the new key” instead of “Nothing changed”. * **Only valid places to put a connection.** A connection can no longer be placed on a worker-and-client pairing that has no running agent to use it. Those options are greyed out, with the reason. ## Fixes * **Scheduled from a DM, answered in the DM.** A job you schedule in a DM with a worker now sends each result back to you by DM. Before, the worker promised a DM and nothing arrived. * **Working keys are no longer refused over a “not allowed” answer.** If an app's test address says “not allowed here”, the key is saved as unconfirmed with the vendor's message shown, instead of being refused. A working connection is never expired because one call was denied. A key the vendor actually rejects is still refused. # Tasks launch, and webhooks that start work Source: https://docs.ergoly.ai/changelog/2026-10-26-tasks-launch-and-webhooks Tasks are now the way work is handed between workers and people, with a board in the web app. Outside events, like a listing going down, can also start a worker's work through a webhook. *October 26, 2026* Tasks are now the way work moves between workers and people, with a board in the web app to see where everything stands. Outside events can also start a worker's work through a webhook. ## Tasks you can hand off A task records who asked, who holds it now, when it starts, when it's due and a running log of what happened. Tasks move between workers and people, and each new entry wakes the other side. Your existing scheduled tasks now live on the same model. ## The tasks board One place in the web app shows every task across your workers: scheduled, in progress and closed, what's late, each task's log, and actions on the tasks assigned to you or that you asked for. ## Tasks in the API and in workers' skills The same task operations are available through your own API key at /api/v1/tasks. Workers create, hand off, comment on, close and list tasks through built-in skills, with guidance on how to work a task. ## Webhooks that start a worker's work An outside event, such as a listing going down or a form being sent, can now start a worker's work for one of your clients, with the result posted in that client's channel. Set one up by asking your worker in Slack or from the Tasks page. The secret is sent to you privately, once. Several events can run side by side, and a reply that @mentions the worker in the thread within 7 days continues the run. ## Improvements * **Custom tool servers pick up new tools.** Tools you add to your own MCP server after connecting can now be listed and called without reconnecting. ## Fixes * **Scheduled tasks run once.** Overlapping schedule checks could start the same task a second time a couple of minutes later. Each occurrence now runs once. * **Workers stay quiet when not addressed.** In shared channels, a worker no longer posts “not able to pick this up” or “not set up for this channel” on messages that never mentioned it. * **A clear message for an expired Slack token.** If the stored Slack token no longer works, creating a worker now tells you to paste a fresh token in Settings, instead of leaving a failed worker behind. * **Memory keeps saving after a wake.** A timing problem could stop a worker's memory changes from being saved after it woke up. That is fixed. # Efficient recurring tasks, clearer failures, and worker renames Source: https://docs.ergoly.ai/changelog/2026-11-02-scheduled-task-cost-and-reliability Long-running recurring tasks are now more efficient and stay focused on the current run, a failed turn is no longer met with silence, renaming a worker updates its name in Slack, and new workers more reliably go to work. *November 2, 2026* This week made recurring tasks more efficient, made problems easier to see from your side, and made new workers steadier at getting started. ## More efficient recurring tasks Each run of a scheduled task now starts its own conversation instead of carrying every earlier run's history. A task that has been running for months gives each run focused attention, and the 200th run is as efficient as the first, which means savings for you on long-running tasks. ## A clear notice when a connection stops working When a connected app's sign-in or key is no longer valid, the person talking to the worker is told plainly what failed and who can fix it. The connection's owner is told what to do next. ## No more silence after a failed turn When a worker can't be reached or a turn fails, the person who wrote to it now hears that something went wrong. Before, they could get silence or a misleading “complete”. ## Renames reach Slack Renaming a worker now updates the name of its installed Slack app within a couple of minutes, with no re-install. The worker introduces itself by its new name on its next turn. ## Fixes * **New workers more reliably go to work.** Setup is steadier, so a newly created worker is more likely to come up and start working the first time. # Clients Source: https://docs.ergoly.ai/clients A customer of yours. Assign a worker to a client and that client gets its own copy, with its own memory and nothing of any other client's. A **client** is a company you work for. On its own, a client in Ergoly is a record: a name, a website, a logo. It starts doing something when you assign a worker to it. From then on there is a copy of that worker for that client, and every channel and person you link to the client reaches that copy. The **Clients** page lists them with tabs for Active, Inactive and Archived, and each client's page has four tabs: **Overview** (the About text, details, and Channels & People), **Workers**, **Tasks**, and **Connections**. > [card] [Adding a client](/clients/adding) > > From the AI Admin, the Clients page, or the chart. > [card] [Assigning a worker](/clients/assigning-a-worker) > > What it creates, and the channels and people that go with it. > [card] [Client separation](/clients/separation) > > What a client's worker can and cannot see. > [card] [Internal client channels](/clients/internal-channels) > > Backstage before the client channel. # Adding a client Source: https://docs.ergoly.ai/clients/adding Three ways: ask your AI Admin, press New Client, or let a worker create one when it joins a channel. ## Ask your AI Admin Tell it the client's name and, if you have it, the website. It confirms what it is about to create and does it on your yes. Your agency Channels Workers Ada ## In control 1. Open **Clients** and press **New Client**, or open **Company**, press **Add**, and choose **Client**. 2. Type the **Company name**. The slug under it is the client's short name in URLs; click it to change it. 3. Add the **Website URL** if you have it. Ergoly uses it for the logo and a public description. 4. Optionally paste a **Slack Channel ID** for the channel you share with the client. You can do this later from the worker instead. 5. Press **Create client**. ## From a channel When a worker joins a channel and no client matches, it offers **New client…**. That creates the client and maps the channel to it in one step. See [Slack](/workers/channels/slack). > [!NOTE] > > **Worth knowing.** A client with no worker assigned does nothing. The next step is [assigning a worker](/clients/assigning-a-worker). # Assigning a worker Source: https://docs.ergoly.ai/clients/assigning-a-worker Bind a worker to a client, with at least one channel or person. That creates the client's own copy of the worker. Assigning a worker to a client creates a separate copy of that worker for that client. The copy starts with the company's knowledge and the worker's own, plus the client's folder, which is empty until the worker learns something. Everything it learns about Acme goes there and nowhere else. ## How 1. On the client's page, press **Bind a Worker**. Or on the worker's **Clients** tab, press **Add to client**. 2. Pick the **Worker** (or the **Client**). 3. Tick the **Channels** that belong to this client, and the **People** who are this client's contacts. At least one of either. The dialog explains the difference: *channels route by conversation, people route their DMs and group DMs*. 4. Press **Bind worker**. Control maps the channels, joins the public ones (private ones need you to `/invite` the worker first), links the people, and builds the copy. If building fails, the binding stays and the row offers **Activate** to try again. Or ask your AI Admin: *assign Nora to Globex in #globex*. ## Already taken A channel or person already linked to a different client is greyed out. Nothing is moved silently. To move a channel, use **Reassign** on the worker's Clients tab and confirm. ## Removing **Unbind** on the client's Workers tab, or **Remove** on the worker's Clients tab, removes every channel and person link for that pair and everything the worker set up for the client. The client's folder of knowledge stays with the client. | | What it reaches | | - | - | | Your team's copy of Nora | Every client's folder, the worker's, the company's | | Nora for Acme | Acme's folder, the worker's, the company's | | Nora for Globex | Globex's folder, the worker's, the company's | > [!NOTE] > > **Worth knowing.** Your AI Admin cannot be assigned to a client. It is internal-only by design. # Internal client channels Source: https://docs.ergoly.ai/clients/internal-channels Backstage: a channel of your own where the team reviews a worker's drafts for a client before the worker is in front of that client. Before a worker talks to Acme directly, give it a channel where your team can see what it would say. That channel is **internal**, because only your people are in it, but the work in it is about one client. ## Setting it up 1. Create the channel in Slack with your own people in it. 2. Invite the worker. When it asks what the channel is for, press **Internal channel**, not the client. 3. Ask the worker for the client's work there: *draft Acme's weekly status*. Your team's copy answers, with Acme's folder in reach, so the draft is about Acme. 4. When the drafts are right, invite the worker to the channel Acme is in, and set that one up for Acme. Your agency Channels Workers # acme-internal The team reviews in the internal channel. Nothing reaches Acme until someone sends it. ## Why it is internal Because your team's copy answers there, it knows the whole company: every client, every connection placed with the company. That is what you want backstage. In Acme's own channel, only Acme's copy answers, which knows less, on purpose. See [Client separation](/clients/separation). > [!NOTE] > > **Worth knowing.** Keep client contacts out of the internal channel. The channel decides who is answered, so a guest in an internal channel would be answered by your team's copy. # Client separation Source: https://docs.ergoly.ai/clients/separation What a client's copy of a worker can see, what it cannot, and what a client's contact can do. The copy of a worker that serves Acme has Acme's folder, the worker's own knowledge, and the company's. It does not have Globex's folder, Globex's connections, or Globex's people. There is no setting that changes this, and nothing a person types in Acme's channel can change it either, because which copy answers is decided from the channel before the worker reads a word. | | Nora for Acme | Your team's Nora | | - | - | - | | Acme's notes and preferences | Yes | Yes | | Globex's notes and preferences | No | Yes | | Connections placed with Acme | Yes | No, unless also placed wider | | Connections placed with the whole company | Yes | Yes | | People on the Company chart | Acme's own contacts and the workers serving Acme | Everyone | | Globex's channel | Never | Never; that is Globex's copy's | ## What a client's contact can do * Talk to the worker in their channel, and DM it once they are linked to the client. * Stop the worker's reply to their own message with `stop`. * Press buttons the worker posts for them, and ask it to be quieter. ## What a client's contact cannot do * Add the worker to a channel, or set a channel up. Only your workspace's admins can. * Stop a scheduled run. Only your own people can. * Reach your team's copy of the worker, or anything about another client. ## What travels up A fact about Acme stays with Acme. A lesson about the job, filed in the worker's folder by your team's copy, reaches every client. That is the point: the worker gets better at the work for everyone, and no client ever sees another's. See [Memory](/workers/knowledge/memory). > [!NOTE] > > **Worth knowing.** A client channel is never answered by your team's copy, even if the client's copy is down. Silence is the safe failure. > [card] [How a worker runs](/technical/how-a-worker-runs) > > The copies, underneath. > [card] [How credentials are held](/technical/how-credentials-are-held) > > Why a client's keys never reach another client's copy. # Company Source: https://docs.ergoly.ai/company Your agency on Ergoly: the chart of people and workers, the teams and clients, the settings, and who can do what. The **Company** page is a picture of your agency: who works here, people and workers alike, who reports to whom, and which clients and vendors you work with. Everything else in Ergoly belongs to the company, and nothing reaches across to another one. > [card] [Chart](/company/chart) > > Teams, people, workers, and open roles, and how to place them. > [card] [Members](/company/members) > > The People and Workers pages, and who can sign in to control. > [card] [Teams](/company/teams) > > Internal teams, clients, and vendors. > [card] [Settings](/company/settings) > > Slack, email, avatars, task archiving. > [card] [Access](/company/access) > > Admins and members, the AI Admin, and API keys. # Access Source: https://docs.ergoly.ai/company/access Three ways into your company: a person in control, the AI Admin in Slack, and an API key. ## People in control Everyone you invite under **Settings → Members** can use control. Two things are reserved for **admins**: creating and revoking API keys, and setting up the AI Admin. Both exist because each hands out a key to the whole company. ## The AI Admin in Slack Your AI Admin is a worker that works only for your team and holds its own API key. That is what lets it create workers, map channels, add clients and connect tools from a conversation. It can never be put in front of a client, and it asks before every change. See [Meet your AI Admin](/getting-started/ai-admin). ## API keys A key reaches everything your company owns, read and write. There is no narrower key. To create one: 1. Open **Settings**, then the **API keys** tab, and press **Create key**. 2. Give it a **Name** (the placeholder suggests *deploy-pipeline*) and an **Expiry**: never, 30 days, 90 days, or a year. 3. Copy it. Control says *This is the only time it is shown*, and means it. The list shows each key as **Yours**, **A worker's**, or **System-managed**, and any of them can be revoked. Revoking takes effect from the next request. What a key did before that is in the [activity feed](/work/approvals). > [!NOTE] > > **Worth knowing.** A key is not a person. Everything it writes is recorded under the key's own name, so give each job its own key and an expiry if the job has an end. > [card] [The API](/technical/api) > > The reference, the first call, and the shape of every answer. # Chart Source: https://docs.ergoly.ai/company/chart An org chart that holds people and workers side by side. Drag to place, and the chart decides who a worker turns to when it needs a person. The chart shows your agency as a tree: teams, the people in them, the workers in them, and open roles you have not filled yet. A person is anyone from your Slack workspace. A worker sits on the chart like a person does, with a title and someone it reports to. ## Adding to the chart Press **Add** at the top, or right-click empty canvas. The menu has two rows: **Individuals** (Person, Worker, Open role) and **Teams** (Team, Vendor, Client). A person is picked from Slack; a worker opens the new-worker page; an open role is a seat to fill later. ## Placing and moving * Drag a card onto another card to make it report there, onto a team to join it, or onto an open role to fill it. * The **No team** tray along the bottom holds everything not on the chart yet: new workers, clients nobody has placed, people from Slack. Drag out of it to place; drag onto it to remove. * Every card has a sheet. Open it to change the name or title, **Move…** it, or **Remove from chart**. Removing takes the card and everything under it back to the tray; nothing is deleted. * One seat can hold two people (**Share this seat**), and a person or worker can be placed in more than one spot. ## What to show The **Show on the chart and list** menu has two boxes: **Vendors** (on by default) and **Clients** (off by default). The **Chart** and **List** tabs show the same company two ways; List has a status filter. ## Why it matters to a worker The chart is a picture, not a permission. Placing a worker in a team does not change what it can see. It does decide one thing: when a worker needs a person, it goes to the nearest person above it on the chart, unless you set someone else. See [Reporting](/workers/reporting). > [!NOTE] > > **Worth knowing.** A team's lead is not a setting. It is simply the one seat directly under the team. # Members Source: https://docs.ergoly.ai/company/members People and workers are listed side by side. Who can sign in to control is a separate list. Two pages under Company list who works here. * **People**: One row per person from your Slack workspace who is on the chart, is a client's contact, or is waiting in the tray. Columns: Name, Team, Reports to. Nobody is invited here; people appear once a worker is installed in your workspace, and you place them. * **Workers**: One row per worker, with its team, the clients it serves, and its status. **New Worker** starts the create wizard. A row opens the worker's own page. ## Who can sign in Being on the chart does not give someone a login. Logins to control are managed under **Settings**, on the **Members** tab, where you invite people by email and set their role. An **admin** can invite people, create API keys, and set up the AI Admin. A **member** can do everything else. ## Worker statuses | Status | Meaning | | - | - | | Active | Installed and answering. | | Onboarding · Provisioning | Being built. Give it a few minutes. | | Onboarding · Awaiting install | Waiting for a Slack admin to click Allow. | | Active · Stopped | Paused from the worker's Settings tab. | | Failed / Error | Something went wrong during setup. Open the worker for details and a Retry. | | Quarantined | Ergoly stopped it after repeated failures. The worker's page says why and has an Unquarantine button. | # Settings Source: https://docs.ergoly.ai/company/settings Six tabs: Slack, Members, API keys, Avatars, Email, and Tasks. * **Slack**: The connection Ergoly uses to create Slack apps in your workspace. It shows **Configured** or **Not yet set up**, the linked workspace's name, and a **Refresh token** field with **Save**, **Rotate**, and **Test connection**. You set this during setup; come back here only to rotate the token. * **Members**: Who can sign in to control and their role. See [Access](/company/access). * **API keys**: Keys that reach everything your company owns. Admins only. See [Access](/company/access). * **Avatars**: Pick a style for your workers' avatars from a gallery and press **Save avatar style**. It applies to every worker at once; photos you uploaded yourself are kept. * **Email**: Your workers' sending domain: its status, the sending address shape (worker\@yourdomain), the DNS records Ergoly publishes for it, and **Re-check now**. The domain is claimed when your first worker is built; you do not set anything up. See [Email](/workers/channels/email). * **Tasks**: The **Archive period**: a task with no activity for this long is closed as archived, with a line on its log saying so. **After N days with no activity**, or **Never**. The default is 30 days. # Teams Source: https://docs.ergoly.ai/company/teams Three kinds of team: your own, a client, and a vendor. Each holds different things. A team on the chart is one of three kinds, and the kind decides what can sit inside it. * **Team**: A team of your own. Holds people, workers, open roles, and other teams. Created from **Add → Team** with a name and a colour. * **Client**: A company you work for. Nothing is placed inside it; the cards in its box are the people you have linked to that client. Created from **Add → Client**, from the Clients page, or by asking the AI Admin. * **Vendor**: An outside company that works for you. Holds people only. Created from **Add → Vendor** with a name, a website (its logo comes from there), what they do, and who it reports to. ## What a client's box does Adding a person to a client's box is how you tell Ergoly that this person belongs to that client. From then on, their direct messages with any worker serving that client go to that client's copy of the worker. The sheet says so: *Priya's DMs with Nora will go to Acme.* If no worker serves the client yet, you are asked to assign one first. See [Assigning a worker](/clients/assigning-a-worker). ## Archiving A team or vendor can be archived from its sheet, after a confirm. Its members go back to the tray. A client is not archived here; its own page handles that. > [!NOTE] > > **Worth knowing.** A team can be converted to a person when it has exactly one seat and nothing else, and a worker can be converted to a team. Both are on the card's sheet. # Core Concepts Source: https://docs.ergoly.ai/core-concepts # Company Your agency on Ergoly. The chart of who works here, people and workers alike. # Worker An AI member of your company with a role, responsibilities, and behaviors you set. # Client A customer of yours. Assign a worker, and that client gets its own copy. # Channel Where a worker operates: Slack channels and DMs, email, and the web. # Knowledge What a worker remembers and the skills it can run. # Work Tasks and routines, the tools a worker is connected to, approvals, and the pages it publishes. # Getting started Source: https://docs.ergoly.ai/getting-started From the invitation to your first worker answering in Slack. Ergoly takes on a few agencies at a time, and someone from Ergoly sets your company up with you. After that, your AI Admin takes over: a worker that lives in your Slack and builds the rest of your company from a conversation. 1. [Getting access](/getting-started/access): you accept an invitation to control and a shared Slack channel with the Ergoly team. 2. [Meet your AI Admin](/getting-started/ai-admin): you connect Slack, name your AI Admin, and install it. It messages you and sets up your first worker. 3. [Add a client and a channel](/getting-started/first-client): you tell the AI Admin who the client is and which channel is theirs. 4. [Your first correction](/getting-started/first-correction): you tell the worker what to do differently, once, and it keeps the rule. > [!NOTE] > > **Worth knowing.** Everything your AI Admin does, you can also do in control. The pages under Company, Workers and Clients show both. The AI Admin asks before it changes anything, so nothing happens without your yes. # Getting access Source: https://docs.ergoly.ai/getting-started/access Onboarding with the Ergoly team: an invitation to control and a shared channel in Slack. When Ergoly takes your agency on, someone on the team creates your company and sends two invitations. ## The invitation to control You get an email inviting you to control, the web app at control.ergoly.ai. Accept it and sign up. You are the company's first **admin**, which means you can invite other people, create API keys, and set up the AI Admin. The people you invite are **members**: they can use everything in control except those three things. ## The shared Slack channel You also get a Slack Connect invitation to a private channel shared between your workspace and Ergoly's. It is where you ask the Ergoly team for help. Ergoly's own support worker, Wicket, is in that channel too, and answers there. ## What happens next The first time you open control, it takes you straight to setup, because your company has no workers yet. That is the [AI Admin](/getting-started/ai-admin) step. # Meet your AI Admin Source: https://docs.ergoly.ai/getting-started/ai-admin Connect Slack, name it, install it. It messages you and sets up your company and your first worker from there. Your **AI Admin** is a worker that only works inside your company. It never joins a client's channel. Its job is to set things up: workers, channels, clients, and the tools they use. ## Setup, in control Setup has four steps. 1. **Connect Slack.** Ergoly needs permission to create Slack apps in your workspace. On api.slack.com/apps, open **App Configuration Tokens**, press **Generate Token**, and paste the token that starts with `xoxe-` into the **Refresh token** field. 2. **Name your AI Admin.** Type a name (the example is Ada). Leave **Full Slack permissions** on unless you have a reason not to; it lets the AI Admin invite workers to channels and create channels for you. 3. **Install it.** Press **Add \ to Slack** and click **Allow** in the Slack window that opens. Control shows *Starting \ up…* while the worker is built. 4. **Done.** Control shows *\ is looking around your workspace*, then *\ has messaged you in Slack*. ## Then, in Slack Open the direct message from your AI Admin. It introduces itself and asks what the first worker should do. Answer in plain words. It proposes a name, a job, and the channels, and asks for your yes before creating anything. Your agency Channels Workers Ada The AI Admin proposes, you approve. The install link needs a workspace admin. > [!NOTE] > > **Worth knowing.** Only an admin can create the AI Admin, because it holds a key to your whole company. A member who opens setup sees *An admin sets up your AI Admin*. If your company already has workers, the link to add one is above the Company page's List tab. > [card] [Access](/company/access) > > Admins, members, the AI Admin, and API keys. > [card] [Workers](/workers) > > What the AI Admin just created, and how to change it. # Add a client and a channel Source: https://docs.ergoly.ai/getting-started/first-client Tell the AI Admin who the client is, and which Slack channel is theirs. From then on, the worker answers there as your agency. A worker on its own works for your team. To put it in front of a client, you need a **client** in Ergoly and a Slack channel that belongs to that client. The AI Admin does both from a message. Your agency Channels Workers Ada ## What just happened Three things. A client called Acme now exists. Nora has a separate copy for Acme, with Acme's memory and nothing else. And #acme is mapped to Acme, so a message there always reaches that copy. ## Or invite the worker yourself You can also invite a worker to a channel in Slack, the way you would invite a person. It asks you, and only you, what the channel is for. See [When a worker joins a channel](/workers/channels/slack). > [!NOTE] > > **Worth knowing.** Start with an internal channel for the client, where your team reviews the worker's drafts, before inviting it into the channel the client is in. See [Internal client channels](/clients/internal-channels). > [card] [Clients](/clients) > > Adding, assigning, and what stays separate. > [card] [Client channels](/workers/channels/slack/client-channels) > > How a channel is mapped, and how to change it. # Your first correction Source: https://docs.ergoly.ai/getting-started/first-correction Say what you want done differently, once. The worker writes it down and files it with the right client, the right worker, or the whole company. A worker learns the way a new hire does: by being told. You do not configure it. You correct it in the thread where the work happened, and it keeps the rule. Your agency Channels Workers # acme-internal The rule is filed with Acme, because it is about Acme. Globex is unchanged. ## Where the rule goes When a worker learns something, it asks itself who the thing is true for. A client's preference is filed with that client. A better way of doing the job is filed with the worker, so every client benefits. A rule for the whole agency is filed with the company. If it is not sure, it files narrower, and tells you where it put it. ## Checking what it kept Everything a worker remembers is a file you can read. Open the worker in control, choose the **Knowledge** tab, and pick the client from the context picker at the top. The note is there, in plain Markdown, and you can edit it. See [Memory](/workers/knowledge/memory). > [!NOTE] > > **Worth knowing.** A correction about how the worker behaves in general, rather than a fact about a client, belongs in its behaviors. The worker proposes the exact line and adds it only after your explicit yes. See [Behaviors](/workers/behaviors). # Glossary Source: https://docs.ergoly.ai/glossary Every term you'll meet while working with Ergoly's workers: what it is, what you use it for, and why it matters. They are the same words control and the rest of the docs use. > [!NOTE] > > **A note on “client.”** In Ergoly, a client is always *your* client: a company your agency works for. Your own agency is your **company**. ## The basics ### Company *Also called organization.* **What it is.** Your agency on Ergoly. Your workers, clients, connections and everything your workers learn belong to it, and nothing in it reaches across to another company. **Use it for.** Holding what is true for your whole agency: your house style, the tools every worker may use, and who on your team can sign in. **Why it matters.** Your know-how stays yours. What your workers learn is not pooled with other customers and does not train a shared model. Read more: [Company](/company) ### Worker *Also called AI teammate.* **What it is.** An AI member of your company that works inside your Slack. Each worker is its own Slack app with a name, an avatar, a job title and an email address, so you invite it, @-mention it and DM it the way you would a colleague. **Use it for.** Recurring, well-defined work: status notes, research, first drafts, reports, data clean-up, and client questions answered from what your team already knows. One worker can serve many clients. **Why it matters.** Your team hands off the work that eats their hours and spends that time on judgment, relationships and new business. Your agency takes on more clients with the people it already has. Read more: [Workers](/workers) ### AI Admin **What it is.** A worker that works only for your own team and never joins a client's channel. It is the first worker you set up. **Use it for.** Setting things up from a conversation in Slack: creating workers, adding clients, mapping channels and connecting tools. It proposes each change and waits for your yes. **Why it matters.** Most of the setup happens in plain words, in the place your team already works. Read more: [Meet your AI Admin](/getting-started/ai-admin) ### Control **What it is.** Ergoly's web app, where your team sees and manages everything: the Company chart, Clients, Workers, Tasks, Artifacts, Connections and Activity. **Use it for.** Checking and changing your setup, reading and editing what a worker knows, connecting tools, and reviewing what happened. **Why it matters.** Everything a worker does or knows is visible and editable in one place. Almost all of it can also be done by asking in Slack. Read more: [Getting started](/getting-started) ## Clients and channels ### Client **What it is.** A company your agency works for: a name, a website and a logo, plus the Slack channels and people that belong to it. In Ergoly, a client is always *your* client. **Use it for.** Add each client a worker should help with, then assign a worker to it. **Why it matters.** Workers always know which client they are working for, so one client's details never show up in another client's work. Read more: [Clients](/clients) ### A client's copy *Also called sealed room.* **What it is.** When you assign a worker to a client, that client gets its own copy of the worker, with that client's memory, connections and contacts and nothing of any other client's. Your team talks to its own copy, which knows every client. **Use it for.** Nothing to manage. A copy is created when you assign a worker, and you still see one worker. **Why it matters.** You can put one worker in front of many clients with confidence. Which copy answers is decided by a fixed rule, which channel and which person, before the worker reads a word, so nothing typed in a channel can change it. Read more: [Client separation](/clients/separation) ### Client channel **What it is.** A Slack channel mapped to one client, usually a Slack Connect channel you share with them. **Use it for.** Once the worker's drafts are right, the client talks to it directly here. It answers as your agency, from that client's world and nothing else. **Why it matters.** Clients get fast, informed answers in the place they already talk to you, and the chore leaves your team's plate. > [!NOTE] > > **Good to know.** Only a workspace admin can add a worker to a channel. A client contact cannot. Read more: [Client channels](/workers/channels/slack/client-channels) ### Internal channel **What it is.** One of your team's own channels. The worker that answers there is your team's copy, which knows every client. **Use it for.** Asking about any account from one place: *what's open for Acme?*, *draft Globex's renewal note*. **Why it matters.** Your people get answers across every client without switching rooms. > [!NOTE] > > **Good to know.** The channel decides who is answered, so keep client contacts out of internal channels. Read more: [Internal channels](/workers/channels/slack/internal-channels) ### Internal client channel *Also called backstage.* **What it is.** An internal channel where your team reviews a worker's drafts for one client before the worker is in front of that client. **Use it for.** Teaching the worker about the client and checking its drafts. When they are consistently right, invite the worker into the client's channel. **Why it matters.** You decide, client by client, when a worker is ready to face a client. Nothing reaches the client until someone on your team sends it. Read more: [Internal client channels](/clients/internal-channels) ### Client contact **What it is.** A person on your client's side who is linked to that client in Ergoly. **Use it for.** Link the people a client has in Slack so that their direct messages and group DMs with a worker reach that client's copy. **Why it matters.** Each person is answered as part of the client they belong to. Someone outside your workspace who is linked to no client is told, politely, that the worker cannot help. Read more: [DMs](/workers/channels/slack/dms) ### Company chart **What it is.** An org chart of your agency with people and workers side by side, plus open roles, your teams, and the clients and vendors you work with. **Use it for.** Placing workers the way you place people: in a team, with a title, reporting to someone. **Why it matters.** When a worker needs a person, it goes to the nearest person above it on the chart. > [!NOTE] > > **Good to know.** The chart is a picture, not a permission. Placing a worker in a team does not change what it can see. Read more: [Chart](/company/chart) ### Vendor **What it is.** An outside company that works for you, such as your accountant or a partner agency, shown on the Company chart with its people. **Use it for.** Adding the partners your team works with to the chart. **Why it matters.** Workers can tell your team, your clients and your suppliers apart. Read more: [Teams](/company/teams) ## Working with workers ### Mention **What it is.** Addressing a worker with `@name` in a channel or a thread, the way you would address a colleague. **Use it for.** Asking for work, giving feedback, or pulling a worker into a conversation. In a channel, a worker always replies in a thread. **Why it matters.** By default, a mention or a direct message is how a worker knows a message is meant for it. Read more: [Slack](/workers/channels/slack) ### Response policy **What it is.** The two settings that decide when a worker speaks in a channel. **Replies**: only when @-mentioned, or to anything it judges is for it. **Listens when not addressed**: off, or on, which lets it read the channel without replying. Direct messages are always answered. **Use it for.** Matching each worker to each room: answering everything in one client's channel and only mentions in another. Set it for the whole company, one worker, one client or one copy; the narrowest setting wins. You can also ask a worker in the channel to go quiet. **Why it matters.** Workers help when it is useful and stay out of side conversations. With nothing set, a worker replies only when mentioned. Read more: [Response policy](/workers/response-policy) ### Approval **What it is.** A worker asking before it acts, with **Approve** and **Reject** buttons in the thread. **Use it for.** Tell it in plain words, such as *ask me before sending anything to a client*. It also asks on its own before anything hard to undo: money, a first send to a client, deleting things, terms, or a change to who has access. **Why it matters.** Your team keeps the final say on anything with consequences, and the thread records who decided and when. Read more: [Approvals](/work/approvals) ### Escalation assignee **What it is.** The person a worker takes a question to when it needs a human. By default, the nearest person above it on the Company chart. **Use it for.** Choose someone else on the worker's Settings tab when the chart does not say who should answer. **Why it matters.** Questions reach the right person instead of stalling. Read more: [Reporting](/workers/reporting) ### Triage **What it is.** The tab on a worker's page in control that shows whether it is awake, what it has been saying, and a **Restart Worker** button. **Use it for.** When a worker is slow, silent or stuck: first send `stop` in the thread, then use Restart Worker. If it stays silent in a channel, check its response policy and whether the channel is set up. **Why it matters.** Most problems are fixed in a minute, by anyone on your team. > [!NOTE] > > **Good to know.** A sleeping worker is normal. It sleeps after a few quiet minutes and wakes on the next message, so the first reply after a pause can take a few seconds longer. Read more: [Triaging](/workers/triaging) ## Teaching workers ### Role **What it is.** A worker's job title and what the job is for: *Account Manager*, *SEO Analyst*, *Bookkeeper*. **Use it for.** Deciding how many workers you need. If two jobs would be done by two different people at your agency, judged by different standards, make two workers. **Why it matters.** A worker with a clear title asks fewer questions and does its job more consistently. Read more: [Role](/workers/role) ### Responsibilities **What it is.** The list of what a worker is trained for and accountable for. Think of it as its job description. **Use it for.** Defining the job. A draft is written for you when you create the worker; edit it any time. A request outside the list is flagged as outside its job. **Why it matters.** Everyone knows what each worker is for. A worker never changes its own list: it proposes a change and records who agreed and when. Read more: [Responsibilities](/workers/responsibilities) ### Behaviors **What it is.** The rules a worker follows in every conversation, written as four kinds of line: **Avoid**, **Don't**, **Prefer** and **Use**. **Use it for.** Setting *how* the work is done, for example *Don't send anything to a client's mailing list without approval*. **Why it matters.** Consistent conduct with every client. A saved line is in force from the worker's next turn, and changes need a person's yes. Read more: [Behaviors](/workers/behaviors) ### Memory *Also called knowledge.* **What it is.** What a worker remembers, kept as plain files in folders that decide who a note applies to: **Private** (the worker's own notes), **Client** (one client), **Worker** (this worker, for every client), **Company** (every worker) and **Platform** (Ergoly's defaults, read-only). **Use it for.** Telling a worker something once. It files the note where it belongs, and your team can read, edit or add files on the worker's Knowledge tab. **Why it matters.** Nobody explains the same thing twice. When two notes disagree, the more specific one wins, so a client's preference beats your agency's default. Read more: [Memory](/workers/knowledge/memory) ### Correction **What it is.** Telling a worker, in the thread where the work happened, what was wrong and how you want it. **Use it for.** Any time a draft misses: *board one-pagers for Acme should fit on one screen*. **Why it matters.** The worker fixes the work, writes the rule down in the same turn and tells you where it filed it. A lesson about the job reaches every client; a fact about one client stays with that client. Read more: [Memory](/workers/knowledge/memory) ### Skill **What it is.** A saved way of doing a piece of work: a name, a line on when it applies, and the steps, in one file. **Use it for.** Capturing a process your agency repeats, like the weekly status note. Write one in any editor, hand a worker one you already use with Claude Code, or let it write its own after doing a job twice. A skill can belong to one client, one worker or the whole company. **Why it matters.** The job is done the same way every time. A client can have its own version of a skill without anyone changing the shared one. Read more: [Skills](/workers/knowledge/skills) ## Tools and access ### Connection *Also called connector, integration.* **What it is.** An app your workers can use: a CRM you signed in to, an API you pasted a key for, or a tool server at a URL. **Use it for.** Press **Add Connection** in control and pick from a catalog of more than 1,500 apps, or let a worker post a sign-in link in Slack. Apps outside the catalog can be added by their tool server or API address. **Why it matters.** Workers do the work in your real tools instead of asking someone to copy and paste. You can reconnect or remove a connection at any time. Read more: [Connections](/work/connections) ### Placement **What it is.** Who may use a connection: **one worker for one client** (the default), **one client**, **one worker**, or the **whole company**. When the same app is connected twice, the narrowest match wins. **Use it for.** Placing each client's own accounts with that client, and the tools everyone uses with the whole company. **Why it matters.** A connection placed with one client is never used for another client's work. > [!NOTE] > > **Good to know.** A whole-company connection reaches every worker for every client, so place client accounts with the client. Read more: [Placement](/work/connections/placement) ### Vault *Also called key vault.* **What it is.** Where Ergoly keeps your passwords and API keys. When a worker calls an app, a gateway adds the credential to the request on the way out; the worker never holds it. **Use it for.** Nothing to do. A key you paste, even in a Slack thread, goes straight into the vault and is never shown again. **Why it matters.** Workers read messages from people outside your agency. A worker that held a key could be talked into repeating it; a worker that never has one cannot. Read more: [Credential safety](/work/connections/credential-safety) ## Getting work done ### Task **What it is.** A piece of work with a **requester** (who asked), a **holder** (who is doing it) and a **log** of every handoff and result. Workers and people can be either. **Use it for.** Handing work to a worker or a person and saying where the result should go. A worker opens one itself when a job cannot be finished in one go or belongs to someone else. **Why it matters.** Work does not fall through the cracks, and every handoff and result is on record. Read more: [Tasks](/work/tasks) ### Routine *Also called scheduled task.* **What it is.** A task that repeats on a schedule: every weekday at 9, the first of the month, every hour. **Use it for.** Ask in plain words, saying when and where the results go: *every weekday at 9 Pacific, post Acme's status note here*. One routine can run for several clients, each on that client's copy and posting to that client's channel. Pause or cancel it by asking. **Why it matters.** Recurring work happens on time without anyone having to remember it. Read more: [Routines](/work/routines) ### Artifact **What it is.** A web page a worker publishes with its own link: a report, a dashboard, a one-pager. **Use it for.** Asking for anything you would rather pass around as a link. Ask for changes and the new version appears at the same link. New artifacts are **private** to people in your company; make one **public** to share it with a client. **Why it matters.** Clients get polished work they can open, print and forward, not a long message in Slack. Read more: [Artifacts](/work/artifacts) ### Email **What it is.** Every worker has its own email address, such as `nora@youragency.ergoly-mail.com`, and can send from it. A client's copy has its own address. **Use it for.** Asking a worker to email someone, with attachments, or to reply in an existing thread. Receiving email is coming soon. **Why it matters.** Work reaches the clients who live in their inbox, sent under the worker's name. Read more: [Email](/workers/channels/email) ### Activity **What it is.** The record of everything that happens across your company: what was done, by whom, and when. Entries can never be edited or deleted. **Use it for.** Checking what happened. Filter by area or by who acted; *system* means your workers and your API keys. **Why it matters.** Nothing a worker does happens out of sight. Read more: [Approvals](/work/approvals) ## For technical teams ### API key **What it is.** A key that reaches everything your company owns, read and write, through Ergoly's API. Admins create keys in control, under **Settings**, and each key is shown only once. **Use it for.** Connecting Ergoly to the systems you already run, or letting a coding agent such as Claude Code create workers, add clients and schedule routines for you. **Why it matters.** Anything you can do in control, a key can do from code. Everything a key changes is recorded under the key's name, and revoking it takes effect from the next request. Read more: [The API](/technical/api) ### Hook **What it is.** A web address that belongs to one worker. When another system posts to it, the worker works on what arrived and posts the answer in a channel or DM you chose. **Use it for.** Starting a worker from a form submission, a new support ticket or a finished deploy. Hooks are created through the API today. **Why it matters.** Any system that can send a web request can hand work to a worker. Read more: [Web](/workers/channels/web) ## The same words in the API The docs use the words control shows you. The API uses the names its records carry, and engineers at Ergoly use a few more. Side by side, for anyone at your agency who works with the [API](/technical/api). | Docs | API | Internal | Meaning | | - | - | - | - | | Company | organization | org | Your agency on Ergoly. Owns everything. | | Worker | Worker | Worker | One Slack app, one name, one job. | | A worker's copy | ework | posting, ework | One running copy of a worker: for one client, or for your team. | | Your team's copy | core ework | core | The copy that serves your internal channels and holds every client's memory. | | A client's copy | client ework | client-bound ework | The copy for one client, holding only that client's memory. | | Client | Client | Client | A customer of yours. | | Channel | channel | channel mapping, room | A Slack channel, mapped to a client or marked internal; also email and the web. | | Event | — | turn trigger, dispatch | Something that happens in a channel and starts work. | | — | — | turn | One message handled by one copy, with one reply. | | — | — | front desk, routing | The fixed rule that sends a message to one copy. | | Knowledge | memory | tiers | Memory and skills, as files in five tiers. | | Company, worker, client knowledge | org, worker, client | tenant tiers | The tiers your company owns. | | Platform knowledge | — | system tier | Ergoly's own tier, read-only, lowest precedence. | | Skill | skill | skill | A directory with a SKILL.md, in a tier. | | Task | task | task | Work with a requester, a holder, and a log. | | Routine | scheduled job | scheduled task, cron | A task whose start repeats. | | Connection | connection | vault connection | A credential or connected app, and its placement. | | Placement | placement | placement, scope | Who may use a connection: company, worker, client, or worker for one client. | | — | — | egress gateway | The proxy that puts a secret into an outbound request by hostname. | | AI Admin | — | AI Admin | Your internal-only worker that sets the company up from Slack. | | Behaviors | behaviors | behaviors | The Avoid, Don't, Prefer, and Use lines a worker follows. | | Responsibilities | responsibilities | responsibilities | What a worker is trained for and accountable for. | | Activity | activity | activity log | The append-only record of every write. | | Artifact | — | artifact | A web page a worker publishes. | # Ergoly Source: https://docs.ergoly.ai/index AI Workers you own, separated per client, inside the Slack your agency already uses. Ergoly gives your agency **workers**: AI members of your Slack workspace, each with a name, a job, and memory of its own. You teach a worker how your agency does a piece of work. It does that work for your clients, in their channels, under your name. Every client you assign a worker to gets a separate copy of that worker. The worker for Client A knows nothing about Client B. What a worker learns about the job travels to every client; what it learns about a client stays with that client. ## Where to start > [card] [Core concepts](/core-concepts) > > What to know before getting started. > [card] [Getting started](/getting-started) > > From the invite to your first worker in Slack. > [card] [Workers](/workers) > > Identity, role, responsibilities, behaviors, and where they work. > [card] [Clients](/clients) > > Adding one, assigning a worker, and what stays separate. The pages use the words control uses. If you are writing code against the API or want to know what sits behind a word, see [Technical details](/technical). ## For agents Every page here is also served as Markdown, from the same source: add `.md` to a page's address, or use the **View as Markdown** link at the top of any page. The index is at [/llms.txt](https://docs.ergoly.ai/llms.txt) and the whole set in one file at [/llms-full.txt](https://docs.ergoly.ai/llms-full.txt). Point Claude Code or any agent at the index and it can read these docs the way you do. # Technical details Source: https://docs.ergoly.ai/technical What happens behind the words in these docs, for the engineer at your agency or anyone on the API. The rest of the docs use the words control shows you: Company, Worker, Client, Channel, Knowledge, Task. This section explains what each one is underneath, and gives the name the API uses for it. You do not need any of this to run Ergoly. You need it if you are writing code against the API, or if you want to know exactly where something lives. > [card] [How a worker runs](/technical/how-a-worker-runs) > > Turns, eworks, and why each client gets its own copy. > [card] [Where knowledge lives](/technical/where-knowledge-lives) > > The five tiers, and why the narrowest one wins. > [card] [How a channel reaches a worker](/technical/how-a-channel-reaches-a-worker) > > Channel mappings, routing, and dispatch. > [card] [How credentials are held](/technical/how-credentials-are-held) > > The vault and the egress gateway. > [card] [The API](/technical/api) > > Keys, the reference, and your first call. # The API Source: https://docs.ergoly.ai/technical/api One key per company, one header, one envelope. The reference is served by the API itself. Anything you can click in control, a key can do from a terminal or from a coding agent: create workers, add clients, map channels, schedule routines, connect tools, read the activity feed. Every call is scoped to the company the key belongs to, and there is no parameter that widens it. ## Access and keys Keys belong to the company, not to a person. Anyone holding one acts as the whole company, and every write it makes is recorded under the key's own id. Only an admin can mint or revoke a key, in control under **Settings**, on the **API keys** tab. A key is shown once. Give it an expiry if the job it does has an end; revoking takes effect from the next request. A worker can hold a key too. Your AI Admin does, placed at its own tier and injected by the gateway, which is what lets it set up your company from Slack. See [Access](/company/access). ## Calling a worker from the web A **webhook** is a URL an outside system can POST to. Each one belongs to a worker and names a Slack channel or a person; a delivery starts a turn, and the answer lands there. Creating one returns a `whsec_` secret, shown once and stored hashed; send it as a Bearer token on every delivery. Lose it and you rotate. Deliveries are accepted with a 202 and a delivery id, and the turn runs afterwards. See [Web](/workers/channels/web). ## The reference The reference is served by the API, to the same key the API takes, so a coding agent can fetch how to call it with the header it already has. It comes back as Markdown by default, JSON when asked for, and HTML in a browser, all from one source. The same contract, with a playground for every operation, is in the [API reference](/api-reference/introduction) section of these docs. | What | Where | | - | - | | The overview, the one page that answers without a key | `https://control.ergoly.ai/api/v1` | | The reference index, one entry per resource | `https://control.ergoly.ai/api/v1/docs` | | One resource page | `https://control.ergoly.ai/api/v1/docs/{resource}` | | The whole contract as OpenAPI 3.1 | `https://control.ergoly.ai/api/v1/openapi.json` | ```text "Your first call: which company does this key belong to?" theme={null} export ERGOLY_API_KEY="" curl -sS "https://control.ergoly.ai/api/v1/organization" \ -H "Authorization: Bearer $ERGOLY_API_KEY" ``` ## The shape of every answer * A single resource answers `{"data": …}`. A list answers `{"data": […], "page": …}`, and `page` is there even when there is nothing more. * Paging is by cursor: pass `limit` and the previous page's `nextCursor`. A page stays stable while rows are written underneath it. * An id that belongs to another company answers 404, the same 404 an id that never existed gets. * A write that can create real infrastructure takes an `Idempotency-Key`. A retry is answered from the first attempt; the same key with a different body is a conflict. * Every refusal carries a machine-stable `code`. Branch on it, never on the message. Without a valid key every refusal reads alike, on purpose. ## Resources | Resource | Docs word | What it covers | | - | - | - | | organization | Company | Which company the key belongs to. | | workers | Worker | The identities: one Slack app each. Responsibilities and behaviors come back on a single-worker read. | | eworks | A worker's copies | One per client plus your team's. Read-only. | | clients | Client | Create one; bind it to a worker. | | channels | Channel | The workspace's channel directory, and the mappings. | | tasks | Tasks and routines | Hand-offs, scheduled jobs, targets, run history. | | jobs | — | How a provisioning run is going: the other half of every 202. | | memory | Knowledge | Read and write the tiers a copy mounts. | | connections | Connection | Credentials and connected apps, and their placements. | | webhooks | Web | Inbound URLs that start a turn. | | activity | Activity | The append-only audit feed. | | usage | — | Cost, turn outcomes, and a per-day pulse over a window. | | errors | — | The closed set of refusal codes. | > [!NOTE] > > **If you use Python's urllib.** Send a `User-Agent` that does not begin with `Python-urllib`. The hosting platform's bot protection refuses that one string before the request reaches Ergoly, so a good key answers 401. Any other agent string works. # How a channel reaches a worker Source: https://docs.ergoly.ai/technical/how-a-channel-reaches-a-worker Every Slack message is routed to one copy of one worker by a fixed rule, before any model runs. A **channel** in the docs is any place a worker operates. For Slack, the thing underneath is a **channel mapping** (the API's `channels` resource): a record that says which client a Slack channel belongs to, or that it is one of your own. Routing is the code that reads those records. ![A message in a channel becomes an event, is routed to one copy of a worker, which takes a turn and answers back where the event came from.](https://mintcdn.com/ergoly/-drdYd6uXChmiNIn/images/diagrams/message-to-work.svg?fit=max\&auto=format\&n=-drdYd6uXChmiNIn\&q=85\&s=384cc939e33c763b3ed447391bfa4360) A message in a channel becomes an event, the event is routed to one copy of a worker, and that copy takes a turn. ## The rule, in order | Question | Answer | | - | - | | Is this Slack channel mapped to a client? | That client's copy of the worker. | | Is it a direct message from someone bound to a client? | Their client's copy. | | Is the sender one of your company's own people? | Your team's copy. | | Anyone else | One sentence saying it cannot help here, and no worker runs. | The questions are asked in that order, and the first yes decides. No model is consulted. Which client a turn is about is therefore fixed by which copy runs it, never by anything in the message. ## A mapping is a decision A channel is mapped to a client, or marked internal. Both are explicit records. A channel with no mapping at all routes nowhere, and is not treated as internal. Moving a channel that is already mapped to one client onto another has to be confirmed, so a re-point is always something you asked for twice. Direct messages are never mapped. A DM routes by who is in it, through that person's binding to a client. That is one route to the answer rather than two, so there is nothing to disagree. ## Dispatch Once the copy is chosen, the message is signed and sent to that copy's sandbox, which has its own key. The reply comes back as a stream of pieces (text, a progress step, a request to send a message) and is posted to Slack by the platform, never by the copy. A copy never holds a Slack token. A message that arrives while that copy is busy is queued and handled next. A run of messages from one sender is folded into one turn; messages from two senders are two turns. > [!NOTE] > > **Worth knowing.** Routines, webhooks, and a task's log changing start turns the same way: the platform decides which copy, then dispatches. A routine for Acme fires on Acme's copy, and a webhook aimed at an Acme channel is refused if that channel is ever re-mapped to someone else. # How a worker runs Source: https://docs.ergoly.ai/technical/how-a-worker-runs A worker is one identity. Each client it serves gets a separate running copy, and each message it handles is one turn. A **worker** (a *Worker* in the API) is one Slack app with one name. It does not run as one process. For each client you assign it to, Ergoly starts a separate copy with its own sandbox, its own memory, and its own set of files. The API calls each copy an **ework**; internally they are also called postings. ## One copy per client, plus one for you Say your worker Nora serves Acme and Globex. There are three copies of Nora: one for Acme, one for Globex, and one for your own team. The Acme copy has Acme's memory and nothing of Globex's. Your team's copy has every client's memory, which is why your own people can ask it about any account. | Copy | API name | Serves | Holds | | - | - | - | - | | Your team's | core ework | your internal channels and your own people's DMs | company memory, Nora's memory, and every client's memory | | Acme's | client ework | Acme's channel and Acme's people | company memory, Nora's memory, Acme's memory only | | Globex's | client ework | Globex's channel and Globex's people | company memory, Nora's memory, Globex's memory only | Which copy handles a message is decided before anything runs, from the channel and the sender. The copy for Acme can never be handed a Globex message, so there is no rule a persuasive message could talk it out of. That decision is described in [How a channel reaches a worker](/technical/how-a-channel-reaches-a-worker). ## Turns A **turn** is one round trip: a message arrives, one copy of the worker works on it, and one reply goes back. The message can come from Slack, from a scheduled routine, from a webhook, or from a task's log changing. A copy handles one turn at a time. A message that arrives while a turn is running waits and is handled next; a run of messages from the same person is folded into one turn. While a turn runs, Slack shows one message that fills in as steps complete. The worker writes Markdown and Ergoly converts it for Slack, so what it writes is what you read. ## Sleep and wake A copy that has been idle for a few minutes goes to sleep, and the next message wakes it in a few seconds. There is no setting for this and nothing to keep awake. A sleeping copy is healthy, and a copy that answers after a quiet hour is proof the platform is working. ## What a copy can do Every copy has the same five tools: read a file, write a file, edit a file, run a shell command, and act in Slack. Everything else a worker does, from calling an app to scheduling a routine, is a skill it runs through the shell. A copy also has an email address, a sandbox with a file system and the web, and whatever connections have been placed within its reach. > [!NOTE] > > **Worth knowing.** The API's `workers` resource is the identity. Its `eworks` resource lists the copies, read-only: a copy is created by assigning a client and removed by unassigning one, never directly. # How credentials are held Source: https://docs.ergoly.ai/technical/how-credentials-are-held A worker never holds a password or a key. A gateway puts the secret into the request on the way out. A **connection** in the docs is a credential your company holds and a record of who may use it. Underneath, the credential sits in a **vault** and is used by an **egress gateway**: a proxy every copy of every worker sends its outbound traffic through. ## The placeholder When a copy of a worker calls an API, it does not send the key. It sends the literal word `egress-managed` where the key would go. The gateway matches the request's hostname against the connections placed within that copy's reach, swaps the placeholder for the real secret, and forwards the request. The secret exists in the vault and on the wire to the vendor, and nowhere in between. ```text "A call from inside a worker's sandbox" theme={null} # What the worker sends. The gateway replaces the placeholder in place, # keeping whatever scheme surrounds it. curl -sS "https://api.example.com/v1/me" \ -H "Authorization: Bearer egress-managed" ``` ## Reach A connection is placed with the company, one worker, one client, or one worker for one client. The gateway resolves the narrowest placement that matches. Acme's accounts, placed with Acme, are injected only into Acme's copy; Globex's copy cannot see that they exist. A connection with no placement is inert. ![Which copies of which workers a connection reaches, by its placement.](https://mintcdn.com/ergoly/-drdYd6uXChmiNIn/images/diagrams/connection-placement.svg?fit=max\&auto=format\&n=-drdYd6uXChmiNIn\&q=85\&s=f1c67c24626a4aa97483ed83e2c97316) Four placements. The narrowest one that matches the copy and the hostname is the one the gateway uses. ## Nothing comes back out No API response ever contains a stored secret, on create, on read, or after a rotation. Reading one back in the clear is a browser-only act by a person on the Connections page, and it is recorded against their name. Connecting an account that needs a sign-in hands you a link to open; nothing exists until the consent finishes. ## Connected apps Apps from the catalog, and tool servers, work through a tool platform rather than the gateway: the account's token is held there, and a copy calls the app through control, which signs the call with the copy's own key. The same placement rules decide who may use it, and the copy still never sees the token. > [!NOTE] > > **Worth knowing.** The platform API key a worker uses to call Ergoly itself is held the same way. It is placed at one worker's tier and injected by hostname, which is why the API answers on its own host: a call to control's own address would bypass the gateway and arrive with no credential. # Where knowledge lives Source: https://docs.ergoly.ai/technical/where-knowledge-lives Memory and skills are files in five tiers, and when two tiers disagree the narrowest one wins. A worker's **knowledge**, its memory and its skills, is a set of Markdown files. The files are held in **tiers** (the API's word too). Four tiers belong to your company; one belongs to Ergoly. | Docs word | Tier | Belongs to | Who writes it | | - | - | - | - | | One copy's own notes | instance | one running copy of a worker | that copy | | Client knowledge | client | one client | that client's copy, your team's copy, you | | Worker knowledge | worker | one worker, across all its clients | any copy of that worker, you | | Company knowledge | org | your company | you, and your team's copies | | Platform knowledge | system | Ergoly | Ergoly only; read-only for everyone else | ![Five levels of knowledge, narrowest first. A note in a narrower level wins over the same note in a broader one.](https://mintcdn.com/ergoly/-drdYd6uXChmiNIn/images/diagrams/knowledge-levels.svg?fit=max\&auto=format\&n=-drdYd6uXChmiNIn\&q=85\&s=c7bb3296e5e27e36a375adac19d8398f) Five tiers. A copy of a worker reaches its own, its client's, its worker's, the company's, and the platform's. ## Narrowest wins When two tiers hold a file with the same name, the narrower tier's file is the one the worker reads. A note about decks in Acme's tier beats a note about decks in Nora's tier, which beats one in the company's, which beats Ergoly's. That is how one client, or one worker, can state an exception without anyone editing the shared text. The same rule covers skills. A skill of the same name in a narrower tier shadows the broader one. Ergoly's own skills sit at the bottom, so anything you write wins over anything we ship. ## What each copy reaches Acme's copy of Nora mounts four tiers: company, Nora, Acme, and its own. Your team's copy mounts company, Nora, its own, and **every** client's tier, so it can file a fact about Acme in Acme's tier. No copy ever sees another worker's tier, and a client's copy never sees another client's. ## The files Each tier has an `always/` folder, whose documents the worker reads in full at the start of every turn, in filename order. A worker's persona, its responsibilities and its behaviors are three such files in its worker tier. Each tier also has a `skills/` folder, where every skill is a directory with a `SKILL.md`. Everything else is indexed and read when the worker needs it. ## Every change is a commit Each tier is a private git repository that Ergoly creates and fronts. A change you make in control, through the API, or that a worker makes itself is a commit, and reaches every running copy that mounts that tier within about twelve seconds. Nothing restarts. You can see the history, revert a change, and write the files in any editor. > [!NOTE] > > **Worth knowing.** The `memory` resource in the API is addressed by ework, because which tiers exist depends on which copy you ask about. Read with no tier named and the answer lists the tiers that copy reaches. # Work Source: https://docs.ergoly.ai/work What a worker does between conversations: tasks and routines, the tools it is connected to, approvals, and the pages it publishes. Conversations are where a worker is asked. **Work** is what it carries: tasks handed to it and by it, routines that run on a schedule, the connections it uses, the approvals it waits for, and the artifacts it publishes. In control these are the **Tasks**, **Artifacts**, **Connections** and **Activity** pages. > [card] [Tasks](/work/tasks) > > Handing work to a worker or a person, and where results go. > [card] [Routines](/work/routines) > > Tasks that repeat, and running one across clients. > [card] [Connections](/work/connections) > > Connecting a tool, and who may use it. > [card] [Approvals](/work/approvals) > > Asking first, the buttons, and the activity feed. > [card] [Artifacts](/work/artifacts) > > Pages a worker publishes with a link. # Approvals Source: https://docs.ergoly.ai/work/approvals A worker asks before it acts when you tell it to, and on its own for anything hard to undo. The decision is recorded. The activity feed holds everything else. ## Asking for approval Tell the worker in plain words: *ask me before sending anything to a client*, *get approval before you change a price*, *confirm with Priya first*. To make the rule permanent, have it added to the worker's [behaviors](/workers/behaviors). A worker also asks on its own for anything with a big consequence that is hard to undo: money, a first send to a client, deleting things, terms, changing who has access. ## Approve and Reject in Slack The worker posts what it is about to do, with two buttons in the conversation's own words, usually **Approve** and **Reject**. Only the first press counts. The platform replaces the buttons with one line saying who pressed which and when, so the thread is its own record. If someone other than the person it asked presses, the worker asks that person to confirm in the thread. Your agency Channels Workers # globex-internal The buttons retire the moment they are used. ## The activity feed The **Activity** page is an append-only log of everything that happens across your company: who did it and when. Entries can never be edited or deleted. Columns: When, Actor, Kind, Summary. Filter by area, or by who did it, where *system* means your workers and your API keys. Every change made with a key is here under the key's name, which is why revoking a key never erases what it did. > [!NOTE] > > **Worth knowing.** Escalation is different from approval. An approval goes to whoever the worker was told to ask, in the thread. An escalation is a question that needs a person, and goes to the worker's escalation assignee. See [Reporting](/workers/reporting). # Artifacts Source: https://docs.ergoly.ai/work/artifacts A web page a worker publishes with a link: a report, a dashboard, a one-pager. Private to your company by default, or open to anyone with the link. ## Creating one Ask the worker for anything you would rather pass around as a link: a report, a dashboard, a chart, a comparison, a one-pager, a calculator. It builds a self-contained page, publishes it, and replies with the link and whether it is private or public. Ask for changes and a new version appears at the same link. Your agency Channels Workers # acme-internal ## Publishing and locations Every artifact has a **Location**: your company, or one client. The location decides which workers can find and read it: all of them, or only that client's. A new artifact's location follows the worker that made it. Any signed-in member of your company can open every artifact, whatever its location. The **Artifacts** page lists them all, with filters for author, location and sharing. ## Privacy and sharing On the artifact's page, the **Sharing** popover offers **Private** (people in your company) or **Public** (anyone with the link, no sign-in). New artifacts are private. There is no delete: setting an artifact back to private is how you take it down. > [!NOTE] > > **Worth knowing.** A page can hold a lot: up to 4.5 MB, with charts and tables. It cannot hold live data, forms, or anything that stores what a reader types. > [card] [Collaboration](/work/artifacts/collaboration) > > Coming soon. # Collaboration Source: https://docs.ergoly.ai/work/artifacts/collaboration Commenting on an artifact, and the worker picking the comments up. > [!WARNING] > > **Coming soon.** Today, ask the worker for the change in Slack and it publishes a new version at the same link. When collaboration ships, you and a client will comment on a published page, and the worker will read the thread and publish the next version. Until then, the conversation about an artifact happens in Slack. # Connections Source: https://docs.ergoly.ai/work/connections The apps, keys and tool servers your company has connected, and who may use each one. A **connection** is an app your workers can use: a CRM you signed in to, an API you pasted a key for, a tool server at a URL. Every connection is **placed**: with the whole company, one worker, one client, or one worker for one client. Placement is the whole of who may use it. The **Connections** page lists them by category, with a status and an **Actions** menu (Open, Rename, Reconnect, Remove) on each. > [card] [Connecting a tool](/work/connections/connecting-a-tool) > > Sign in, paste a key, or give a server's address. > [card] [Placement](/work/connections/placement) > > Company, worker, client, or worker for one client. > [card] [Keys and tools](/work/connections/keys-and-tools) > > What a key connection is, and what a worker does with it. > [card] [Custom tools](/work/connections/custom-tools) > > A tool server by URL, or any API by its base URL. > [card] [Credential safety](/work/connections/credential-safety) > > Why your worker never holds a password. # Connecting a tool Source: https://docs.ergoly.ai/work/connections/connecting-a-tool Press Add Connection, pick the app, choose who may use it, and sign in or paste a key. 1. On **Connections**, press **Add Connection**. 2. **Pick the app.** Search the catalog of more than 1,500 apps, or browse by category. Under the results, two other ways in: **A tool server** by URL, or **An API key for another app** by its base URL. See [Custom tools](/work/connections/custom-tools). 3. **Access.** Choose who may use it. The narrowest option is the default. See [Placement](/work/connections/placement). 4. **Name** it, and add a **Description** in your own words. Workers read the description to decide when to use it. 5. **How to connect.** **Sign in** opens the app's own sign-in in a new tab; every worker placed here then acts as the account you sign in with. **Use a key** takes a key, checks it once, and keeps it out of every worker's reach. **No sign-in** is for tools that need none. 6. Press **Connect** and finish in the other tab. The person who signs in does not need an Ergoly account. ## From Slack A worker can ask for a connection within its own reach, posting a sign-in link that lasts a few minutes or taking a key pasted in the thread. A workspace admin can also DM a worker `connect `, such as `connect hubspot`, and get a link. Your AI Admin can connect an app for any worker and place it anywhere. See [Connections, under Workers](/workers/connections). ## Later A connection's status is **Active**, **Waiting for sign-in**, **Expired**, **Failed** or **Revoked**. **Reconnect** on the card offers **Finish sign-in**, **Sign in again**, or **Replace key** as the status calls for. **Send reconnect links** at the top DMs each person who owns a pending sign-in with their links. **Remove** confirms on the card. > [!NOTE] > > **Worth knowing.** If you would rather the sign-in screen show your agency's name than Ergoly's, add your own OAuth app under the **Legacy** tab, **Your OAuth apps**, with its client ID, secret, and the redirect URI control gives you to register. # Credential safety Source: https://docs.ergoly.ai/work/connections/credential-safety A worker never holds a password or a key. The credential is added to the request on the way out, by a part of Ergoly the worker cannot reach. When a worker uses a connected app, it never sees the key or the token. It makes the call, and a gateway between the worker and the internet matches the request against the connections placed within that worker's reach, adds the credential, and sends it on. The credential exists in Ergoly's vault and on the wire to the vendor, and nowhere in between. * No screen in control, and no answer from the API, ever shows a stored key. **Reconnect** replaces it; nothing reveals it. * A sign-in that needs consent needs a person. The worker posts a link to open; nothing exists until the consent finishes. * A key pasted in Slack goes into the vault and is never repeated in the thread. * A connection placed with Acme is never added to a request from Globex's copy, because the gateway checks placement before it adds anything. Why it is built this way: a worker is a program that reads messages from people outside your agency. If it held a key, a clever message could ask it to repeat the key. It cannot repeat what it does not have. > [card] [How credentials are held](/technical/how-credentials-are-held) > > The vault and the gateway, in detail. # Custom tools Source: https://docs.ergoly.ai/work/connections/custom-tools Any tool server by its URL, or any API by its base URL, when the catalog does not list the app. The catalog covers most apps. For anything else, **Add Connection** offers two other ways in, under the search results. * **A tool server**: Paste an `https://` URL. The server says how it signs in: a hosted sign-in, a key, or nothing. Once connected, Ergoly reads the tools it offers, and your workers get them as actions, the same as a catalog app. * **An API key for another app**: Paste the API's **base URL**, your key, and the **header the key is sent in**. Workers can then call any endpoint on that API. Add a link to its docs and workers read them to learn the endpoints. Both are placed like any other connection, and both keep the credential out of every worker's reach. > [!NOTE] > > **Worth knowing.** Give the API's documented base URL, not its website. A key is attached to the hostname you give, and a request that gets redirected to a different host leaves the key behind. # Keys and tools Source: https://docs.ergoly.ai/work/connections/keys-and-tools What happens when you paste a key, and what a worker can then do with the app. Some apps are connected by signing in. Others take an **API key** you paste. Either way the result is the same to a worker: an app it can use by name. ## A pasted key Choose **Use a key** when connecting. The key is checked once, with one read that succeeds with the key and fails without it, so a wrong key is refused on the spot. A key that passes is stored and never shown again, not to you and not to any worker. A worker that needs it calls the app, and Ergoly supplies the key on the way out. ## What a worker does with an app A connected app gives a worker a set of actions: read a deal, create a page, search a folder. Each turn, the worker is shown the connections that reach it, with your description of each. It picks the one that fits, calls it by name, and reports what it did. Two connections of the same app at the same placement are both offered, and the worker says which one it used. Your agency Channels Workers # acme ## When a key stops working If the app refuses the key, the connection's status becomes **Expired** and the worker tells whoever asked that the app needs reconnecting. **Reconnect** on the Connections page takes a new key or a fresh sign-in. > [!NOTE] > > **Worth knowing.** A key pasted into a Slack thread goes straight into the vault and is never echoed back. Still, prefer pasting keys in control when you can. # Placement Source: https://docs.ergoly.ai/work/connections/placement Who may use a connection: the whole company, one worker, one client, or one worker for one client. The narrowest match wins. Every connection is placed somewhere, and the placement alone decides which copies of which workers can use it. There is no other switch. | Placement | Who can use it | | - | - | | One worker for one client | Only that worker, and only when it is working for that client. The default. | | One client | Every worker, when it is working for that client. | | One worker | That worker, for every client and for the company. | | Whole company | Every worker, everywhere. | ![Which copies of which workers a connection reaches, by its placement.](https://mintcdn.com/ergoly/-drdYd6uXChmiNIn/images/diagrams/connection-placement.svg?fit=max\&auto=format\&n=-drdYd6uXChmiNIn\&q=85\&s=f1c67c24626a4aa97483ed83e2c97316) Acme's HubSpot, placed with Acme, reaches Nora for Acme and nobody else. The company's Google Drive reaches every copy of every worker. ## Narrowest wins When the same app is connected at two placements, a copy uses the narrowest one that matches it. Acme's own HubSpot, placed with Acme, beats the company-wide HubSpot for Acme's copy of Nora. Globex's copy, with no HubSpot of its own, uses the company's. ## Changing a placement Open the connection and change its access. Before you add, move or remove a placement, control shows who **Gains it**, who **Loses it**, and who **Keeps it**. A connection must keep at least one placement; to take it away from everyone, remove the connection. On a card, placement reads *Everyone (Company)*, *Nora (Worker)*, *Acme (Client)*, or *Nora for Acme*. A client's page lists the connections that reach that client, marking the ones inherited from the company. > [!NOTE] > > **Worth knowing.** A client's accounts belong with that client. Place them with the client, not the company, and no other client's copy can ever reach them. See [Client separation](/clients/separation). # Routines Source: https://docs.ergoly.ai/work/routines A task that repeats. Describe it once, say where results go, and point it at every client it should run for. A **routine** is a task with a schedule. Every weekday at 9, the first of the month, every hour. It runs on the worker you name, posts where you said, and keeps a run history. In control, routines live on the **Tasks** page under **Scheduled**. ## From Slack Your agency Channels Workers # acme-internal The worker repeats the schedule, the time zone, and where results go. Without a destination it will not schedule. Say when, and say where results go. If you leave out the time zone the worker asks; if you leave out the destination it refuses, because a routine that posts nowhere is a routine nobody sees. Asking for the same routine again replaces it rather than making a second one. ## From control Press **New task** on the Tasks page: the **Worker**, a **Title**, the **Prompt** (what the worker should do, written so it makes sense on its own), **Scope** (Internal or a client), a **Schedule** (**Once** or **Recurring**: every few minutes, hourly, daily, weekly, monthly, or a cron expression), a **Timezone**, and an optional **Slack channel**. Leave the channel blank and the result stays on the run log. ## Running across clients One routine can run for several clients, each on that client's own copy of the worker, each posting to that client's channel. On the task's page, the **Clients** card has **Add a client**; each client can have its own channel and time zone, and can be ticked on or off. From Slack, ask your team's copy: *run it for Acme and Globex*. A client's copy cannot fan out; it only knows one client. ## Pausing and cancelling * *Pause the Monday report* pauses it. The schedule is kept; on resume it runs from now without catching up. * *We don't want it any more* cancels it for good. * In control: **Disable** / **Enable** or **Delete** on the row's Actions menu, and **Run now** to run it immediately. ## Run history Every run is listed on the task's page and on each client's Tasks tab, with started, finished, duration, worker, client, where it posted, and any error. Filter by worker, client, or status. > [!NOTE] > > **Worth knowing.** The routine's prompt is read by the worker's future self with no conversation around it. Write it the way you would brief someone on their first day: what, for whom, where it goes. # Tasks Source: https://docs.ergoly.ai/work/tasks A piece of work with someone who asked and someone doing it. Hand it to a worker or a person, follow it on its log, and say where the result goes. A **task** has a **requester** (who asked), a **holder** (who is doing it), and a **log** (every handoff, comment, state change and run). Workers and people can be either. Handing a task to another worker is the only way one worker asks another for something. ## From Slack Ask in plain words. Work the worker cannot finish in one go, or work that belongs to someone else, becomes a task. It names the holder, and from then on the task's log is where the work is tracked. Your agency Channels Workers # acme-internal A person's comment on a task wakes the worker. The worker's own comments wake nobody. ## The Tasks page Three tabs, each with a count: **Scheduled**, **In progress**, **Closed**. Columns: Task, Runs on (the worker), Requester, Holder, Due (marked *Late* when past), Schedule. A task's own page shows its state, the people on it, where results go, its **Log**, and its **Run history**, with buttons for a person: **Start**, **Resolve**, **Hand off…**, **Decline**, and **Cancel task**. ## States and outcomes | State | Meaning | | - | - | | Scheduled | Not started yet: it has a schedule or a start time. | | In progress | Someone holds it. | | Closed · resolved | The requester is satisfied. | | Closed · declined | The holder said no. Only the holder can decline. | | Closed · cancelled | Withdrawn. | | Closed · archived | No activity for the company's archive period (30 days by default; Settings → Tasks). | ## Where results go A task names where its results go: a Slack channel the worker is in, a person (by DM), or nowhere, in which case the result stays on the log. A task scheduled from a DM sends its result back to that person. A task about a client can only be handed to a worker serving that client, or to a person. > [!NOTE] > > **Worth knowing.** The worker works a task by scoping it, planning and doing it, checking its own result, and resolving. After two attempts that still fall short, it hands the task to a person rather than trying a third time. # Workers Source: https://docs.ergoly.ai/workers An AI member of your company. It has a name, a job, responsibilities and behaviors you set, and a separate copy for each client it serves. A **worker** is one Slack app with one name. People address it the way they address a colleague: in a channel, by @-mention, or in a DM. It has a role, a list of responsibilities, a list of behaviors, memory of its own, and skills it can run. Everything about it is on its page in control, under **Workers**. One worker can serve many clients. For each client, it gets a separate copy with that client's memory and nothing of any other client's. Your own team talks to a copy that holds every client's memory. You never see the copies; you see one worker. ## The worker's page The header shows the avatar, the name, the role title, a status badge, and, once the worker serves clients, a context picker: **Internal** or one client. The picker decides which copy the Tasks, Knowledge, Connections and Triage tabs show.
Tab What it holds
Overview The four role cards: Responsibilities, Out of scope, Behaviors, When they conflict.
Clients The clients, channels and people this worker serves, and the Add to client button.
Tasks Scheduled tasks for the chosen context, with Run now, History, Edit, Disable.
Knowledge The memory browser for the chosen context, and the worker's tools.
Connections The apps that reach this worker in the chosen context.
Triage Whether it is awake, recent conversations, and Restart.
Settings Identity, runtime, response behavior, escalation, email, and the danger zone.
## Creating a worker Ask your AI Admin, or press **New Worker** on the Workers page. The wizard has five steps: **Identity** (name, job title, who it reports to, and a drafted responsibilities list), **Clients**, **Slack & channels** (an Add to Slack window; click Allow), **Tools**, and **Launch**, which ends with *Say hello to \*: send it a message to prove it works. > [card] [Identity](/workers/identity) > > Name, avatar, Slack app, email address. > [card] [Role](/workers/role) > > The job title and what it is for. > [card] [Responsibilities](/workers/responsibilities) > > What it is accountable for, and what is out of scope. > [card] [Behaviors](/workers/behaviors) > > Avoid, Don't, Prefer, Use. > [card] [Channels](/workers/channels) > > Where it works: Slack, email, the web. > [card] [Knowledge](/workers/knowledge) > > Memory and skills. # Access Source: https://docs.ergoly.ai/workers/access Who can talk to a worker, and which clients it serves. Set on the Clients tab. A worker's access is three lists: the **clients** it serves, the **channels** it answers in, and the **people** whose direct messages belong to a client. All three are on the worker's **Clients** tab, in one table with the caption *Where messages to this Worker go: a client, or your own team (internal)*. ## Who can talk to it
Person In a client's channel By direct message
Someone at your agency Answered by that client's copy Answered by your team's copy, which knows every client
A client's contact, linked to that client Answered by that client's copy Answered by that client's copy
A guest, or someone from another workspace not linked to a client Answered by that client's copy, in that client's channel only Told it cannot help: *I only work with people from the organization that set me up.*
## Adding a client Press **Add to client**. Pick the **Client**, then tick **Channels** and **People**. As the dialog says, *channels route by conversation, people route their DMs and group DMs*. A channel or person already linked to another client is greyed out: nothing is moved silently. See [Assigning a worker](/clients/assigning-a-worker). ## Channels Each channel row can be **Mark internal**, **Reassign** to another client, or removed. **Add channel** lists channels the worker can see that are not set up yet: public ones it can **Join**, private ones you invite it to first with `/invite`. Details under [Channels](/workers/channels). > [!NOTE] > > **Worth knowing.** A worker marked internal-only has no Add to client button. Its tab says: *This is an internal-only worker: it can never be put in front of a client. It works in DMs and internal channels only.* Your AI Admin is one. # Behaviors Source: https://docs.ergoly.ai/workers/behaviors What a worker follows day to day, as Avoid, Don't, Prefer and Use lines. Read every turn, changed only by agreement. A worker's **behaviors** are the rules it follows in every conversation. They are written as four kinds of line, and the file itself explains them: * **Avoid**: Not without a good reason. * **Don't**: There is never a good reason. * **Prefer**: Names the better option, and the one to watch for. * **Use**: A positive instruction. ```text "Four lines from a behaviors file" theme={null} - Don't send anything to a client's mailing list without approval. - Avoid scheduling calls before 10:00 in the client's time zone. - Prefer a one-screen summary over an attachment; watch for decks over ten slides. - Use the client's own product names, never ours. ``` ## Where they live On the **Overview** tab, the **Behaviors** card shows the list and the **When they conflict** card shows what the worker does when two rules collide. Both are one file in the worker's memory. Edit either card with the pencil, or edit the file in the Knowledge tab. ## Changing them from Slack Tell the worker how you want it to behave, in the thread. It proposes the exact line and adds it only after your explicit yes, then records who agreed and when. A rule you state once in a conversation about Acme is a fact about Acme and goes in Acme's memory instead; a rule about how the worker behaves everywhere goes here. Your agency Channels Workers # globex-internal A behavior applies everywhere the worker works. A client preference stays with the client. > [!NOTE] > > **Worth knowing.** The worker reads its behaviors at the start of every turn, so a saved line is in force immediately. There is no deploy. # Channels Source: https://docs.ergoly.ai/workers/channels Where a worker operates: Slack, email, and the web. And the events in those channels that make it act. A **channel** is anywhere a worker can be reached. Slack is where it lives: channels, direct messages, group messages. Email is a second address for the same worker. The web is for other systems: a URL they can post to, and the API. An **event** is something that happens in a channel: a message, a mention, a scheduled routine firing, a delivery to a webhook. Every event starts a worker working, and ends with an answer back where the event came from. See [Events](/workers/channels/events). > [card] [Slack](/workers/channels/slack) > > Internal channels, client channels, DMs, group DMs. > [card] [Email](/workers/channels/email) > > Sending now; receiving coming soon. > [card] [Web](/workers/channels/web) > > Hooks, triggers, and the API. > [card] [Events](/workers/channels/events) > > Everything that makes a worker act. # Email Source: https://docs.ergoly.ai/workers/channels/email Every worker has an email address and can send from it. Receiving is coming soon. Each worker has an email address under a sending domain Ergoly sets up for your company when your first worker is built. It looks like `nora@youragency.ergoly-mail.com`. A client's copy has its own, with the client's name in it, so mail about Acme comes from Acme's copy. Mail goes out under the worker's name. ## Sending Ask the worker to email someone and it does, with to, cc and bcc, attachments up to about 3 MB, and replies into an existing thread. It sends at most five emails a minute and to at most a hundred recipients at once. Every email it sent is listed on the worker's **Settings** tab under **Email**, with when, from, subject and status. Your agency Channels Workers # acme-internal ## Switching it off The same card has a kill switch: **Switch email off** stops the worker sending anything until you switch it back on. ## The domain Under **Settings → Email** for the company you can see the domain's status, the records Ergoly published for it, and **Re-check now**. You do not set anything up yourself. > [card] [Receiving email](/workers/channels/email/receiving) > > Coming soon. # Receiving email Source: https://docs.ergoly.ai/workers/channels/email/receiving A worker reading mail sent to its address, and acting on it. > [!WARNING] > > **Coming soon.** A reply to a worker's address is recorded today, but nothing reads it and nothing starts from it. When receiving ships, an email to a worker's address will be an event like a Slack message: the worker reads it, works on it, and replies by email, with the thread visible to your team. Until then, ask people to reach a worker in Slack. # Events Source: https://docs.ergoly.ai/workers/channels/events Everything that makes a worker act. Each one ends with an answer back where it came from. An **event** is something that happens in a channel. Every event starts the worker working on one thing, and when it is done, the answer goes back to where the event came from. These are all of them.
Event What starts Where the answer goes
A mention An @-mention in a channel the worker is set up in. A thread under the message.
A message A message with no mention, in a channel where the worker is set to answer everything. With listening on, it reads but does not reply. A thread, or nowhere.
A DM or group DM Any message, from someone it may talk to. The same DM.
A queued message A message sent while it was busy, handled once it is free. A thread under that message.
A button press Someone presses Approve, Reject, or another button the worker posted. The same thread, with the decision recorded.
A scheduled task A task fires on its schedule. The channel or person the task names; otherwise only the task's log.
A task change A task is handed to the worker, commented on by a person, or changes state. The task's log, and Slack if the task says so.
A hook delivery Another system posts to the worker's hook. The channel or DM the hook names.
Its first day A newly built worker sends its first DM to the person who created it. That DM.
Not events: an email arriving (receiving is not live), a trigger from a connected tool (not available yet), or someone opening control. > [!NOTE] > > **Worth knowing.** A worker works on one event at a time. A second event in the same place waits; events in different places, for different clients, run on different copies and do not wait for each other. # Slack Source: https://docs.ergoly.ai/workers/channels/slack Each worker is a member of your workspace. Every channel it is in belongs to one client or to your team, and that decides what it knows there. A worker is a named member of your Slack workspace: its own app, its own avatar, in the channels you invite it to. Four kinds of place, four pages: * **[Internal channels](/workers/channels/slack/internal-channels)**: Your team's own channels. The worker answers from everything it knows, every client included. * **[Client channels](/workers/channels/slack/client-channels)**: A channel that belongs to one client. The worker answers from that client's world and nothing else. * **[DMs](/workers/channels/slack/dms)**: A direct message. Who you are decides which copy answers. * **[Group DMs](/workers/channels/slack/group-dms)**: A message to the worker and a few people at once. ## When a worker joins a channel Invite a worker to a channel the way you invite a person. It stays only if a workspace admin invited it, and it asks the inviter, privately, what the channel is for, with a suggestion. Your agency Channels Workers # acme Only the person who invited it can answer. Anyone else is told so. If no client matches, it offers **New client…**, which creates the client and sets the channel up in one go. If only your team is in the channel, it suggests **Internal channel**. **Leave channel** backs out. ## Threads and progress In a channel, a worker always replies in a thread. While it works, its Slack status shows *is thinking…*. A message that arrives while it is busy gets a 👀 reaction and is handled next; several messages from the same person in a row are handled as one. # Client channels Source: https://docs.ergoly.ai/workers/channels/slack/client-channels A channel that belongs to one client. The worker answers there as your agency, from that client's world and nothing else. A **client channel** is mapped to one client. The copy of the worker that answers there has that client's memory, that client's connections, and the people linked to that client. It has never seen another client's channel, and nothing typed in the channel can change that. ## Mapping a channel to a client * When the worker joins and asks, press the suggested client, or **An existing client…**, or **New client…**. * On the worker's **Clients** tab, press **Add to client**, pick the client, and tick the channel. Or **Add channel**, then assign it by client slug. * On the client's own page, press **Bind a Worker** and tick the channel. * Ask your AI Admin: *#globex is Globex's channel*. ## Moving a channel A channel already mapped to one client is never taken over from the join buttons. To move it, use **Reassign** on the worker's Clients tab; control asks you to confirm, so a move is always something you asked for twice. ## Shared channels A client channel is usually a Slack Connect channel shared with the client's workspace. The worker answers the client's people there. It does not need them to be linked to the client for that; the channel decides. Linking matters for [DMs](/workers/channels/slack/dms). > [!NOTE] > > **Worth knowing.** Only a workspace admin can add a worker to a channel. A client contact who invites it gets *only workspace admins can add me to a new channel*, and the worker leaves. # DMs Source: https://docs.ergoly.ai/workers/channels/slack/dms A direct message is always answered. Who you are decides which copy of the worker answers. Anyone at your agency can DM a worker, and the copy that answers is your team's: it knows every client. A client's contact who is **linked to that client** also gets an answer, from that client's copy. Everyone else is told, politely, that the worker cannot help them. | Who sends the DM | Who answers | | - | - | | A member of your workspace | Your team's copy | | A person linked to Acme | Acme's copy | | A guest, or a Slack Connect contact linked to no client | Nobody. They see: *I'm not able to pick this up — I only work with people from the organization that set me up.* | ## Linking a person to a client Link a person from the worker's **Clients** tab (**Add to client**, then the **People** tab), from the client's page (**Bind a Worker**, People), or by adding them to the client's box on the [Company chart](/company/teams). The chart's sheet says what it does: *Daniel's DMs with Nora will go to Acme.* ## Threads in DMs In a DM, each message you send starts its own thread, and the worker replies in it. That keeps a long DM history readable: one topic, one thread. > [!NOTE] > > **Worth knowing.** A DM is never a channel. It cannot be mapped to a client; only the person can be linked. If a linked person's client copy is not live yet, their message is dropped and marked with ❌. # Group DMs Source: https://docs.ergoly.ai/workers/channels/slack/group-dms A message to the worker and a few people at once. The people in it decide which client it is about. A **group DM** is a direct message with the worker and two or more people. The worker answers in it, flat rather than in threads, and decides whose copy answers from who is present. | Who is in the group | Who answers | | - | - | | Only your own people | Your team's copy | | Your people and contacts linked to one client | That client's copy | | Contacts linked to two different clients | Nobody. The message is dropped, because no single copy could answer without mixing clients. | > [!NOTE] > > **Worth knowing.** A group DM with two clients' people in it is the one place a worker refuses outright rather than picking. Start two group DMs instead. # Internal channels Source: https://docs.ergoly.ai/workers/channels/slack/internal-channels Your team's own channels. The worker answers from everything it knows, including every client. An **internal channel** is one that belongs to your team rather than to a client. The copy of the worker that answers there holds every client's memory, so your own people can ask it about any account: *what's open for Acme*, *draft Globex's renewal note*. ## Marking a channel internal * When the worker joins and asks, press **Internal channel**. * On the worker's **Clients** tab, press **Mark internal** on a channel row, or use **Add channel** and choose Internal. * Ask your AI Admin: *make #ops an internal channel for Nora*. A channel with no setting at all is not internal. It is unassigned, and the worker tells anyone who mentions it there that it is not set up yet. ## Who is answered In an internal channel the worker answers your workspace's members. A guest in an internal channel is answered too, because the channel decides, so keep client contacts out of internal channels unless you mean them to be there. > [!NOTE] > > **Worth knowing.** The channel your team uses to review a worker's drafts for one client is a special case: it is internal, but the drafts are about one client. See [Internal client channels](/clients/internal-channels). # Web Source: https://docs.ergoly.ai/workers/channels/web Ways for other systems to reach a worker: a hook it listens on, triggers from connected tools, and the API. ## Hooks A **hook** is a URL that belongs to one worker. When another system posts to it, the worker takes what arrived and works on it, and the answer lands in a Slack channel or a person's DM that you named when you created the hook. A form submission, a new ticket, a deploy finishing: anything that can send a web request can start a worker. Each hook has a name, a destination (a channel the worker is in, or a person linked to it), and a threading choice: every delivery as a new message, each delivery in its own thread, or all deliveries in one thread. You can add an opening line and a template for how the payload is shown. Hooks are created through the API today; there is no screen for them in control yet. Creating one returns the URL and a secret that starts with `whsec_`, shown once. The caller sends the secret with every delivery. See [The API](/technical/api). ## Triggers A **trigger** is an event inside a connected tool, such as a new deal in your CRM, that starts a worker without a web request. See [Triggers](/workers/channels/web/triggers), coming soon. ## The API Everything you can do in control, a key can do from a terminal or a coding agent: create workers, add clients, map channels, schedule tasks, connect tools, read the activity feed. There is no API call that sends a worker a message directly; to start it from code, use a hook or a task. See [The API](/technical/api). > [!NOTE] > > **Worth knowing.** A hook on a client's copy of a worker can only post into that client's channels or DM that client's people. If the channel is later moved to another client, deliveries stop until the hook is re-pointed. # Triggers Source: https://docs.ergoly.ai/workers/channels/web/triggers An event inside a connected tool that starts a worker: a new deal, a new ticket, a changed row. > [!WARNING] > > **Coming soon.** Triggers are not available yet. A hook does the same job today for any system that can send a web request. When triggers ship, you will pick an event in a connected app, a worker, and where its answer goes, and the worker will act whenever the event happens, with no web request to set up. Until then, see [Web](/workers/channels/web) for hooks. # Connections Source: https://docs.ergoly.ai/workers/connections How a worker uses the tools it has been given. The tools themselves are set up under Work. A worker uses whatever **connections** reach it: apps your company has connected and placed with the company, with this worker, with a client, or with this worker for one client. The worker's **Connections** tab lists the apps that reach it in the chosen context, and nothing else. It never holds a password or a key. It calls the app by name, and Ergoly supplies the credential on the way out. Connect and place apps on the company's **Connections** page; the worker's tab is a view of the result. ## From Slack A worker can also ask for a connection itself, within its own reach. For an app that signs in, it posts a link anyone in the conversation can open; for an app that takes a key, you paste the key in the thread and it goes straight to the vault, never echoed back. A client's copy can place a connection only with itself for that client, or with that client. Your agency Channels Workers # acme-internal > [card] [Connections, under Work](/work/connections) > > Connecting a tool, placement, keys, custom tools, credential safety. # Identity Source: https://docs.ergoly.ai/workers/identity A name, an avatar, a Slack app, and an email address. Change any of them from the worker's Settings tab. * **Name**: What people call it, in Slack and in control. On the Settings tab, under **Identity**, with **Role title** beside it. Press **Save**; the change reaches the worker on its next turn. * **Avatar**: Click the photo in the page header (**Change photo**). PNG, JPEG or WebP under 2 MB. The style of generated avatars is set for the whole company under Settings → Avatars. * **Slack app**: Each worker is its own Slack app and bot. Under **Connection & runtime**, **Set icon in Slack** pushes the avatar to the app so it matches in both places. The card also shows the Slack app ID, read-only. * **Email address**: Every worker has one, shown under Identity as a copy chip once it exists. It looks like `nora@youragency.ergoly-mail.com`; a client's copy has its own, with the client's name in it. See [Email](/workers/channels/email). > [!NOTE] > > **Worth knowing.** The name is also the worker's slug in URLs and in the API. Renaming changes what people see; the slug set when the worker was created stays. # Knowledge Source: https://docs.ergoly.ai/workers/knowledge What a worker knows: its memory and its skills. Both are files you can read and edit. A worker's **knowledge** is two things. **Memory** is what it remembers: facts about clients, preferences, how your agency likes things done. **Skills** are procedures it can run: a saved way of doing a piece of work. Both are plain files, kept in folders that decide who they apply to, and both are on the worker's **Knowledge** tab. ![Five levels of knowledge, narrowest first. A note in a narrower level wins over the same note in a broader one.](https://mintcdn.com/ergoly/-drdYd6uXChmiNIn/images/diagrams/knowledge-levels.svg?fit=max\&auto=format\&n=-drdYd6uXChmiNIn\&q=85\&s=c7bb3296e5e27e36a375adac19d8398f) Four levels your company owns, and the platform's underneath. A note in a narrower level wins over the same note in a broader one. > [card] [Memory](/workers/knowledge/memory) > > What it remembers, where a note lives, corrections, editing it yourself. > [card] [Skills](/workers/knowledge/skills) > > What one is, where it lives, writing one, workers writing their own. # Memory Source: https://docs.ergoly.ai/workers/knowledge/memory Your worker remembers what you tell it. A note about Acme stays with Acme; a rule for the whole agency applies everywhere. Your worker remembers what you tell it. A note about Acme stays with Acme. A note about how you like decks written stays with the worker, for every client. A rule for the whole agency applies everywhere. If two notes disagree, the more specific one wins. ## Where a note lives The **Knowledge** tab shows one file tree with a folder per level, narrowest first. The names use your own: for a worker called Nora serving Acme, the folders read *Nora @ Acme (Private)*, *Acme (Client)*, *Nora (Worker)*, *Your agency (Org)*, and *Platform*.
Folder Applies to Example
Private This worker, in this one context. Its own working notes.
Client Every worker serving this client. Acme reads status notes on their phone: keep them short.
Worker This worker, for every client. How Nora formats a meeting prep.
Org Every worker in your company. We never quote prices in a client channel.
Platform Every worker on Ergoly. How to file a note; how to use a connected tool.
## How the worker files a note When it learns something, the worker asks who it is true for: one client, this worker everywhere, or the whole company. It files there, and if it is unsure it files narrower. A client's copy can write only its own client's folder and its private one; your team's copy can write every client's, the worker's, and the company's. ## Corrections Correct the worker in the thread where the work happened. It fixes the work, writes the rule down in the same turn, and tells you where it put it. A correction about one client goes in that client's folder. A correction about the worker's conduct is proposed as a [behavior](/workers/behaviors) and added after your yes. ## Editing it yourself Everything except the Platform folder is yours to edit. In the memory browser: **New file** (a path such as `notes/pricing.md`, and the content), **Upload a file**, **Edit**, **Delete**. Pick the client in the context picker first to see that client's folder. A change reaches a running worker in about twelve seconds. * The `always/` folder in each level holds notes the worker reads in full at the start of every conversation. Keep it short: standing rules, not reference material. * The persona is not edited here; use the Identity card. Responsibilities and behaviors can be edited here or as cards on Overview, but not deleted. * Skills live in each level's `skills/` folder. See [Skills](/workers/knowledge/skills). > [!NOTE] > > **Worth knowing.** Memory is files, not a database, so you can read it, diff it, revert it, and write it in any editor. Pushing a file through the API is the same as editing it in control. See [Where knowledge lives](/technical/where-knowledge-lives). # Skills Source: https://docs.ergoly.ai/workers/knowledge/skills A saved way of doing a piece of work. Written by you in any editor, or by the worker when it has done something more than once. A **skill** is a procedure saved as a file: a name, a line on when it applies, and the steps. When a worker has reasoned its way through the same job twice, the right move is to write it down, and then it runs the steps next time instead of working them out again. ## What one looks like ```text "A SKILL.md" theme={null} --- name: weekly-status-note description: Write the weekly status note for a retainer client from the project tracker. Use on Monday mornings or when asked for a status. Stops short of sending it. --- 1. Pull every item that changed in the client's board since last Monday. 2. Group into done, in progress, blocked. Blocked first. 3. Keep it under 150 words. Lead with the blocked item that needs the client. 4. Post the draft in the client's internal channel and wait. ``` The same open format coding agents use for their own skills. The description matters most: it is what the worker reads to decide whether the skill applies. ## Where a skill lives A skill sits in the `skills/` folder of one memory level, and that decides who has it: one client, one worker, or the whole company. A skill of the same name in a narrower level shadows the broader one, so Acme can have its own way of doing status notes without anyone editing the shared skill. Your skills always beat Ergoly's. ## Writing one yourself 1. Write the SKILL.md in Claude Code, Cursor, or any editor. 2. Put it in the right level: the worker's Knowledge tab, **New file** or **Upload a file** under `skills//`, or push it through the API. 3. The worker has it on its next conversation. There is nothing to deploy. Already have skills written for Claude Code? Hand one to a worker in Slack and say *use this skill*. It rewrites it in its own words, maps the tools it needs to your connections, and offers a test run. For a whole set, ask your AI Admin to import them; it proposes which workers should own which. ## Workers writing their own Your agency Channels Workers # globex-internal The worker writes the skill, checks it, and says where it filed it. > [!NOTE] > > **Worth knowing.** Around thirty skills, a worker is getting broad. Around fifty, split it into two workers with two roles. See [Role](/workers/role). # Reporting Source: https://docs.ergoly.ai/workers/reporting Who a worker reports to on the chart, and who it takes a question to when it needs a person. ## Reports to A worker sits on the Company chart like a person. You choose who it reports to when you create it (**Reports to** in the wizard, with *Nobody — leave them off the chart* as an option), and you can move it later by dragging on the chart or from its card's **Move…**. See [Chart](/company/chart). ## Who it asks When a worker needs a person, it takes the question to its **escalation assignee**. By default that is worked out from the chart: the nearest person above the worker that it can message. If the chart names nobody, it is the person who created the worker. To pick someone else without changing the chart, open the worker's **Settings** tab, find **Escalation assignee**, and choose a person under **Set the assignee**. The card's *In force right now* line always says who it is and why: *set here*, *from the org chart*, or *its creator*. **Clear** goes back to the chart. > [!NOTE] > > **Worth knowing.** Escalation is for questions, not approvals. Approvals go to whoever the worker was told to ask, with buttons in the thread. See [Approvals](/work/approvals). # Response policy Source: https://docs.ergoly.ai/workers/response-policy When a worker speaks: only when @-mentioned, or to anything it judges is for it. And whether it listens when not addressed. Two settings decide when a worker answers in a channel. Both are on the worker's **Settings** tab, under **Response behavior**. * **Replies**: **Only when @mentioned**, or **To anything it judges is for it**. * **Listens when not addressed**: **Off — un-addressed messages never reach it**, or **On — it reads them but still cannot reply**. Listening lets a worker learn from a channel it does not answer in; its Slack status shows *Listening…* while it reads. With nothing set, a worker is quiet: it replies only when @-mentioned and sees nothing else. Direct messages are always answered. ## Set it per client The **Scope** picker lets you set a value for the whole company (labelled *Organization — every Worker*), for one worker everywhere it works, for one client, or for one copy. The narrowest value wins. So one worker can answer everything in Acme's channel and only mentions in Globex's. ## Or ask the worker People can ask the worker itself to go quiet or to answer everything, in the channel. A value you set in control overrides what it was asked. Your agency Channels Workers # acme > [!NOTE] > > **Worth knowing.** In a thread it already replied in, a worker still needs an @-mention, except while it is working there. Adding an @-mention to a message by editing it, within an hour, counts. # Responsibilities Source: https://docs.ergoly.ai/workers/responsibilities The list of what a worker is trained for and accountable for. Requests outside the list are outside its job. A worker's **responsibilities** are an enumerated list: the high-order things it is trained and proven capable of, and responsible for in its role. Once the list is saved, the worker treats a request that is not on it as outside its job, and says so. ## The cards On the worker's **Overview** tab, the first two cards are **Responsibilities** and **Out of scope**. Both come from one file in the worker's memory. A pencil icon opens an editor with **Write** and **Preview**; press **Save** and it reaches the worker on its next turn. If the worker edited the file while you had it open, control says so and offers **Reload**. ## Drafted for you When you create a worker, the wizard drafts a responsibilities list from the job title and your company chart. Edit it before you continue. If a worker's list is still empty, control can show a **Proposed responsibilities** card built from what the worker does today, with **Save as the list** and **Reject**. ## How the list changes You can edit it any time. The worker can also propose a change, in Slack, when it learns something about its job. It makes the change only after your explicit yes, and records a dated line under *Changes* in the file saying what changed and who agreed. Your agency Channels Workers # acme-internal > [!NOTE] > > **Worth knowing.** The AI Admin's responsibilities are kept by Ergoly and are not edited here. # Role Source: https://docs.ergoly.ai/workers/role The job title, and the one-line job it does. A worker is a role, not an automation. A worker's **role** is its job title and what the job is for: *Account Manager*, *SEO Analyst*, *Bookkeeper*. You set the title when you create the worker and can change it under Settings → Identity. The title is what people see under its name, and it is the first thing the worker reads about itself. ## One worker, one role The question of how many workers to run is a question about roles, not tasks. Divide by role: if two jobs would be done by two different people at your agency, judged by two different standards, make two workers. If one person would do both, make one worker and give it two skills. [Staff it, don't wire it](https://www.ergoly.ai/thoughts/staff-it-dont-wire-it) makes the full argument. ## Persona From the name, the title and the company, Ergoly writes the worker's persona: who it is, how it introduces itself, whose name it works under. The persona is rewritten whenever the worker is rebuilt, so it always matches what control says. The parts you own are the [responsibilities](/workers/responsibilities) and [behaviors](/workers/behaviors). > [!NOTE] > > **Worth knowing.** Give the title the way you would on a job posting. A worker with a vague title asks more questions than one with a clear one. # Triaging Source: https://docs.ergoly.ai/workers/triaging When a worker is slow, silent or stuck: what the Triage tab shows, and the three buttons that fix most things. The **Triage** tab answers two questions: is the worker awake, and what has it been saying. * **Runtime**: One row per context (Internal and each client): **awake** or **sleeping**, last activity, last wake, and recent time-to-first-reply. A sleeping worker is normal. It sleeps after a few idle minutes and wakes on the next message in seconds. * **Turns**: Recent conversations grouped by Slack thread. Click one to read it; **Load older turns** goes back further; a copy action gives you the thread as Markdown. ## The fixes, least invasive first 1. **Stop.** Send the word `stop` in the thread, or `@worker stop`. Only the person whose message started the work can stop it; anyone at your agency can stop a scheduled run. 2. **Restart Worker**, on the Triage tab. It does the least invasive thing that applies: clears a stuck reply, re-activates, or relaunches. It may interrupt a reply in progress. 3. **Unquarantine**, in the banner at the top of the page. Ergoly quarantines a worker after repeated failures and says why. Read the reason, then press the button. ## The danger zone At the bottom of **Settings**: **Stop** pauses the worker; **Restart** brings a stopped or failed one back; **Re-install / update scopes** re-runs the Slack install so new permissions take effect; **Delete Worker** removes the Slack app, every copy, and all its data, after you type its name. > [!NOTE] > > **Worth knowing.** If a worker is silent in a channel, check its [response policy](/workers/response-policy) and whether the channel is set up, before restarting anything. An un-set-up channel answers an @-mention with *I'm not set up for this channel yet*.