{"openapi":"3.0.3","info":{"title":"Constitor platform API","version":"v1","description":"Authenticated, tenant-scoped API for organisations, members, role assignment, Microsoft workspace data, agents, the handbook, and registers. Version 1. Handbook and register reads are /api/v1/handbook and /api/v1/registers. Writes and recoverable deletes require the scope microsoft:write. An agent state is working, waiting_for_ok, done, stopped, or failed."},"paths":{"/api/v1/session":{"get":{"summary":"Signed-in session and the active organisation.","tags":["Session and organisations"]}},"/api/v1/me":{"get":{"summary":"Signed-in account, organisation, and roles.","tags":["Session and organisations"]}},"/api/v1/health":{"get":{"summary":"Process check.","tags":["Session and organisations"]}},"/api/v1/docs":{"get":{"summary":"Guides and the interactive reference for this document.","tags":["Session and organisations"]}},"/api/v1/openapi":{"get":{"summary":"This document.","tags":["Session and organisations"]}},"/api/v1/openapi.json":{"get":{"summary":"This document.","tags":["Session and organisations"]}},"/api/v1/notes":{"get":{"summary":"Tenant notes for the signed-in organisation.","tags":["Notes"]},"post":{"summary":"Add a tenant note for the signed-in organisation.","tags":["Notes"]}},"/api/v1/tokens/database":{"post":{"summary":"Mint a short-lived database token for the signed-in organisation.","tags":["Session and organisations"]}},"/api/v1/partner-tenants":{"get":{"summary":"Customer organisations linked to the active partner organisation.","tags":["Partner tenants"]},"post":{"summary":"Create a customer organisation and invite its first admin.","tags":["Partner tenants"]}},"/api/v1/partner-tenants/slug-availability":{"get":{"summary":"Whether a customer short name is free. Query: slug. A partner admin calls this before creating a customer.","tags":["Partner tenants"]}},"/api/v1/handbook":{"get":{"summary":"Platform handbook commit, chapter counts, and ground rules.","tags":["Handbook"]}},"/api/v1/handbook/search":{"get":{"summary":"Search handbook articles, register articles, decisions, and control and glossary terms. Query: q.","tags":["Handbook"]}},"/api/v1/decisions":{"get":{"summary":"Platform decisions read from the handbook: id, title, status, date, and path.","tags":["Handbook"]}},"/api/v1/decisions/{decisionId}":{"get":{"summary":"One platform decision, including the body. The id is a D-number.","tags":["Handbook"]}},"/api/v1/handbook/articles/{articleId}":{"get":{"summary":"One handbook article: title, fields, body, path, and commit.","tags":["Handbook"]}},"/api/v1/handbook/articles/{articleId}/save":{"post":{"summary":"Propose a handbook change as a pull request. An agent does not approve.","tags":["Handbook"]}},"/api/v1/handbook/articles/{articleId}/changes":{"get":{"summary":"Pull requests for one article: author, approving code owner, and timestamp. Read from the git host. No local audit table.","tags":["Handbook"]}},"/api/v1/links":{"get":{"summary":"Typed links to and from one object. Git index joined with runtime links for the signed-in organisation. Query: id.","tags":["Handbook"]}},"/api/v1/handbook/vocabularies":{"get":{"summary":"Kind, form, status, and norm refs read from the constitution spec and handbook files.","tags":["Handbook"]}},"/api/v1/handbook/articles/{articleId}/versions":{"get":{"summary":"Published article and earlier commits for one path. Read from the git host.","tags":["Handbook"]}},"/api/v1/handbook/articles/{articleId}/versions/{ref}":{"get":{"summary":"Article text at one commit, the published file, or a baseline-vX.Y tag.","tags":["Handbook"]}},"/api/v1/handbook/compose":{"get":{"summary":"Composed handbook for one tenant. Optional brand, app, and bot query params. An app needs a brand. A bot needs a brand. A conflict returns both texts and no composed page.","tags":["Handbook"]}},"/api/v1/handbook/articles/{articleId}/proposals":{"get":{"summary":"Open pull requests for one article, and whether the signed-in human may review.","tags":["Handbook"]}},"/api/v1/handbook/articles/{articleId}/proposals/{number}/comments":{"get":{"summary":"Comments on one proposal pull request.","tags":["Handbook"]},"post":{"summary":"Add a pull-request comment as the signed-in GitHub user. This is not a review.","tags":["Handbook"]}},"/api/v1/handbook/articles/{articleId}/proposals/{number}/reviews":{"post":{"summary":"Submit APPROVE or REQUEST_CHANGES with the GitHub token the Constitor login stored for the signed-in user. The app token is not used.","tags":["Handbook"]}},"/api/v1/handbook/corpus":{"get":{"summary":"Handbook pages and the commit they were read from. Article ids stay the handbook ids.","x-constitor-status":"planned","tags":["Handbook"]}},"/api/v1/handbook/statement-of-applicability":{"get":{"summary":"Statement of applicability for the pilot controls. An empty list is an empty register.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/handbook/suppliers":{"get":{"summary":"Supplier register rows. Names stay the handbook tokens until a record exists.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/suppliers":{"get":{"summary":"Supplier register rows for the signed-in organisation. The same rows as the handbook supplier read.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/suppliers/{id}":{"get":{"summary":"One supplier register row for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/soa":{"get":{"summary":"Statement of applicability for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/contracts":{"get":{"summary":"Contract rows for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/assets":{"get":{"summary":"Asset rows for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/processing-activities":{"get":{"summary":"Processing activities for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/ai-systems":{"get":{"summary":"AI system rows for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/training":{"get":{"summary":"Training rows for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/organisation":{"get":{"summary":"Department rows for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/risks":{"get":{"summary":"Risk rows for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/incidents":{"get":{"summary":"Incident rows for the signed-in organisation. This is not the helpdesk incident path.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/exceptions":{"get":{"summary":"Exception rows for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/registers/gaps":{"get":{"summary":"Gap rows for the signed-in organisation.","x-constitor-status":"planned","tags":["Registers"]}},"/api/v1/organisations":{"get":{"summary":"Organisations the signed-in user belongs to.","tags":["Session and organisations"]},"post":{"summary":"Create an organisation when the Microsoft tenant has none.","tags":["Session and organisations"]}},"/api/v1/organisations/{organisationId}/activate":{"post":{"summary":"Set the active organisation. The caller must be a member.","tags":["Session and organisations"]}},"/api/v1/organisations/connect":{"get":{"summary":"Start Microsoft admin consent to connect the signed-in tenant.","tags":["Session and organisations"]}},"/api/v1/organisations/connect/callback":{"get":{"summary":"Finish admin consent and bind the Entra tenant.","tags":["Session and organisations"]}},"/api/v1/organisations/{organisationId}/connections":{"get":{"summary":"Linked accounts for the signed-in member. Status, account name, date, and scopes. No secret name and no secret value. Requires connection.read.","tags":["Session and organisations"]}},"/api/v1/organisations/{organisationId}/connections/{provider}/link":{"post":{"summary":"Start linking GitHub or Microsoft while signed in. Requires connection.own.link. Returns an address and sets the state cookie the callback checks.","tags":["Session and organisations"]}},"/api/v1/organisations/{organisationId}/connections/{provider}/unlink":{"post":{"summary":"Unlink the signed-in member's GitHub account. Microsoft sign-in cannot be unlinked. Requires connection.own.unlink. Audited.","tags":["Session and organisations"]}},"/api/v1/microsoft/sites":{"get":{"summary":"List SharePoint sites for the organisation, or one site by hostname and path. Read-only.","tags":["Microsoft 365"]}},"/api/v1/microsoft/drives":{"get":{"summary":"List drives on one SharePoint site. Query: organisation_id, site_id. Read-only.","tags":["Microsoft 365"]}},"/api/v1/microsoft/items":{"get":{"summary":"List folder items. Query: organisation_id or organisation, drive_id, optional item_id.","tags":["Microsoft 365"]},"patch":{"summary":"Rename or move one drive item. The item id stays the same, so version history stays on that item. Requires microsoft:write. Audited as microsoft_write with the operation and target ids.","tags":["Microsoft 365"]},"delete":{"summary":"Move one drive item to the SharePoint or OneDrive recycle bin. Recoverable. Never a permanent delete. Requires microsoft:write. Audited as microsoft_write with the operation and target ids.","tags":["Microsoft 365"]}},"/api/v1/microsoft/search":{"get":{"summary":"Search files. Query: organisation_id, query. Read-only.","tags":["Microsoft 365"]}},"/api/v1/microsoft/files":{"post":{"summary":"Create a file. An existing name fails and is not replaced. Requires microsoft:write. Audited as microsoft_write with the operation and target ids, never the bytes.","tags":["Microsoft 365"]},"get":{"summary":"Read a text, docx, or pdf file where the bytes can be turned into text. mode=base64 returns at most 3 MB of file bytes. mode=download_url returns a short-lived download URL from the drive item or from the content redirect, and does not download the bytes.","tags":["Microsoft 365"]},"put":{"summary":"Update file content in place on the same item through an upload session so SharePoint version history accrues. conflictBehavior is replace. Check-out and check-in run when the library requires check-out. A name conflict does not create a new item. Requires microsoft:write. Audited as microsoft_write with the operation and target ids, never the bytes.","tags":["Microsoft 365"]}},"/api/v1/microsoft/folders":{"post":{"summary":"Create a folder. An existing name fails and is not replaced. Requires microsoft:write. Audited as microsoft_write with the operation and target ids.","tags":["Microsoft 365"]}},"/api/v1/microsoft/items/rename-open":{"patch":{"summary":"Rename a drive item that is open for coauthoring. Sends Prefer: bypass-shared-lock. The item id stays the same. An exclusive checkout stays locked. Requires microsoft:write. Audited as microsoft_write with the operation and target ids.","tags":["Microsoft 365"]}},"/api/v1/microsoft/workbook/sheets":{"get":{"summary":"List worksheets in an Excel workbook. Read-only.","tags":["Microsoft 365"]},"post":{"summary":"Add a worksheet to an existing workbook. Requires microsoft:write and Files.ReadWrite.All. The audit records the operation and target ids, not cell values.","tags":["Microsoft 365"]},"patch":{"summary":"Rename a worksheet. The workbook item id stays the same. Requires microsoft:write. The audit records the operation and target ids, not cell values.","tags":["Microsoft 365"]},"delete":{"summary":"Delete a worksheet from a workbook. This is not a drive-item delete and does not permanently delete the file. Requires microsoft:write.","tags":["Microsoft 365"]}},"/api/v1/microsoft/workbook/range":{"get":{"summary":"Read one worksheet range. Query: sheet, address.","tags":["Microsoft 365"]},"patch":{"summary":"Write values into an existing worksheet range in place. Requires microsoft:write. The audit records the operation and target ids, not the cell values.","tags":["Microsoft 365"]}},"/api/v1/microsoft/workbook/range/insert":{"post":{"summary":"Insert rows or columns in a worksheet. shift is Down or Right. Requires microsoft:write. The audit records the operation and target ids, not cell values.","tags":["Microsoft 365"]}},"/api/v1/microsoft/workbook/range/delete":{"post":{"summary":"Delete rows or columns in a worksheet by shifting cells. shift is Up or Left. This is not a drive-item delete. Requires microsoft:write.","tags":["Microsoft 365"]}},"/api/v1/microsoft/workbook/range/merge":{"post":{"summary":"Merge a worksheet range. across merges each row separately. Requires microsoft:write.","tags":["Microsoft 365"]}},"/api/v1/microsoft/workbook/range/unmerge":{"post":{"summary":"Unmerge a worksheet range. Requires microsoft:write.","tags":["Microsoft 365"]}},"/api/v1/microsoft/workbook/range/format":{"patch":{"summary":"Set bold, column width, row height, fill color or font color on a range. Requires microsoft:write. The audit does not store cell values.","tags":["Microsoft 365"]}},"/api/v1/microsoft/workbook/visibility":{"patch":{"summary":"Hide or unhide rows, columns or a worksheet. Requires microsoft:write.","tags":["Microsoft 365"]}},"/api/v1/microsoft/teams":{"get":{"summary":"List Teams in the organisation tenant. Read-only.","tags":["Microsoft 365"]}},"/api/v1/microsoft/channels":{"get":{"summary":"List channels in one team. Query: organisation_id or organisation, team_id.","tags":["Microsoft 365"]},"post":{"summary":"Create a standard channel. Requires microsoft:write and Channel.Create. Does not create a site.","tags":["Microsoft 365"]}},"/api/v1/microsoft/channels/messages":{"get":{"summary":"List recent messages in one channel. Requires the delegated scope ChannelMessage.Read.All.","tags":["Microsoft 365"]},"post":{"summary":"Post a plain-text Teams channel message. Requires microsoft:write and the delegated scope ChannelMessage.Send. The audit records the operation and target ids, not the message text.","tags":["Microsoft 365"]}},"/api/v1/microsoft/channels/replies":{"post":{"summary":"Reply in a channel thread. Requires microsoft:write and ChannelMessage.Send. The audit stores the ids, not the text.","tags":["Microsoft 365"]}},"/api/v1/microsoft/chats":{"get":{"summary":"List the signed-in user's chats. Requires Chat.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/chats/messages":{"get":{"summary":"List messages in one chat, including message type, event detail, attachments, content URL and hosted contents. Requires Chat.ReadWrite.","tags":["Microsoft 365"]},"post":{"summary":"Send plain text in a chat. Requires microsoft:write and Chat.ReadWrite. The audit stores the ids, not the text.","tags":["Microsoft 365"]}},"/api/v1/microsoft/meetings":{"post":{"summary":"Create a Teams online meeting. Requires microsoft:write and OnlineMeetings.ReadWrite. The audit stores the meeting id, not the join URL.","tags":["Microsoft 365"]}},"/api/v1/microsoft/meetings/find":{"get":{"summary":"Find an online meeting by join URL. Requires OnlineMeetings.ReadWrite. Read-only.","tags":["Microsoft 365"]}},"/api/v1/microsoft/meetings/transcripts":{"get":{"summary":"List transcripts for an online meeting. Requires OnlineMeetingTranscript.Read.All. Read-only.","tags":["Microsoft 365"]}},"/api/v1/microsoft/meetings/transcript":{"get":{"summary":"Read one transcript as text/vtt or plain text. Requires OnlineMeetingTranscript.Read.All. Read-only. The audit does not store the transcript.","tags":["Microsoft 365"]}},"/api/v1/microsoft/meetings/attendance-reports":{"get":{"summary":"List attendance reports for an online meeting. Requires OnlineMeetingArtifact.Read.All. Read-only.","tags":["Microsoft 365"]}},"/api/v1/microsoft/meetings/attendance-records":{"get":{"summary":"List attendance records for one report. Requires OnlineMeetingArtifact.Read.All. Read-only.","tags":["Microsoft 365"]}},"/api/v1/microsoft/meetings/recordings":{"get":{"summary":"List recordings for an online meeting. Requires OnlineMeetingRecording.Read.All. Read-only. Does not download the recording.","tags":["Microsoft 365"]}},"/api/v1/microsoft/meetings/ai-insights":{"get":{"summary":"Read the Copilot recap for an online meeting. Requires OnlineMeetingAiInsight.Read.All. Read-only. The audit does not store the recap.","tags":["Microsoft 365"]}},"/api/v1/microsoft/presence":{"get":{"summary":"Read one person's presence. Requires Presence.Read.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/people":{"get":{"summary":"List relevant people. Requires People.Read.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/token-scopes":{"get":{"summary":"List delegated scopes on the signed-in user's token. Reads app grants only when Directory.Read.All or Application.Read.All is already on that token.","tags":["Microsoft 365"]}},"/api/v1/microsoft/planner/plans":{"get":{"summary":"List Planner plans for a group. Requires Tasks.ReadWrite or Group.ReadWrite.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/planner/buckets":{"get":{"summary":"List buckets in a Planner plan. Requires Tasks.ReadWrite or Group.ReadWrite.All.","tags":["Microsoft 365"]},"post":{"summary":"Create a Planner bucket. Requires microsoft:write and Tasks.ReadWrite.","tags":["Microsoft 365"]},"delete":{"summary":"Delete a Planner bucket. Reads the etag and sends If-Match. Requires microsoft:write and Tasks.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/planner/task":{"get":{"summary":"Read one Planner task, including start, due, status, bucket, assignees and notes. Requires Tasks.ReadWrite or Group.ReadWrite.All. The audit does not store the notes.","tags":["Microsoft 365"]}},"/api/v1/microsoft/planner/tasks":{"get":{"summary":"List tasks in a Planner plan. Requires Tasks.ReadWrite or Group.ReadWrite.All.","tags":["Microsoft 365"]},"post":{"summary":"Create a Planner task. Requires microsoft:write and Tasks.ReadWrite. The audit stores ids, not the description.","tags":["Microsoft 365"]},"patch":{"summary":"Update a Planner task title, bucket, assignees, start, due, status or notes. Requires microsoft:write and Tasks.ReadWrite.","tags":["Microsoft 365"]},"delete":{"summary":"Delete a Planner task. Reads the etag and sends If-Match. Requires microsoft:write and Tasks.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/planner/tasks/complete":{"post":{"summary":"Mark a Planner task complete. Requires microsoft:write and Tasks.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/items/invite":{"post":{"summary":"Grant read or write on a drive item. Requires microsoft:write and Files.ReadWrite.All or Sites.ReadWrite.All. The audit stores the item id and role, not the recipient.","tags":["Microsoft 365"]}},"/api/v1/microsoft/mail/messages":{"get":{"summary":"List mailbox messages. Requires Mail.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/mail/message":{"get":{"summary":"Read one mailbox message. Requires Mail.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/mail/drafts":{"post":{"summary":"Create a draft. Requires microsoft:write and Mail.ReadWrite. The audit does not store the body or recipients.","tags":["Microsoft 365"]}},"/api/v1/microsoft/mail/send":{"post":{"summary":"Send mail as the signed-in user. Requires microsoft:write and Mail.Send. The audit stores the recipient count, not the body or addresses.","tags":["Microsoft 365"]}},"/api/v1/microsoft/calendar/events":{"get":{"summary":"List calendar events. Requires Calendars.ReadWrite.","tags":["Microsoft 365"]},"post":{"summary":"Create a calendar event. Requires microsoft:write and Calendars.ReadWrite.","tags":["Microsoft 365"]},"patch":{"summary":"Update a calendar event. Sends only the changed fields and keeps isOnlineMeeting, the online meeting and the location of a Teams meeting. Requires microsoft:write and Calendars.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/calendar/event":{"get":{"summary":"Read one calendar event, including onlineMeeting.joinUrl. Event ids may end in '='. Requires Calendars.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/contacts":{"get":{"summary":"List contacts. Requires Contacts.ReadWrite.","tags":["Microsoft 365"]},"post":{"summary":"Create a contact. Requires microsoft:write and Contacts.ReadWrite.","tags":["Microsoft 365"]},"patch":{"summary":"Update a contact. Requires microsoft:write and Contacts.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/users":{"get":{"summary":"Find directory users. Requires User.ReadBasic.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/groups":{"get":{"summary":"List groups. Requires Group.ReadWrite.All. Does not create a group.","tags":["Microsoft 365"]}},"/api/v1/microsoft/groups/members":{"get":{"summary":"List group members. Requires Group.ReadWrite.All.","tags":["Members and roles"]}},"/api/v1/microsoft/todo/lists":{"get":{"summary":"List To Do lists. Requires Tasks.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/todo/tasks":{"get":{"summary":"List To Do tasks. Requires Tasks.ReadWrite.","tags":["Microsoft 365"]},"post":{"summary":"Create a To Do task. Requires microsoft:write and Tasks.ReadWrite.","tags":["Microsoft 365"]},"patch":{"summary":"Update a To Do task. Requires microsoft:write and Tasks.ReadWrite.","tags":["Microsoft 365"]}},"/api/v1/microsoft/onenote/notebooks":{"get":{"summary":"List OneNote notebooks. Requires Notes.ReadWrite.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/onenote/sections":{"get":{"summary":"List OneNote sections. Requires Notes.ReadWrite.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/onenote/pages":{"get":{"summary":"List OneNote pages. Requires Notes.ReadWrite.All.","tags":["Microsoft 365"]},"post":{"summary":"Create a plain-text OneNote page. Requires microsoft:write and Notes.ReadWrite.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/onenote/page":{"get":{"summary":"Read one OneNote page as text. Requires Notes.ReadWrite.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/mail/shared/messages":{"get":{"summary":"List messages in a shared mailbox. Requires Mail.ReadWrite.Shared.","tags":["Microsoft 365"]}},"/api/v1/microsoft/mail/shared/message":{"get":{"summary":"Read one shared-mailbox message. Requires Mail.ReadWrite.Shared.","tags":["Microsoft 365"]}},"/api/v1/microsoft/mail/shared/send":{"post":{"summary":"Send from a shared mailbox. Requires microsoft:write and Mail.Send.Shared. The audit stores the user id and recipient count.","tags":["Microsoft 365"]}},"/api/v1/microsoft/calendar/shared/events":{"get":{"summary":"List events on a shared calendar. Requires Calendars.ReadWrite.Shared.","tags":["Microsoft 365"]},"post":{"summary":"Create an event on a shared calendar. Requires microsoft:write and Calendars.ReadWrite.Shared.","tags":["Microsoft 365"]}},"/api/v1/microsoft/todo/shared/lists":{"get":{"summary":"List shared To Do lists. Requires Tasks.ReadWrite.Shared.","tags":["Microsoft 365"]}},"/api/v1/microsoft/todo/shared/tasks":{"get":{"summary":"List tasks in a shared To Do list. Requires Tasks.ReadWrite.Shared.","tags":["Microsoft 365"]},"post":{"summary":"Create a task in a shared To Do list. Requires microsoft:write and Tasks.ReadWrite.Shared.","tags":["Microsoft 365"]}},"/api/v1/microsoft/contacts/shared":{"get":{"summary":"List shared contacts. Requires Contacts.ReadWrite.Shared.","tags":["Microsoft 365"]}},"/api/v1/microsoft/bookings/businesses":{"get":{"summary":"List booking businesses. Requires Bookings.ReadWrite.All.","tags":["Microsoft 365"]},"post":{"summary":"Create a booking business. Requires microsoft:write and Bookings.ReadWrite.All. That scope cannot create a business; Graph may refuse. Bookings.Manage.All is not requested.","tags":["Microsoft 365"]}},"/api/v1/microsoft/bookings/services":{"get":{"summary":"List booking services. Requires Bookings.ReadWrite.All.","tags":["Microsoft 365"]},"post":{"summary":"Create a booking service. Requires microsoft:write and Bookings.ReadWrite.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/bookings/staff":{"get":{"summary":"List booking staff. Requires Bookings.ReadWrite.All.","tags":["Microsoft 365"]},"post":{"summary":"Create a booking staff member. Requires microsoft:write and Bookings.ReadWrite.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/bookings/appointments":{"get":{"summary":"List booking appointments. Requires BookingsAppointment.ReadWrite.All.","tags":["Microsoft 365"]},"post":{"summary":"Create a booking appointment. Requires microsoft:write and BookingsAppointment.ReadWrite.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/sites/pages":{"get":{"summary":"List SharePoint site pages. Requires Sites.ReadWrite.All.","tags":["Microsoft 365"]},"post":{"summary":"Create a SharePoint site page. Requires microsoft:write and Sites.ReadWrite.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/sites/pages/publish":{"post":{"summary":"Publish a SharePoint site page. Requires microsoft:write and Sites.ReadWrite.All.","tags":["Microsoft 365"]}},"/api/v1/microsoft/files/loop":{"post":{"summary":"Store a .loop file in a drive. Requires microsoft:write and Files.ReadWrite.All. Graph stores the file and does not create a live Loop component.","tags":["Microsoft 365"]}},"/api/v1/microsoft/teams/members":{"get":{"summary":"List team members. Requires TeamMember.ReadWrite.All.","tags":["Members and roles"]},"post":{"summary":"Add a team member. Requires microsoft:write and TeamMember.ReadWrite.All. Apply the change only after the owner has approved it (D158).","tags":["Members and roles"]}},"/api/v1/organisations/{organisationId}":{"get":{"summary":"Organisation overview for a member.","tags":["Session and organisations"]}},"/api/v1/organisations/{organisationId}/members":{"get":{"summary":"Members, their roles, and pending email invites. A reader sees only their own row.","tags":["Members and roles"]}},"/api/v1/organisations/{organisationId}/members/{userId}":{"post":{"summary":"Deactivate or reactivate a member. Management only. The caller cannot change their own access.","tags":["Members and roles"]}},"/api/v1/organisations/{organisationId}/invitations":{"post":{"summary":"Invite a person by email and name the role to propose when they join. Management only. The role is not granted until board approves. System mail is the delivery path. There is no mail resource.","tags":["Members and roles"]}},"/api/v1/organisations/{organisationId}/invitations/{invitationId}/accept":{"post":{"summary":"Accept an invite for the signed-in account. The first admin of a new customer organisation receives the opening management grant. A later invite still waits for board approval.","tags":["Members and roles"]}},"/api/v1/organisations/{organisationId}/roles":{"get":{"summary":"Seeded role catalogue and capabilities.","tags":["Members and roles"]}},"/api/v1/organisations/{organisationId}/roles/{roleId}":{"delete":{"summary":"Delete a custom role. Base roles are refused.","tags":["Members and roles"]}},"/api/v1/organisations/{organisationId}/assignments":{"get":{"summary":"Role assignment proposals and the append-only audit.","tags":["Members and roles"]},"post":{"summary":"Propose an assign or a revoke. Board approval still applies.","tags":["Members and roles"]}},"/api/v1/organisations/{organisationId}/assignments/{proposalId}/approve":{"post":{"summary":"Approve a proposal. The only board holder may self-approve.","tags":["Members and roles"]}},"/api/v1/organisations/{organisationId}/assignments/{proposalId}/reject":{"post":{"summary":"Reject a proposal. The previous assignment stays.","tags":["Members and roles"]}},"/api/v1/directory/organisations":{"get":{"summary":"Directory organisations for the signed-in organisation.","tags":["Directory"]},"post":{"summary":"Create a Directory organisation.","tags":["Directory"]}},"/api/v1/directory/organisations/{id}":{"get":{"summary":"One Directory organisation.","tags":["Directory"]}},"/api/v1/directory/persons":{"get":{"summary":"Directory persons for the signed-in organisation.","tags":["Directory"]},"post":{"summary":"Create a Directory person. This is not a login account.","tags":["Directory"]}},"/api/v1/directory/persons/{id}":{"get":{"summary":"One Directory person.","tags":["Directory"]}},"/api/v1/directory/relations":{"get":{"summary":"Directory relations for the signed-in organisation.","tags":["Directory"]},"post":{"summary":"Create a Directory relation inside the signed-in organisation.","tags":["Directory"]}},"/api/v1/directory/relations/{id}":{"get":{"summary":"One Directory relation.","tags":["Directory"]}},"/api/v1/deals":{"get":{"summary":"Deals for the signed-in organisation.","tags":["Deals"]},"post":{"summary":"Create a deal. A deal value is not stored.","tags":["Deals"]}},"/api/v1/deals/{id}":{"get":{"summary":"One deal.","tags":["Deals"]}},"/api/v1/projects":{"get":{"summary":"Projects for the signed-in organisation.","tags":["Projects"]},"post":{"summary":"Create a project.","tags":["Projects"]}},"/api/v1/projects/{id}":{"get":{"summary":"One project.","tags":["Projects"]}},"/api/v1/trips":{"get":{"summary":"Trips for the signed-in organisation.","tags":["Trips"]},"post":{"summary":"Create a trip.","tags":["Trips"]}},"/api/v1/trips/{id}":{"get":{"summary":"One trip.","tags":["Trips"]}},"/api/v1/calls":{"get":{"summary":"Grant calls for the signed-in organisation.","tags":["Grants"]},"post":{"summary":"Create a grant call.","tags":["Grants"]}},"/api/v1/calls/{id}":{"get":{"summary":"One grant call.","tags":["Grants"]}},"/api/v1/grant-proposals":{"get":{"summary":"Grant proposals for the signed-in organisation.","tags":["Grants"]},"post":{"summary":"Create a grant proposal.","tags":["Grants"]}},"/api/v1/grant-proposals/{id}":{"get":{"summary":"One grant proposal.","tags":["Grants"]}},"/api/v1/directory/imports":{"post":{"summary":"Import Directory organisations or persons from a CSV body.","tags":["Directory"]}},"/api/v1/directory/imports/{id}":{"get":{"summary":"One Directory import: kind, created count, and the new record ids.","tags":["Directory"]}},"/api/v1/organisations/{organisationId}/modules":{"get":{"summary":"Socius modules for one organisation. A missing row is on.","tags":["Session and organisations"]},"put":{"summary":"Turn one Socius module on or off. The records stay.","tags":["Session and organisations"]}},"/api/v1/calendar":{"get":{"summary":"Constitor's own calendar, stored in the platform, and the source of truth. An event may link a task, a scheduled post, or a meeting. Microsoft 365, and later Google, are optional sync connectors and are never required.","x-constitor-status":"planned","tags":["Platform services"]}},"/api/v1/conversations":{"get":{"summary":"The one communication API, stored in the platform, and the source of truth. Channel is a field: email, WhatsApp, SMS, Slack, Teams, or in-app. A new channel is a connector, not a new path. A connector is never required.","x-constitor-status":"planned","tags":["Platform services"]}},"/api/v1/files":{"get":{"summary":"Constitor's own files, stored in the platform. Access follows the caller's role and tenant. A workspace drive is an optional connector and is never required.","x-constitor-status":"planned","tags":["Platform services"]}},"/api/v1/tasks":{"get":{"summary":"The one task list across apps. A task names its source app and linked resource. A planning view is a filter on this list.","x-constitor-status":"planned","tags":["Platform services"]}},"/api/v1/notifications":{"get":{"summary":"Alerts for the signed-in user. Delivery uses a conversation channel. This is not a second inbox.","x-constitor-status":"planned","tags":["Platform services"]}},"/api/v1/notifications/preferences":{"get":{"summary":"Notification preferences for the signed-in user.","x-constitor-status":"planned","tags":["Platform services"]}},"/api/v1/search":{"get":{"summary":"One search across the records the caller may read. The role and the tenant bound the result.","x-constitor-status":"planned","tags":["Platform services"]}},"/api/v1/audit-events":{"get":{"summary":"The one audit trail and the event stream between apps. A row stores ids, not the page body.","x-constitor-status":"planned","tags":["Platform services"]}},"/api/v1/tickets":{"get":{"summary":"Helpdesk tickets.","x-constitor-status":"planned","tags":["Auxilium"]}},"/api/v1/help/articles":{"get":{"summary":"Help articles.","x-constitor-status":"planned","tags":["Auxilium"]}},"/api/v1/status":{"get":{"summary":"Status.","x-constitor-status":"planned","tags":["Auxilium"]}},"/api/v1/incidents":{"get":{"summary":"Incidents.","x-constitor-status":"planned","tags":["Auxilium"]}},"/api/v1/roadmap":{"get":{"summary":"Roadmap.","x-constitor-status":"planned","tags":["Auxilium"]}},"/api/v1/stickers":{"get":{"summary":"Stickers.","x-constitor-status":"planned","tags":["Auxilium"]}},"/api/v1/agents":{"get":{"summary":"Agents for the signed-in organisation. A bot name may be the agent name. model is the model id, or null. A provider class and a model group alias are not returned. State is working, waiting_for_ok, done, stopped, or failed. An agent may include a budget with max, duration, and spent, and cost_usd for the last seven days. A key value is not returned. Token counts are not on this list.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/messages":{"post":{"summary":"Send a message to one agent. The response is a server-sent event stream. An event may be text, a tool name, a reasoning title, a reference, an image, a video, audio, or an error. The answer shows the model id. A provider class and a model group alias are not on the stream. Token counts are not on the stream.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/runs":{"get":{"summary":"Runs for one agent. A run may include the model id and cost_usd. A model group alias is not returned. Token counts are not on this list.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/runs/{runId}/stop":{"post":{"summary":"Stop a working run.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/runs/{runId}/restart":{"post":{"summary":"Restart a stopped or failed run.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/sessions":{"get":{"summary":"Conversations for one agent. Each row is one conversation.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/sessions/{sessionId}":{"get":{"summary":"One conversation. Messages and runs for that conversation. A provider class and a model group alias are not returned.","tags":["Battalion agents, runs and waits"]},"delete":{"summary":"Remove one past conversation.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/spend":{"get":{"summary":"Cost for one agent. today_usd is today, month_usd is this month, and days is one amount per day. The amounts are dollars, to four decimal places. budget_max is present when the agent record carries a budget. A key value is not returned.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/runs/{runId}/events":{"get":{"summary":"Server-sent events for one run. Each flow event is the model, the loaded files, the mandate decision and the tool. A working run sends a later event. A done run sends one event.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/runs/{runId}/steps":{"get":{"summary":"Steps in one run. A step may include cost_usd and the model id the run reports. Token counts are not on this list.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/runs/{runId}/waits":{"get":{"summary":"Waits in one run. A wait asks a person before the action continues.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/runs/{runId}/waits/{waitId}/approve":{"post":{"summary":"Approve a waiting action. The platform records the decision.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/runs/{runId}/waits/{waitId}/reject":{"post":{"summary":"Reject a waiting action. The platform records the decision.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/runs/{runId}/receipts":{"get":{"summary":"Run receipts.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/tools":{"get":{"summary":"Tools one agent may use.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/agents/{id}/access":{"get":{"summary":"Named access for one agent. A key value is not returned.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/mandates":{"get":{"summary":"Mandates for the signed-in organisation. Money, signature, promise, and people stay never.","tags":["Battalion agents, runs and waits"]}},"/api/v1/issues":{"get":{"summary":"Issues.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/pull-requests":{"get":{"summary":"Pull requests.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/outreach":{"get":{"summary":"Outreach.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/today":{"get":{"summary":"What waits today. Each row is one action that still needs a person, with the agent name and its state.","tags":["Battalion agents, runs and waits"]}},"/api/v1/ways-out":{"get":{"summary":"Ways out.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/lessons":{"get":{"summary":"Lessons.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/teams":{"get":{"summary":"Agent teams.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/teams/{id}/messages":{"post":{"summary":"Send a message to one team. The response is a server-sent event stream.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/flows":{"get":{"summary":"The one flows list: content flows, email flows and sequences.","x-constitor-status":"planned","tags":["Flows"]}},"/api/v1/knowledge":{"get":{"summary":"Knowledge.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/memory":{"get":{"summary":"Memory.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/evals":{"get":{"summary":"Evals.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/schedules":{"get":{"summary":"Schedules.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/triggers":{"get":{"summary":"Triggers.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/models":{"get":{"summary":"Models in use. Each row is one model id, the agents that use it, this month's cost in dollars, and the budget when an agent record carries one. A provider class and a model group alias are not returned. A key value is not returned.","tags":["Battalion agents, runs and waits"]}},"/api/v1/budgets":{"get":{"summary":"This month's cost for each agent, in dollars, and the budget when the agent record carries one. A working run id is set when a run is working.","tags":["Battalion agents, runs and waits"]}},"/api/v1/cost-stop":{"get":{"summary":"The same cost rows as budgets. A person stops a working run from this list. The stop is not sent until that person confirms it.","tags":["Battalion agents, runs and waits"]}},"/api/v1/agent-sync":{"get":{"summary":"Agent file sync.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/posts":{"get":{"summary":"The one posts list: the post, the content plan and the search brief. A scheduled post is an event on the calendar and links back to this post.","x-constitor-status":"planned","tags":["Posts"]}},"/api/v1/publishing/channels":{"get":{"summary":"Where a post is published.","x-constitor-status":"planned","tags":["Posts"]}},"/api/v1/ideal-customer-profiles":{"get":{"summary":"Ideal customer profiles.","x-constitor-status":"planned","tags":["Posts"]}},"/api/v1/pilots":{"get":{"summary":"Pilots.","x-constitor-status":"planned","tags":["Billing"]}},"/api/v1/cohorts":{"get":{"summary":"Cohorts.","x-constitor-status":"planned","tags":["Billing"]}},"/api/v1/usage":{"get":{"summary":"Usage.","x-constitor-status":"planned","tags":["Billing"]}},"/api/v1/waits/{id}":{"get":{"summary":"One wait. Approve and reject still need design.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/tools":{"get":{"summary":"Tools.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/instincts":{"get":{"summary":"Instincts. Publication is a separate axis.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/autonomy-ladder":{"get":{"summary":"Autonomy ladder.","x-constitor-status":"planned","tags":["Battalion agents, runs and waits"]}},"/api/v1/helpdesk/setup":{"get":{"summary":"Helpdesk setup.","x-constitor-status":"planned","tags":["Auxilium"]}},"/api/v1/helpdesk/reports":{"get":{"summary":"Helpdesk reports.","x-constitor-status":"planned","tags":["Auxilium"]}}},"tags":[{"name":"Session and organisations","description":"Who is signed in, the active organisation, and this document."},{"name":"Partner tenants","description":"Customer organisations of the active partner."},{"name":"Members and roles","description":"Memberships, invites, roles, and the board's assignments."},{"name":"Directory","description":"The shared organisations, persons and relations, and the CSV import."},{"name":"Deals","description":"Deals for the signed-in organisation."},{"name":"Projects","description":"Projects for the signed-in organisation."},{"name":"Trips","description":"Trips for the signed-in organisation."},{"name":"Grants","description":"Grant calls and grant proposals."},{"name":"Notes","description":"Tenant notes."},{"name":"Handbook","description":"Read the handbook, decisions, versions and search; propose a change as a pull request."},{"name":"Microsoft 365","description":"The signed-in user's own workspace. Not the product Directory, Inbox, calendar, files or tasks."},{"name":"Platform services","description":"Constitor's own calendar, communication, files, tasks, notifications, search and audit trail, stored in the platform. Connectors are optional and are never required."},{"name":"Flows","description":"The one flows list: content flows, email flows and sequences."},{"name":"Auxilium","description":"Tickets, help, status, incidents, roadmap and stickers."},{"name":"Battalion agents, runs and waits","description":"Agents, their mandates, runs, waits and receipts."},{"name":"Posts","description":"The one posts list, publishing channels, and ideal customer profiles."},{"name":"Registers","description":"Supplier rows and the statement of applicability."},{"name":"Billing","description":"Pilots, cohorts and usage."}]}