Skip to content
Takeida
Browse the reference

Account key · /v1/api

Administer an organization from your own code

An Account key acts for the person who made it, outside every Concept. It sets a workspace up: invites people, decides which Concepts they reach, creates agents and lends them standing, and brings a new Concept into existence.

It never reads or writes what is inside a Concept. A key that cannot see content cannot leak it. There is no document, draft or proposal on this surface, and no setting on the key that adds one.

The key itself

A client has the same first question an agent does: what am I, and what can I reach. Ask before doing anything else.

Ask who the key is

GET/v1/api/me

Who the caller is, and with ?org=, what it may do in that organization. The email is the owner's, because the owner is who answers for what the key does.

Query

orgstring
An organization's slug. Without it, organization and role are null and permissions is empty. Standing belongs to an organization, and there is none to report until one is named.

Refusals

  • 401unauthenticatedThe key is missing, revoked or expired, or is not an Account key. A key of another kind is refused here before anything else is looked at.
  • 404not_foundThe owner has no standing in the organization named.
Request
curl "https://your-server.example/v1/api/me?org=harbour-works" \
  -H "Authorization: Bearer arb_live_…"
Response200
{
  "principal": {
    "type": "API_KEY",
    "id": "2f6d0c1a-9b8e-4f7d-a6c5-b4a3928170fe",
    "name": "Onboarding script",
    "email": "dmitri@harbour.example"
  },
  "agent": null,
  "organization": {
    "id": "9a1b2c3d-4e5f-4a6b-8c7d-0e9f1a2b3c4d",
    "slug": "harbour-works",
    "name": "Harbour Works"
  },
  "role": "OWNER",
  "permissions": ["concept:create", "member:invite", "member:set_role", …]
}

List the Concepts its owner reaches

GET/v1/api/me/concepts

Every Concept the owner can reach, across every organization they belong to, with the role held in each. Names and addresses only. The key learns that a Concept exists and what it is called, and nothing of what it holds.

Belonging to an organization grants none of its Concepts. This is the ones an owner administers, plus the ones somebody granted.

What a row tells you

identifierstring
The Concept's address. The agent routes take it in their path.
role, viastring, string
What the owner may do there, and how they come to reach it.
status, purgeAfterstring, date-time
An archived or deleted Concept reaches this list only for its owner, and says so here.
Request
curl https://your-server.example/v1/api/me/concepts \
  -H "Authorization: Bearer arb_live_…"
Response200
[
  {
    "id": "3c2b1a09-8f7e-4d6c-b5a4-9e8d7c6b5a41",
    "slug": "coastal-atlas",
    "identifier": "k7m2xq9d",
    "name": "Coastal atlas",
    "description": "Survey notes for the northern harbours.",
    "owner": { "username": "dmitri", "displayName": "Dmitri Okafor" },
    "visibility": "PRIVATE",
    "adaptable": false,
    "adaptedFrom": null,
    "adaptationCount": 0,
    "exportCount": 4,
    "agentPolicy": "MEMBERS_ONLY",
    "followerCount": 0,
    "trunkBranch": "main",
    "createdAt": "2026-08-02T09:14:00.000Z",
    "organization": { "id": "…", "slug": "harbour-works", "name": "Harbour Works" },
    "role": "OWNER",
    "via": "owner",
    "status": "ACTIVE",
    "purgeAfter": null
  }
]

The organization

Every account owns one organization. It is made at sign-up and nothing deletes it. The key administers that one. It can also read the others its owner belongs to, which is why the reads below still take a slug and the changes on the next pages do not.

List organizations

GET/v1/api/o

The organizations the owner is a member of, oldest first. The first is usually their own.

What a row tells you

slugstring
What the reads below take as {org}.
allowExternalAgentsboolean
Whether members may work here through agents of their own.
Request
curl https://your-server.example/v1/api/o \
  -H "Authorization: Bearer arb_live_…"
Response200
[
  {
    "id": "9a1b2c3d-4e5f-4a6b-8c7d-0e9f1a2b3c4d",
    "slug": "harbour-works",
    "username": "harbour-works",
    "name": "Harbour Works",
    "description": "Coastal surveying.",
    "allowExternalAgents": false,
    "createdAt": "2026-08-02T09:13:51.000Z"
  }
]

Read an organization

GET/v1/api/o/{org}

One organization, from its slug. For a client that holds only a slug, from a link or an invitation, and needs the rest.

Refusals

  • 404not_foundNo such organization, or the owner is not in it. The two are not told apart, so this cannot be used to find out which slugs exist.
Request
curl https://your-server.example/v1/api/o/harbour-works \
  -H "Authorization: Bearer arb_live_…"
Response200
{
  "id": "9a1b2c3d-4e5f-4a6b-8c7d-0e9f1a2b3c4d",
  "slug": "harbour-works",
  "username": "harbour-works",
  "name": "Harbour Works",
  "description": "Coastal surveying.",
  "allowExternalAgents": false,
  "createdAt": "2026-08-02T09:13:51.000Z"
}

List the people in it

GET/v1/api/o/{org}/members

Everybody in the organization, in the order they joined. Somebody who has deleted their account is not listed.

What a row tells you

userIduuid
What the routes that change a member take.
roleOWNER · EDITOR · WRITER · READER
Their standing in the organization.
canUseAgentsboolean
Whether they may work through agents of their own here.
This list carries an email address beside every name. Treat what it returns accordingly.
Request
curl https://your-server.example/v1/api/o/harbour-works/members \
  -H "Authorization: Bearer arb_live_…"
Response200
[
  {
    "userId": "5e4d3c2b-1a09-4f8e-9d7c-6b5a4f3e2d1c",
    "email": "dmitri@harbour.example",
    "displayName": "Dmitri Okafor",
    "username": "dmitri",
    "avatar": "beaver",
    "role": "OWNER",
    "status": "ACTIVE",
    "canUseAgents": true,
    "joinedAt": "2026-08-02T09:13:51.000Z"
  },
  {
    "userId": "8b7a6f5e-4d3c-4b2a-9180-7f6e5d4c3b2a",
    "email": "ana@harbour.example",
    "displayName": "Ana Reyes",
    "username": "ana",
    "avatar": "otter",
    "role": "WRITER",
    "status": "ACTIVE",
    "canUseAgents": false,
    "joinedAt": "2026-08-19T14:02:10.000Z"
  }
]

List the agents in it

GET/v1/api/o/{org}/agents

The agents that are members here in their own right, each with the person who answers for it. People and agents are listed separately on purpose: they are different kinds of member, with different rules.

An agent a member merely works through is not in this list. It is not a member and holds nothing of its own.

Request
curl https://your-server.example/v1/api/o/harbour-works/agents \
  -H "Authorization: Bearer arb_live_…"
Response200
[
  {
    "organization": { "id": "…", "slug": "harbour-works", "name": "Harbour Works" },
    "agent": { "id": "c1d2e3f4-…", "slug": "scribe", "name": "Scribe", "status": "ACTIVE" },
    "owner": { "id": "5e4d3c2b-…", "displayName": "Dmitri Okafor" },
    "role": "WRITER",
    "status": "ACTIVE",
    "joinedAt": "2026-09-03T08:30:00.000Z"
  }
]

A new Concept

Creating a Concept is a name appearing in the organization's list, which is setup. Reading one is content. So a key may do the first and never the second.

Create a Concept

POST/v1/api/o/c

Makes an empty Concept in the owner's organization. Whether it is public, whether it may be adapted, and whose agents may work in it are three separate decisions. None follows from another, and each defaults to the closed answer.

Body

slugstring · 2 to 64 · required
Lowercase letters, digits and single hyphens. Unique within the organization.
namestring · 1 to 100 · required
What people see.
descriptionstring · up to 1,000
The one line that appears in a list.
aboutstring · up to 100,000
The page a reader lands on, in Markdown.
visibilityPRIVATE · PUBLIC
Private when absent.
publicRoleREADER · WRITER
What the public may do once it is published.
adaptableboolean
Whether others may take a copy to build on. Off when absent.
agentPolicyMEMBERS_ONLY · OPEN · NONE
Whose agents may work here. Members only when absent.
trunkBranchNamestring · 1 to 100
main when absent.
These three switches can be set here, once, as the Concept is made. Changing them afterwards is something only a person signed in may do. A request body on this surface may be at most 1 MB.

Refusals

  • 409conflictThe organization already has a Concept with that slug.
  • 400validation_failedA private Concept was asked to be open to outside agents, or the body named a field that is not listed. The address is drawn by the server and cannot be chosen.
Request
curl -X POST https://your-server.example/v1/api/o/c \
  -H "Authorization: Bearer arb_live_…" \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "tide-tables",
    "name": "Tide tables",
    "visibility": "PUBLIC",
    "adaptable": true
  }'
Response201
{
  "id": "7d6c5b4a-3f2e-4d1c-8b0a-9f8e7d6c5b4a",
  "slug": "tide-tables",
  "identifier": "p3n8vw2c",
  "name": "Tide tables",
  "description": null,
  "owner": { "username": "dmitri", "displayName": "Dmitri Okafor" },
  "visibility": "PUBLIC",
  "adaptable": true,
  "agentPolicy": "MEMBERS_ONLY",
  "trunkBranch": "main",
  "status": "ACTIVE",
  "documentCount": 0,
  "role": "OWNER",
  "createdAt": "2026-10-09T11:00:03.000Z",
  …
}

No organization in the address. The key acts in the one its owner owns.