Accounts and Members
Accounts are the top-level API boundary. Environments, VMs, tasks, users, invitations, secrets, snapshots, and logs all live under an account.
Most integrations start by discovering the account ID, then using account-scoped routes for the rest of their work.
Discover Accounts
curl -s "$WALLFACER_API/accounts" \
-H "Authorization: Bearer $WALLFACER_TOKEN" \
| jq ".data[] | {id, name}"Store the chosen account ID. It appears in most routes:
/v1/accounts/{account_id}/...Resolve Members
Account user routes are useful for automation that needs to map an external identity to a Wallfacer user. The most common case is resolving a GitHub username before creating a task on that user's behalf.
curl -s "$WALLFACER_API/accounts/$ACCOUNT_ID/users?github_username=$GITHUB_LOGIN" \
-H "Authorization: Bearer $WALLFACER_TOKEN" \
| jq ".data[0] // null"An empty data array means no active account member matched that GitHub username. Treat that as a skip, not as an API failure.
Agents
An agent is an AI identity in the account that runs work. Every task runs as an agent, and the commits, pull requests, and credentials that task uses resolve to it. The responsible human is recorded separately as the task owner.
Creating an agent is an admin operation. When you create one without naming an environment_id, Wallfacer provisions a computer for it, an account-editable environment named after the agent, and sets it as the agent's environment. The agent is runnable the moment it exists. The computer starts as a default Linux box with no repositories and begins generating its base snapshot right away; add repositories or services to it later and the snapshot regenerates.
A task defaults its environment_id from its agent. A task that names an agent and omits environment_id lands on that agent's computer without you naming the environment. See Tasks and Sessions for the create call.
Connect GitHub to an agent only when it will work on code in a GitHub repository. An agent whose computer has no repositories runs with no GitHub connected at all.
Standing State
Each agent carries objectives and todos under /v1/accounts/{account_id}/agents/{agent_user_id}.
objectivesis readable, creatable, editable, and closable by any account member. Closing is aPATCHcarrying bothstatus: "closed"and an outcome (done,dropped, orsuperseded) rather than a verb segment on the URL. The two are validated against each other: an outcome withoutstatus: "closed", orstatus: "closed"without an outcome, is a 422.todosis read-only and filters bystatus,ref, andobjective_id. There is no write endpoint by design: the agent writes its own todos as it commits to them.
See Agents for what the two are for.
Mail Policy
The agent's mail_policy is read on GET and replaced wholesale on PATCH of the agent. A partial policy is a 422. See Email an Agent for the fields and the defaults.
People
/v1/accounts/{account_id}/people is the account's directory: members, agents, and everybody your agents have met on a channel, each with the spellings that resolve to them.
GET /peopleandGET /people/{person_id}read the record.PATCH /people/{person_id}sets the preferred channel and the contact notes your agents read.POST /people/{person_id}/mergesfolds a duplicate into this person. Two rows that are both account members cannot be merged, and a member row can only be the survivor.
These routes are open to any account member. See Accounts for the app surface.
The Keychain
Credentials your agents use to sign into third-party services are account-owned and granted per agent.
| Goal | Route |
|---|---|
| List or store a credential | GET and POST /v1/accounts/{account_id}/credentials |
| Read, replace, or delete one | GET, PATCH, DELETE /v1/accounts/{account_id}/credentials/{credential_id} |
| See who holds it | GET /v1/accounts/{account_id}/credentials/{credential_id}/grants |
| Grant or revoke for one agent | PUT and DELETE /v1/accounts/{account_id}/credentials/{credential_id}/grants/{agent} |
| List what one agent holds | GET /v1/accounts/{account_id}/agents/{agent_user_id}/credentials |
No route returns a stored value. Responses carry the name, the reference the agent reaches it by, the kind, grant dates, and how the credential is audited. See The Account Keychain for what an agent does with one.
Roles
Account members have one of three roles:
| Role | Meaning |
|---|---|
owner | Full control, including ownership and other owners. |
admin | Can add, update, and remove members, but cannot grant or modify owner. |
member | Can use the account but cannot manage membership. |
Admin-level operations include attaching existing users, updating roles, removing users, and managing invitations. Owner-specific constraints still apply: only owners can remove owners, and the last owner cannot be removed.
Invitations
Invitations are for emails that do not yet belong to a Wallfacer user. When accepted, the invitee joins the account with the invited role.
There are two invitation flows:
- Account admins list and create invitations under
/v1/accounts/{account}/invitations. - Invitees use public token routes under
/v1/invitations/{token}to inspect and accept the invitation.
The public show-by-token route reveals enough metadata to identify the account and inviter, but the token itself is the secret. Do not log invitation URLs.
Task Ownership and Execution Identity
Every task has two distinct identities: the agent it runs as, and the human accountable for it.
- Execution identity (
created_by). The agent the task runs as. Every commit, pull request, and credential resolves to this agent. It is always an agent, never a person. On task creation,created_byis optional and must be an enabled agent of the account; omit it to use the account's connected agent (the default). - Owner (
owner_user_id). The human accountable for the task. When a person's token creates a task, that person becomes the owner. A task an agent opens on its own stays unowned and surfaces in a shared "needs someone" queue rather than routing to anyone.
{
"title": "Fix the assigned issue",
"prompt": "Resolve the attached ticket.",
"environment_id": "019d8e44-e110-71f6-864b-8e91470dcc4a"
}Task access is account-scoped, not restricted to the creator: any member of the account can list and read the account's tasks. Filter by execution identity with the created_by query parameter, or by responsible human with owner_user_id.
Environment Visibility
Environment visibility also affects account members:
privateenvironments are only visible and usable by their creator.account_readlets members use the environment but not edit it.account_editlets members use, edit, and delete it.
Use account_read for shared team environments that should be stable. Use account_edit only when account members should be able to change the manifest and regenerate snapshots.