Skip to main content

Teams

A team is a named group of workspace members — Payments, Platform, Identity — and the links people use to reach it: a contact e-mail, a chat channel, an on-call schedule and its documentation. Teams are the owners of projects, catalog items, MCP endpoints, consumers and connectors. A team is the only kind of group in a workspace.

Go to Workspace → Teams to see them. Teams are created and changed with the apiome teams command or the REST API.

Team pages​

Teams lists every team with its handle, how many members it has and its links. Click a team's name to open its page.

The Teams page: Payments and Platform, each with its handle, member count and contact, chat and on-call linksThe Teams page: Payments and Platform, each with its handle, member count and contact, chat and on-call links
Route/ade/dashboard/teams

A team's page shows, top to bottom:

  • Open findings for you — your unread owner findings for this team, the same ones your bell counts; click it to open your notifications. Owned, Suggested and Members count the rest, and the team's links sit beside them.
  • Members, leads first.
  • What it owns, grouped by kind — projects, catalog items, MCP servers, consumers and connectors — each with how it became the owner (Assigned, Gateway tag, CODEOWNERS, …).
  • Findings routed in the last 30 days, newest first, one row per finding however many members it reached.
The Payments team page: 3 open findings, its members with the lead marked, what it owns by kind, and two routed findingsThe Payments team page: 3 open findings, its members with the lead marked, what it owns by kind, and two routed findings
Route/ade/dashboard/teams/payments

What a team holds​

FieldWhat it is
slugThe team's handle, for example payments: lowercase letters, digits and hyphens. Made from the name when you leave it out. It cannot be changed — gateway tags such as owner:payments and the x-apiome-owner extension refer to it
nameWhat people read, for example Payments
descriptionWhat the team does (optional)
contact_emailA shared mailbox (optional)
chat_url, oncall_url, docs_urlLinks to the team's chat channel, on-call schedule and documentation (optional; each must start with http:// or https://)

Each slug is unique among the workspace's teams. Once a team is deleted, its slug is free to use again.

Members​

Each member is a lead or a member. Everyone on a team must already be a member of the workspace — invite them on Members & seats first.

Setting the members always sends the whole list: anyone left out is removed, and an empty list empties the team. If someone on the list is not in the workspace, nothing changes and the reply names them.

When someone leaves the workspace, they leave every team they were on at the same moment.

Delete a team​

Deleting a team removes it from every list, and its slug is free again. Its history stays in the access audit.

A team that is the confirmed owner of anything cannot simply be deleted: the request is refused with how many entities it owns. Name another team with reassign_to and those entities move to it as the team is deleted.

Ownership​

Every project, catalog item, MCP endpoint, consumer and connector can have an owner: a team. An owner is either:

  • Confirmed — the team responsible for the entity. Findings about the entity are routed to it. There is at most one.
  • Suggested — a team an importer found evidence for. Each suggestion shows where it came from, and nothing is ever sent to a suggested owner. There can be several.

A suggestion only becomes the owner when someone confirms it, and the access audit records who did.

Where suggestions come from​

SourceEvidenceBecomes a suggestion for
gateway_tagA Kong tag owner:payments, or an AWS API Gateway tag apiome:owner = payments (see Connectors)The catalog item the connector synced
codeownersA CODEOWNERS rule naming @your-org/payments for the spec's path — the file in .github/, the repository root or docs/, last matching rule winsThe project or catalog item imported from that path
spec_extensionx-apiome-owner: payments at the root of the document, or info.contact.name: paymentsThe project or catalog item the import wrote

Only team slugs count. A suggestion naming a team that does not exist is not stored. A connector says so in its run's findings — unknown team ghost in tag — so you can create the team or fix the tag. CODEOWNERS owners that are people (@alice) or e-mail addresses are not suggestions. Suggestions refresh on every sync, scan and import: when the tag, rule or extension goes away, so does the suggestion.

Confirm or assign an owner​

On Catalog, Projects, MCP servers, Published and a project's Consumers:

  • the Owner column (or, on cards, the line under the summary) shows each entity's owner, and a suggestion's Suggested badge says where it came from;
  • click “Confirm” next to a suggestion to make it the owner — the row updates without reloading;
  • Owner in the toolbar narrows the list to one team; the choice is kept in the address (?team=payments), so a filtered list can be shared;
  • on Catalog and Projects, tick rows and use Assign owner in the bar at the bottom of the page: choose a team and click “Assign owner” to make it the owner of every selected item.

From the command line, apiome teams assign <kind> <id> --team <slug> assigns one owner; an unknown team is refused with a non-zero exit. Over the API:

  • Confirm a suggestion: POST /v1/tenants/{tenant}/owners/{kind}/{id}/confirm, with {"team": "payments"} — or {} when only one team is suggested. The owner keeps its source and records who confirmed it.
  • Assign any team: PUT /v1/tenants/{tenant}/owners/{kind}/{id} with {"team": "platform"}.
  • Assign one team to many entities: POST /v1/tenants/{tenant}/owners:assign with {"team": "platform", "entities": [{"kind": "catalog_item", "id": "…"}]} (up to 200; all or nothing).
  • Remove the owner: DELETE /v1/tenants/{tenant}/owners/{kind}/{id}. Suggestions stay, and an owner that came from a suggestion becomes a suggestion again.
  • See an entity's owner and suggestions: GET /v1/tenants/{tenant}/owners/{kind}/{id}.

kind is project, catalog_item, mcp_endpoint, consumer or connector. Who may change an owner is whoever may edit the entity: projects:edit for projects, catalog items and MCP endpoints, consumer_contracts:edit for consumers and imports:edit for connectors. Reading needs the matching view. Every change is in the access audit as owner.assign, owner.confirm, owner.remove, owner.bulk_assign, or — when an importer changes the suggestions — owner.suggestions.

What an owner team hears about​

Lint regressions, breaking changes on refresh, verification drift, failing deploy gates, MCP trust drift, shadow APIs and failed connector syncs reach the confirmed owner team: a notification for each member and one message to the team's chat_url. See Notifications → Owner findings. Without a confirmed owner the finding goes to the Unowned findings report — and, when the workspace has a catch-all team (set in the tenant's Ownership settings), to that team as well; its notifications say they came because nobody owns the entity.

Ownership policy​

Two workspace settings, changed in the tenant's Ownership settings and shown read-only under the Teams list:

  • the catch-all team for findings on unowned entities;
  • Require an owner to publish — a version of a project with no confirmed owner is refused with reason no-owner (see Publish a version).

Ownership drift​

Under the Teams list, Ownership drift lists ownership that has quietly stopped working:

ReasonMeans
Owner team deletedThe confirmed owner is a deleted team, so findings reach nobody
Owner team has no membersThe owner team is empty, so its notifications reach nobody
Suggestion never confirmedA suggested owner nobody confirmed in 30 days, on an entity with no owner

Each row names the entity (linked to its page) and the team. Fix it by assigning another owner, adding members, or confirming the suggestion.

Ownership drift under the Teams list: one entity whose owner team was deleted, one whose team is empty, and two old suggestionsOwnership drift under the Teams list: one entity whose owner team was deleted, one whose team is empty, and two old suggestions
Route/ade/dashboard/teams

Ownership facts​

GET /v1/tenants/{tenant}/owners/{kind}/{id} returns two facts about the entity, the ones scorecard ladders read (all of an entity's facts are on Scorecards):

FactTrue when
owner.presentThe entity has a confirmed owner team that has not been deleted
owner.contactableThat team has an on-call link or a chat link

The catalog, project, MCP endpoint and consumer lists show each entity's owner as owner: {team, status, source}: the confirmed owner, or else its first suggestion with status: "suggested". See the Owners API reference.

Permissions​

Teams have their own row in the permission matrix, Teams (teams):

RoleTeams permissions
Owner, AdminView, create, edit (including members) and delete
Editor, ViewerView

A team decides who is told about — and paged for — what it owns, so changing teams is kept with the people who run the workspace. Give a custom role teams:edit to let it manage membership.

Every change is recorded in the workspace's access audit as team.create, team.update (each changed field, old and new), team.members.replace (who was added, removed or changed role) or team.delete.

With the API​

See the Teams API reference:

CallDoesNeeds
GET /v1/tenants/{tenant}/teamsEvery team, with its links and member countteams:view
POST /v1/tenants/{tenant}/teamsCreate a teamteams:create
GET /v1/tenants/{tenant}/teams/{slug}One team and its members, leads firstteams:view
PATCH /v1/tenants/{tenant}/teams/{slug}Change the name, description or links; null clears oneteams:edit
PUT /v1/tenants/{tenant}/teams/{slug}/membersReplace the members ([{"user_id", "role"}])teams:edit
GET / PUT /v1/tenants/{tenant}/ownership-policyRead or change the catch-all team and Require an owner to publishteams:view / teams:edit
GET /v1/tenants/{tenant}/ownership-driftThe Ownership drift reportteams:view
GET /v1/tenants/{tenant}/teams/{slug}/activityWhat it owns, your open findings for it, and the findings routed to it in the last 30 daysteams:view
DELETE /v1/tenants/{tenant}/teams/{slug}Delete; add ?reassign_to=<slug> when it owns entitiesteams:delete

For example, to create a team and make yourself its lead:

curl -X POST "$APIOME/v1/tenants/acme/teams" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name": "Payments", "chat_url": "https://chat.example.com/c/payments"}'

curl -X PUT "$APIOME/v1/tenants/acme/teams/payments/members" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"members": [{"user_id": "<your user id>", "role": "lead"}]}'

What a refusal means:

Statusdetail.codeWhy
400team-invalidA malformed slug, a blank name, a link that is not http(s), a bad e-mail, or a user listed twice
400team-reassign-invalidreassign_to names the team being deleted, or no team
404team-not-foundNo team has that slug
409team-slug-takenAnother team already has that slug
409team-owns-entitiesThe team owns entities; detail.owned_count says how many
422team-member-not-in-tenantSomeone on the list is not a workspace member

Where next​