Constitor Platform API
The one API every app uses: Constitor, Socius, Mercator, Battalion and Auxilium. No app has an API of its own. This page explains how it is built and how to connect, then lists every path in the OpenAPI document as served on 16 October 2026.
| Base path | /api/v1 on the live app |
| The document | GET /api/v1/openapi |
| Try it | GET /api/v1/docs, the interactive reference for the same document |
| Live host | https://app.constitor.ai/api/v1 |
| Sign-in | The Constitor login with Microsoft, Google or SSO; not a /v1 resource. One session for the whole suite. Machines use a service token. |
How the platform works
Constitor runs an agentic company on one rulebook. The handbook says what is allowed and who decides. Agents do the work inside those rules, in every app. A person says ok where the rules ask for it, and Constitor records a receipt. What the agents learn goes back to the handbook as a proposal, never straight in. All of it runs through this one API.
The suite
Every app has the same shape: the app rail, the agent panel as the second column, and the content. Every app reads and writes only through /api/v1.
| App | For | What you do there | API groups |
|---|---|---|---|
| Constitor | Everyone | Read the handbook, propose a change, approve it. People, roles and the audit trail. | handbook, organisations, members, roles, audit-events |
| Socius | Partners and sales | Customers and partners, companies and people, deals, projects, group travel, grants. | partner-tenants, directory, deals, projects, trips, calls, grant-proposals |
| Mercator | Marketing | A view of the shared posts list, publishing channels, profiles and flows. | posts, publishing/channels, ideal-customer-profiles, flows |
| Battalion | Whoever runs the agents | The agents, their mandates, runs, waits and receipts, lessons, teams and flows, models and budgets. | agents, mandates, ways-out, lessons, teams, flows, models, budgets, cost-stop |
| Auxilium | Customers and support | Feedback, tickets, the help center, status, roadmap and thank-you stickers. Its bot is Curator. | tickets, help/articles, status, incidents, roadmap, stickers |
| In every app | Everyone | The agent panel, and the shared Inbox, calendar, files, tasks, notifications and search. | conversations, calendar, files, tasks, notifications, search, audit-events |
Where things live
| In the handbook | In the platform database | In neither |
|---|---|---|
| Versioned in git, changed only by an approved proposal | Per organisation, row-level security, reached only through /v1 | Held by the runtime, given per action |
| Role cards: task, tools, risk level, what data an agent may see | Conversations and threads | Keys and secrets: an agent never sees them |
| Skills, standards and instincts | Runs, steps and their receipts | |
| The mandate per kind of action, by role | Who holds which role, and approval receipts | |
| Which model class and which tools are allowed | Records: customers, deals, tickets, posts … | |
| Flows, once a person said ok | Cost and quality figures |
Who signs in, and when
| Who | Signs in | How they prove who they are |
|---|---|---|
| A person in a customer organisation | Once, at the Constitor login | Microsoft, Google or the organisation's SSO; passkey, second factor or magic link where set. One session for every app; they switch organisation, not account. |
| A partner | Once, in their own partner organisation | Their own work account. They reach a customer only through the partner_tenants link and a consent grant that expires. |
| A new customer's first admin | After an email invite | Signs in, accepts the invite and receives the opening management grant. Later invites wait for board approval. |
| Platform staff | With the platform admin role | No standing access to an organisation's content. Any impersonation is written to the audit log. |
| An agent | Never | A short-lived token for one organisation, minted for each run. |
| An outside tool or script | Never | A service token for one organisation, with scopes. |
| An MCP client | Never | A service token today; sign-in through Microsoft (OAuth 2.1) is proposed. |
One way to approve
- The agent asks in the panel, with what it wants to do and why.
- The person says ok in the chat. There is no Approve button.
- Constitor checks the person's role, the channel and the handbook version.
- Constitor writes the receipt: "Recorded by Constitor, not by a bot." The run continues.
At any mandate level an agent never approves, publishes or merges; never changes its own role card, skills or mandate; never touches keys; never deletes data; and never names a price, signs, promises or gives access without a person's ok. A mandate goes up only by a board decision.
Screens and endpoints
Each app is a view of the shared resources, and apps link by the shared resource id. The calendar is GET /api/v1/calendar, Constitor's own calendar, stored here, and the source of truth. An event may link a task, a scheduled post, or a meeting. The week of posts is a filter on that list. Microsoft 365, and later Google, are optional sync connectors and are never required. Communication is GET /api/v1/conversations, the one communication API, stored here. Channel is a field: email, WhatsApp, SMS, Slack, Teams, or in-app. A new channel is a connector, not a new path. Files are GET /api/v1/files. Tasks are GET /api/v1/tasks, and a planning view is a filter on that list. Notifications are GET /api/v1/notifications and are delivered on a conversation channel. Search is GET /api/v1/search. The audit trail is GET /api/v1/audit-events. Posts are GET /api/v1/posts. Contacts are the Directory. Flows are GET /api/v1/flows. A new app uses these services. It does not build its own. 35 of 92 screens can be built on a path that is served in the repository. The rest are planned on those resources, or still wait for a path. Phase 1 paths are live. Directory, Socius and the agent paths are served in the repository and are not yet on the live host.
Socius29 screens · 24 served
| Screen | Resource | Path | Status |
|---|---|---|---|
| Sign-in | Sign-in | The Constitor login, not /v1 | Served |
| Invite sign-in | Sign-in | The Constitor login, not /v1 | Served |
| Customers | Customer organisations | GET /api/v1/partner-tenants | Served |
| Customer states | Customer organisations | GET /api/v1/partner-tenants | Served |
| New customer | Customer organisations | POST /api/v1/partner-tenants | Served |
| New customer states | Customer organisations | POST /api/v1/partner-tenants | Served |
| Accept invite | Invitations | POST /api/v1/organisations/{organisationId}/invitations/{invitationId}/accept | Served |
| People | Members and roles | GET /api/v1/organisations/{organisationId}/members, GET …/roles | Served |
| Companies | Directory | GET /api/v1/directory/organisations | Served |
| Company | Directory | GET /api/v1/directory/organisations | Served |
| Contacts | Directory | GET /api/v1/directory/persons. Microsoft contacts are not this list | Served |
| Person | Directory | GET /api/v1/directory/persons | Served |
| Deals | Deals | GET /api/v1/deals | Served |
| Deal | Deals | GET /api/v1/deals | Served |
| Partner deal | Deals | GET /api/v1/deals and GET /api/v1/partner-tenants. The sharing rule is still open | Partly |
| Import | Directory | POST /api/v1/directory/imports | Served |
| Outreach | Flows | GET /api/v1/flows planned. Articles are served. The run is GET /api/v1/outreach planned | Partly |
| Sequence | Flows | GET /api/v1/flows planned | Planned |
| Modules | Modules | GET /api/v1/organisations/{organisationId}/modules | Served |
| Projects | Projects | GET /api/v1/projects | Served |
| Project | Projects | GET /api/v1/projects | Served |
| Trips | Trips | GET /api/v1/trips | Served |
| Trip | Trips | GET /api/v1/trips | Served |
| Grant calls | Grants | GET /api/v1/calls | Served |
| Grant proposal | Grants | GET /api/v1/grant-proposals | Served |
| Applications | Grants | GET /api/v1/grant-proposals | Served |
| Deals overview | Deals | GET /api/v1/deals | Served |
| Pipeline | Partner tenants | GET /api/v1/partner-tenants is served. This view has no path yet | Waits for API |
| Sales steps | Flows | GET /api/v1/flows planned | Planned |
Mercator9 screens · 0 served
| Screen | Resource | Path | Status |
|---|---|---|---|
| Flow editor | Flows | GET /api/v1/flows planned | Planned |
| Calendar | Calendar | GET /api/v1/calendar planned. The week of posts is a filter. The post stays GET /api/v1/posts | Planned |
| Post | Posts | GET /api/v1/posts planned | Planned |
| Publishing channels | Publishing | GET /api/v1/publishing/channels planned | Planned |
| Email flow | Flows | GET /api/v1/flows planned | Planned |
| Content steps | Flows | GET /api/v1/flows planned | Planned |
| Ideal customer profile | Profiles | GET /api/v1/ideal-customer-profiles planned | Planned |
| Content plan | Posts | GET /api/v1/posts planned | Planned |
| Search brief | Posts | GET /api/v1/posts planned | Planned |
Battalion29 screens · 9 served
| Screen | Resource | Path | Status |
|---|---|---|---|
| Agent home | Agents | GET /api/v1/agents | Served |
| Triggers | Triggers | GET /api/v1/triggers planned | Planned |
| Mandates | Mandates | GET /api/v1/mandates | Served |
| Run | Runs | GET /api/v1/agents/{id}/runs and …/steps | Served |
| Waits | Waits | GET /api/v1/agents/{id}/runs/{runId}/waits | Served |
| Ways out | Ways out | GET /api/v1/ways-out planned | Planned |
| Lessons | Lessons | Article proposals are served. GET /api/v1/lessons planned | Partly |
| Autonomy | Autonomy | GET /api/v1/autonomy-ladder planned | Planned |
| Today | Today | GET /api/v1/today planned. Runs and waits are served | Partly |
| Roster | Agents | GET /api/v1/agents | Served |
| Agent | Agents | GET /api/v1/agents and GET /api/v1/mandates | Served |
| Runs | Runs | GET /api/v1/agents/{id}/runs | Served |
| Teams | Teams and flows | GET /api/v1/teams and GET /api/v1/flows planned | Planned |
| Safety | Budgets | GET /api/v1/budgets and GET /api/v1/cost-stop planned | Planned |
| Flow | Flows | GET /api/v1/flows planned | Planned |
| Handbook edit | Handbook | Article save and proposals are served. GET /api/v1/agent-sync planned | Partly |
| Memory | Memory | GET /api/v1/memory planned | Planned |
| Trace | Steps | GET …/steps is served. Receipts are GET …/receipts planned | Partly |
| Schedules | Schedules | GET /api/v1/schedules planned | Planned |
| Evals | Evals | GET /api/v1/evals planned | Planned |
| Coding | Agents | GET /api/v1/agents | Served |
| Models | Models | GET /api/v1/models and GET /api/v1/budgets planned | Planned |
| Tools | Tools | GET /api/v1/agents/{id}/tools planned | Planned |
| Sync | Versions | Article versions are served. GET /api/v1/agent-sync planned | Partly |
| Access | Roles | Members and roles are served. GET /api/v1/agents/{id}/access planned | Partly |
| Agents | Agents | GET /api/v1/agents | Served |
| Flows | Flows | GET /api/v1/flows planned | Planned |
| Modes | Teams | GET /api/v1/teams planned | Planned |
| Lesson | Lessons | GET /api/v1/lessons planned | Planned |
Auxilium17 screens · 0 served
| Screen | Resource | Path | Status |
|---|---|---|---|
| Feedback | Tickets | GET /api/v1/tickets and GET /api/v1/stickers planned | Planned |
| Tickets | Tickets | GET /api/v1/tickets planned | Planned |
| Ticket | Tickets | GET /api/v1/tickets planned | Planned |
| Thanks | Stickers | GET /api/v1/stickers planned | Planned |
| Flow | Flows | GET /api/v1/flows planned | Planned |
| Setup | Handbook | Handbook articles are served. This screen has no product path | Waits for API |
| Today | Today | GET /api/v1/today planned | Planned |
| Inbox | Conversations | GET /api/v1/conversations planned | Planned |
| Conversation | Conversations | GET /api/v1/conversations planned | Planned |
| Customers | Directory | GET /api/v1/directory/organisations and GET /api/v1/directory/persons. Service levels have no path | Partly |
| Help | Handbook | Articles are served. A public mark has no path | Partly |
| Roadmap | Roadmap | GET /api/v1/roadmap planned | Planned |
| Epics | Roadmap | No path yet | Waits for API |
| Status | Status | GET /api/v1/status and GET /api/v1/incidents planned | Planned |
| Reports | Reports | GET /api/v1/helpdesk/reports planned | Planned |
| Channels | Conversations | GET /api/v1/conversations planned. A connector is optional and is never required | Planned |
| Git settings | Git | No /v1 path | Waits for API |
Shared in every app8 screens · 2 served
| Screen | Resource | Path | Status |
|---|---|---|---|
| Shell | Shell | No resource. The app shell | Served |
| Panel | Waits | GET /api/v1/agents/{id}/runs/{runId}/waits is served. Receipts are planned | Partly |
| Today | Today | GET /api/v1/today planned | Planned |
| Planning | Calendar | GET /api/v1/calendar planned. A planning task is a filter on GET /api/v1/tasks. A workspace task list is a connector, not this list | Planned |
| Inbox | Conversations | GET /api/v1/conversations planned. Stored here. Mail and Microsoft 365 are optional connectors | Planned |
| Thread | Conversations | GET /api/v1/conversations planned | Planned |
| Channels | Conversations | GET /api/v1/conversations planned. A connector is optional and is never required | Planned |
| Links | Links | GET /api/v1/links | Served |
How it fits together
There is one API. Every screen, bot, connector and outside tool goes through it, and nothing reads or writes the database directly. Only schema migrations touch the database, through the controlled migration pipeline. That rule (API first, C0.4 and D91) is what keeps every app the same shape and every change audited. Each app is a view of the shared resources, stored in the platform and the source of truth: one calendar (/api/v1/calendar), one communication layer (/api/v1/conversations, channel is a field), one file store (/api/v1/files), one task list (/api/v1/tasks), one notification list (/api/v1/notifications), one search (/api/v1/search), one audit trail (/api/v1/audit-events), one posts list (/api/v1/posts), one Directory, and one flows list (/api/v1/flows). Connectors are optional and are never required. A new app uses these services. It does not build its own.
The layers, left to right
- Callers. The five apps, the bots and agents, MCP connectors and outside integrations. An app never adds its own API in front of this one; there is no backend-for-frontend.
- Identity. A person signs in once with the Constitor login (Microsoft, Google or the customer's own SSO) and that session works in every app. A machine uses a token the platform mints, bound to one organisation. There is no open self-signup: an account exists only by invitation or by an admin.
- The API. Every call is authenticated, scoped to one organisation (tenant), checked against a named capability of the caller's role, and leaves an audit receipt. The OpenAPI document is generated from one module in the platform app and is the single source.
- Behind the API. Kernel tables (organisations, people, roles, the Directory), headless engines reached through adapters, Microsoft 365 on behalf of the signed-in user, and the agent runtime's private store. Engines are used unmodified and never shown; the document uses our names only.
- Data. One EU database in Paris. Every row carries
tenant_id, and row-level security only lets a request see rows of its own tenant. A partner reaches a customer only through thepartner_tenantslink and a consent grant.
Hosts
| What | Address | Status |
|---|---|---|
| Platform app and API | https://app.constitor.ai/api/v1 | Live |
| OpenAPI document | https://app.constitor.ai/api/v1/openapi | Live, OpenAPI 3.0.3 |
| Interactive reference | https://app.constitor.ai/api/v1/docs | Live |
| Handbook MCP | https://handbook-mcp.constitor.ai/api/mcp | Live, read-only |
| Microsoft workspace MCP | https://microsoft-mcp.constitor.ai/api/mcp | Live |
| Own API host | https://api.constitor.ai/v1 | Proposed, not accepted |
How to connect
Pick the route that matches what you are building. All four end at the same API with the same checks; they differ only in how the caller proves who it is.
1 · An app in the suite
- Send the person to the Constitor login. They choose Microsoft, Google or SSO. Sign-in is not a
/v1resource, and the app keeps no user table of its own. - After sign-in the browser holds the suite session. Call the API from the same origin with credentials included.
- Read
GET /api/v1/sessionfor the signed-in account and the active organisation, andGET /api/v1/mefor roles. - Show the organisation switcher from
GET /api/v1/organisations; switch withPOST /api/v1/organisations/{organisationId}/activate. Every later call works in the active organisation.
// any app in the suite, same origin, session included
const res = await fetch('/api/v1/session', { credentials: 'include' });
if (!res.ok) {
const { error } = await res.json(); // e.g. "Sign in is required."
throw new Error(error);
}
const session = await res.json(); // the account and the active organisation
Apps use the shared package (a typed client generated from the OpenAPI document, the session helper and the tenant switch) instead of hand-written calls once it is published.
2 · An outside tool or script
- Get a service token minted by the platform for one organisation. The design shows this under Battalion › Access; who may mint one is still an open question. The token is bound to that organisation and carries scopes.
- Store the token in your own secret store. Name it, never paste it in a chat, ticket or repository.
- Send it as a bearer token on every call. The organisation comes from the token; you cannot switch it.
curl https://app.constitor.ai/api/v1/me \
-H "Authorization: Bearer $CONSTITOR_TOKEN"
Scopes today: microsoft:read and microsoft:write, which the Microsoft routes enforce. Other scope names, token lifetime and who may mint are open questions. A move from the current static token to OAuth 2.1 through Microsoft Entra is proposed (D155) and not yet accepted.
3 · An MCP connector
Connect the MCP host in your tool (for example the handbook MCP at https://handbook-mcp.constitor.ai/api/mcp). Every MCP tool is a thin wrapper over one or more /v1 calls, so it gets the same tenant scope, capability check and audit. The handbook MCP reads the git corpus of the handbook; that read is not a database read.
4 · A bot or agent
Agents are defined in the handbook and run in an agent cell. For each run the cell receives a short-lived token for one tenant (D97) and calls /v1 like any other caller. An agent drafts and asks; it never approves its own work, and every step leaves a receipt.
Your first calls: phase 1
The first milestone: a partner signs in, creates a customer organisation and invites its first admin. These are the only calls the phase 1 screens use, in this order. All are served.
| # | Step | Call |
|---|---|---|
| 1 | Sign in with the work account | The Constitor login, not a /v1 resource |
| 2 | Session after sign-in | GET /api/v1/session |
| 3 | Account, organisation, roles | GET /api/v1/me |
| 4 | The partner's own organisations (the switcher, not the customer list) | GET /api/v1/organisations |
| 5 | Switch the active organisation | POST /api/v1/organisations/{organisationId}/activate |
| 6 | Organisation overview | GET /api/v1/organisations/{organisationId} |
| 7 | Customer list | GET /api/v1/partner-tenants |
| 8 | Create the customer and invite its first admin, in one call | POST /api/v1/partner-tenants |
| 9 | The invited admin signs in and accepts | POST /api/v1/organisations/{organisationId}/invitations/{invitationId}/accept |
| 10 | People and roles after accept | GET …/members, GET …/roles |
Create a customer
The active organisation is the partner's, taken from the session. The body has three fields. Send an Idempotency-Key so a retry never creates a second customer.
POST /api/v1/partner-tenants
Idempotency-Key: new-customer-example-bv-01
Content-Type: application/json
{
"name": "Sample customer",
"slug": "example-bv",
"email": "admin@example.com"
}{ "error": "Slug is not valid." }
Other messages for this call:
"Name is required."
"Enter a work email."
"Only a partner admin may do that."
"The customer was not created."Do not call POST /api/v1/organisations here: that creates an organisation for the caller's own Microsoft tenant, not a customer. A later invite, once the customer has members, is POST /api/v1/organisations/{organisationId}/invitations with an email and a role; that role waits for board approval. The first admin gets the opening management grant on accept.
Read the customer list
GET /api/v1/partner-tenants
GET /api/v1/partner-tenants?cursor=<next_cursor from the previous page>
A page lists each customer's name, slug and status.
A further page exists only when next_cursor is set.
/api/v1/docs shows every field.Conventions
The rules every path follows. They come from the Platform API section of the build plan; where a number is not set yet, it says so.
| Topic | Rule |
|---|---|
| Versioning | The version is in the path: /api/v1. A breaking change is a new segment; v1 is never broken in place. |
| Authentication | People: the one Constitor login and its session. Machines: a service token minted by the platform, bound to one organisation, with scopes. Agents: a short-lived token per run. |
| Tenant | Every call works in exactly one organisation: the active one from the session, or the one bound to the token. Rows of another organisation are invisible, enforced in the database by row-level security. |
| Permissions | Each path checks a named capability of the caller's role. Role changes are approved by the board role; agents draft and never approve alone. |
| Lists | New lists return one page: items and next_cursor. Pass cursor to get the next page. No offset paging. The page size cap is not set yet. |
| Errors | The HTTP status plus one body shape: { "error": "<message>" }. The message is written for a person and can be shown as is. There is no second error envelope. |
| Retries | Creates and sends accept Idempotency-Key (8 to 80 letters, digits, _ or -). The same key and body return the first result; the same key with a different body is a conflict. |
| Rate limits | Per organisation and per token. A limited call returns 429. The numbers are not set yet. |
| Webhooks | An integration registers a URL through the API; each delivery is one HTTPS POST with one event. Event names, signature and retry rule are not set yet. |
| Audit | Every write leaves an append-only receipt. Sign-in events are audited from the login itself. A caller reads receipts through the API. |
| Names | Paths, tags and descriptions use Constitor names. Engines and vendors behind the API are never named in the document. This page names a screen, not a design-file code. |
| Accounts | No open self-signup. Accounts come only by invitation or by an admin through /v1. |
What is live, and what comes when
The owner set the order on 16 October 2026: the API specification first, then the endpoints, then the screens. A screen waits until its phase's endpoints exist. A path without a handler is in the document as x-constitor-status: planned.
| Phase | What it delivers | Paths | Status |
|---|---|---|---|
| Phase 1 | A partner signs in, creates a customer and invites its first admin (Socius S0 and S1) | session, me, organisations, partner-tenants, invitations, members, roles | Served |
| Phase 2 | Directory and Socius: companies and people, deals, projects, trips, grants, CSV import, modules | /directory/…, /deals, /projects, /trips, /calls, /grant-proposals | In the repo, not live |
| Later | The shared calendar, Inbox, files, tasks, notifications, search and audit trail | /calendar, /conversations, /files, /tasks, /notifications, /search, /audit-events | Planned |
| Later | The one flows list and the one posts list | /flows, /posts, /publishing/channels | Planned |
| Later | Auxilium: tickets, help center, status, roadmap, stickers. Customers read the Directory | /tickets, /help/articles, /status, /incidents, /roadmap, /stickers | Planned |
| Later | Battalion: agents, runs, mandates and waits are in the repository. Teams, memory, evals, schedules, models and budgets come after. Flows are the shared list | /agents, /mandates, /flows, … | Partly |
| Later | Billing: pilots, cohorts, usage. The markup is not decided | /pilots, /cohorts, /usage, /cost-stop | Planned |
Microsoft 365 routes (/api/v1/microsoft/…) are live today. They are the signed-in user's own mailbox, calendar, planner and directory lookup, not the product Directory, Inbox or Planning.
Security and data
- Where data lives. One EU database in Paris. Every row carries its organisation; row-level security keeps organisations apart, and a partner sees a customer only with a time-limited consent grant.
- Keys and secrets. Keys are named, never shown. Server and app secrets sit in an EU secret store; a runtime reads only its own. No secret goes into a chat, ticket or repository.
- Microsoft 365. Always delegated: the API acts as the signed-in person, never as an app with its own Graph rights. Writes need
microsoft:write. - Models. Every model call goes through our own gateway and is logged. Apps and outside callers never call a model vendor directly, and the document names none.
- Agents. Agents run on short-lived tokens, work inside a mandate, and stop at a wait for a person's ok. Their working memory is the one store outside the API (D94); approvals are still recorded through it.
- Platform staff. Support has no standing access to an organisation's content. Any impersonation is written to the audit log.
Open questions for the owner
Not decided yet. Until they are, the API does not promise a number or name here.
- Rate-limit numbers per organisation and per token.
- Service tokens: lifetime, who may mint one, and scope names beyond
microsoft:readandmicrosoft:write. - Webhooks: event names, signature scheme and retry rule.
- Page size cap for lists.
- Notes: whether CRM notes and the existing
/api/v1/notesare one record. - Public host: stay on
app.constitor.aior move toapi.constitor.ai. - Deal stage names in Socius.
- Request and response schemas are not in the document yet; until they are, field names come from the handbook pages.
Every path, by group
Every operation in the served document, grouped. The same document is at GET /api/v1/openapi and GET /api/v1/openapi.json. Use the filter in the contents column to find a path.