Skip to content

Account & teams

Account and team resources sit at the top of the object graph. Your account owns API keys and personal sites; teams own members, projects, sites, invites, an audit trail, and a plan. These resources are product-agnostic — they look the same whether your sites run WordPress, static, or wasm.

Your account is the principal behind a personal key.

account:read Retrieve the authenticated account — profile, plan, and the scopes the calling credential holds, for permission introspection.

Retrieve the current account
curl https://api.managed.dev/v1/account \
-H "Authorization: Bearer mfk_live_..."
Response
{
"data": {
"id": "client_01J5...",
"email": "dev@example.com",
"name": "Avery Dev",
"default_team_id": "team_01J6...",
"role": "client",
"plan": "developer",
"scopes": ["sites:read", "deployments:write", "jobs:read"] // an API key lists its explicit set; a human session reports ["*"]
},
"request_id": "req_01J9..."
}

account:write Update account fields. Returns 204 on success. Display and preference fields need no password; changing your email or password requires current_password.

Parameter Type Required Description
name string no Display name for the account.
default_team_id string no Must be a team you actively belong to (else 422).
billing_cc_email string no Extra recipient for billing email.
new_email string no New login email — requires current_password.
new_password string no New password — requires current_password.
current_password string with the two above Proves possession before a credential change.
Change the account email
curl -X PATCH https://api.managed.dev/v1/account \
-H "Authorization: Bearer mfk_live_..." \
-H "Content-Type: application/json" \
-d '{ "new_email": "avery@acme.dev", "current_password": "..." }'

A team is the unit of collaboration and billing. Roles are assigned per team, and sites can be grouped into team projects.

  • List (teams:read) the teams you belong to, cursor-paginated. Each team reports my_role — your role in it.
  • Create (teams:write) a team; you become its owner.
Parameter Type Required Description
name string yes Human-readable team name.
Create a team
curl -X POST https://api.managed.dev/v1/teams \
-H "Authorization: Bearer mfk_live_..." \
-H "Idempotency-Key: 9c2f...a1" \
-H "Content-Type: application/json" \
-d '{ "name": "Acme Web" }'
Response
{
"data": { "team_id": "team_01J6..." },
"request_id": "req_01J9..."
}

Retrieve (teams:read) or update (teams:write, owner/admin only) a team. Delete (teams:write) is owner-only and returns 204 — the team must be empty of sites first.

teams:read The team’s plan and live usage against its limits — sites, environments, and storage. Use this before a create call to avoid a quota_exceeded error.

Response (figures are examples)
{
"data": {
"plan": "developer",
"label": "Developer",
"limits": { "max_sites": 5, "max_environments": 15, "max_branches_per_site": 10, "max_concurrent_jobs": 4, "max_storage_gb": 25 },
"usage": { "sites": 3, "environments": 6, "storage_gb": 11.4 }
},
"request_id": "req_01J9..."
}

teams:read List the sites owned by the team — a convenience filter over the sites collection.

Members are added to a team with one of five roles. The role caps everything a member — and any key they mint — can do.

Role Can do
owner Everything, including deleting the team and managing billing.
admin Manage members, projects, and sites; cannot delete the team.
site_manager Operate sites and environments; no member or billing management.
observer Read-only access to sites, observability, and audit.
billing Plan, usage, and billing only; no site access.

GET · POST /v1/teams/{teamID}/members · PATCH · DELETE /v1/teams/{teamID}/members/{memberClientID}

Section titled “GET · POST /v1/teams/{teamID}/members · PATCH · DELETE /v1/teams/{teamID}/members/{memberClientID}”

teams:read to list; teams:write (owner/admin) to add, change a role or expiry, or remove a member. Mutations return 204. A role you assign can never outrank your own.

Parameter Type Required Description
client_id string add only Account id of the person to add.
role string yes One of owner, admin, site_manager, observer, billing.
expires_at string | null no RFC 3339 expiry for a time-boxed membership — a contractor who falls off the team automatically. On PATCH, a value sets it, null clears it, and omitting the key leaves it unchanged.
Add a contractor until the end of the quarter
curl -X POST https://api.managed.dev/v1/teams/team_01J6.../members \
-H "Authorization: Bearer mfk_live_..." \
-H "Content-Type: application/json" \
-d '{ "client_id": "client_01J5...", "role": "site_manager", "expires_at": "2026-09-30T23:59:59Z" }'

Invites are pending memberships for people who don’t have an account id yet.

  • GET /v1/teams/{teamID}/invitesteams:read list pending invites (owner/admin only).
  • POST /v1/teams/{teamID}/invitesteams:write create an invite: role (required), optional email and expires_at.
  • DELETE /v1/teams/{teamID}/invites/{inviteID}teams:write revoke a pending invite; 204.

Projects group sites. They come in two flavors with the same shape: personal projects under your account, and team projects under a team. See projects.

Endpoint Scope
GET · POST /v1/projects · GET · PATCH · DELETE /v1/projects/{projectID} sites:read / sites:write
GET · POST /v1/projects/{projectID}/sites · DELETE /v1/projects/{projectID}/sites/{siteID} sites:read / sites:write
GET · POST /v1/teams/{teamID}/projects · GET · PATCH · DELETE /v1/teams/{teamID}/projects/{projectID} teams:read / teams:write
GET · POST /v1/teams/{teamID}/projects/{projectID}/sites · DELETE …/sites/{siteID} teams:read / teams:write

Creating takes { "name": "..." }; assigning a site takes { "site_id": "site_01J7..." } (the site must belong to the same owner). Assign and remove return 204.

Group two client sites into a project
mf projects create --name "Client: Acme"
mf projects assign proj_01J6... site_01J7...

Three audit feeds share one event shape (the team feed adds a keyset before cursor):

Feed Endpoint Who can read
Account GET /v1/account/audit audit:read — every event you were the actor of.
Site GET /v1/sites/{siteID}/audit audit:read — events done to one site.
Team GET /v1/teams/{teamID}/audit audit:read — owner/admin only.
Parameter Type Required Description
event string no Filter to a single event type, e.g. snapshot_restore.
actor string no Filter to events performed by one principal.
since / until string no RFC 3339 window — since inclusive, until exclusive.
limit / cursor no Pagination.
Read your audit feed
curl "https://api.managed.dev/v1/account/audit?since=2026-06-17T00:00:00Z&limit=50" \
-H "Authorization: Bearer mfk_live_..."
Response
{
"data": [
{
"id": "aud_01J9...",
"event": "snapshot_restore",
"outcome": "success",
"actor_kind": "api_key",
"actor_user_id": "client_01J5...",
"actor_email": "dev@example.com",
"actor_key_id": "key_01J7...",
"team_id": "team_01J6...",
"site_id": "site_01J7...",
"meta": { "snapshot_id": "snap_01J8..." },
"created_at": "2026-06-24T13:58:10Z"
}
],
"pagination": { "next_cursor": "eyJ0...", "has_more": true },
"request_id": "req_01J9..."
}

actor_kind is member, api_key, or system; actor_user_id is the acting principal even when the actor was an API key, and outcome records whether the action succeeded. See the audit log concept page.