Reference
API and MCP
Read and change projects from scripts with a personal access token (REST API at /api/v1), and let AI tools read them and propose changes you review (MCP at /mcp); scopes, project lists, the organization switch, limits and examples.
On this page
Holarch has a REST API and an MCP endpoint on the hosted service. Both use a personal access token that you create under Account Settings → API tokens. A token acts as you: it reads and changes the projects you are a member of, within your role in each project.
- REST API:
https://app.holarch.app/api/v1/for scripts, exports, imports and dashboards. - MCP:
https://app.holarch.app/mcpfor AI tools that speak the Model Context Protocol, such as Claude Code. Your own AI client reads the model and proposes changes; Holarch does not run or pay for that AI.
Changes from AI clients arrive as a proposal you review in Holarch (see Proposals from AI clients); nothing changes until you apply it. Changes through the REST API are written like edits in the app: everyone with the project open sees them at once, they are recorded in the project's history under your name, and they are part of the project's versions. The API works on the hosted service only.
Concepts
- Token: a secret that starts with
hol_. Holarch stores only a fingerprint of it and shows the token once, when you create it. - Access: Read only tokens read; Read and write tokens also create, change and delete. Your project role still applies: as a viewer or reviewer you only read, also with a read-and-write token.
- Projects: a token works for all your projects, or only for the projects you select when you create it.
- Expiry: in 30 days, 90 days, 1 year, or never.
- Organization switch: an org admin can turn API access off for the organization's projects. Every token is then refused there with the code
org-policy.
How to use it
Create a token
- Open the account button (your initials) → Account Settings → API tokens.
- Under New token, enter a Name that says what uses it, such as Claude Code or nightly export.
- Choose Access (Read only or Read and write), Expires and Projects (All your projects or Selected projects, then tick them).
- Click Create Token. The dialog Token Created shows the token with a Copy button, a
curlexample and the command to connect Claude Code. - Copy the token now. Holarch shows it only once; an email “A Holarch API token was created” tells you about every new token.
The list shows each token's name, the first characters (hol_abcd…), access, projects, expiry and last use. Revoke ends a token's access at once.
Read a project with curl
curl -H "Authorization: Bearer hol_…" https://app.holarch.app/api/v1/projects
curl -H "Authorization: Bearer hol_…" "https://app.holarch.app/api/v1/projects/<project>/entities?class=Requirement&limit=50"
The first call lists your projects with their ids. The second lists the project's requirements, sorted by number.
Create and relate entities
curl -X POST -H "Authorization: Bearer hol_…" -H "Content-Type: application/json" \
-d '{"class": "Requirement", "name": "Report thickness", "number": "SR.2",
"description": "The system shall report the ice thickness.",
"relationships": [{"relation": "satisfied by", "target": "<asset id>"}]}' \
https://app.holarch.app/api/v1/projects/<project>/entities
The answer is the new entity with its id, attributes (a new requirement starts as Draft) and relationships.
Connect Claude Code (MCP)
- Create a token with the access the tool needs.
- Run:
claude mcp add --transport http holarch https://app.holarch.app/mcp --header "Authorization: Bearer hol_…"
- Ask, for example, “List my Holarch projects”, “Which requirements in the Lake Ice project have no verifying test case?” or “Propose a test case that verifies SR.2”.
- When the tool has sent its proposal, review it in Holarch: ✦ AI ▾ → Review “<title>”…, or the notification under the bell.
Other MCP clients that support remote servers over HTTP with a header work the same way. A client that runs only local servers can use a bridge such as mcp-remote:
npx mcp-remote https://app.holarch.app/mcp --header "Authorization: Bearer hol_…"
Worked example: the CubeSat EO-1 demo
- Create a read-only token for the CubeSat project.
GET /api/v1/projects/<project>/model-checks?class=Requirementlists the requirement findings, such as Requirement.10 Leaf requirements with no verifying test case, with the entity and the related items.GET /api/v1/projects/<project>/qualityscores every requirement on the nine quality attributes, with the findings per attribute.- With a read-and-write token, a script adds the missing test case directly with
POST /api/v1/projects/<project>/entitieswith{"class": "Test Case", "name": "Thermal vacuum test", "relationships": [{"relation": "verifies", "target": "<requirement id>"}]}adds the missing test case. Model Checks then no longer list the requirement.
Tips
- Give each script or tool its own token, read only where it only reads, and limited to the projects it needs.
- Keep tokens out of shared files and source code. Anyone with a token acts as you.
- Ask the AI tool to read the schema first (
get_schema): it lists the class, attribute, relation and label names the project uses. - Model Checks and quality results through the API are returned, not stored. The app's Quality page stores quality results in the requirements.
Personal access tokens
| Field | Values |
|---|---|
| Name | Up to 100 characters |
| Access | Read only, Read and write |
| Expires | In 30 days, 90 days, 1 year, or never |
| Projects | All your projects, or selected projects |
- An account has at most 20 tokens, and creates at most 20 an hour.
- A token stops working when it is revoked, when it expires, and when its account is disabled, unverified or deleted. Removing you from a project ends the token's access to that project at once.
- Send the token in the header
Authorization: Bearer hol_…. Requests never use your browser's sign-in, and a token does not work on the app's own pages or routes. - Each new token is recorded in the audit log and announced by email; the token itself is never logged or mailed.
- Revoked and expired tokens are deleted 90 days after they stopped working. Deleting your account deletes your tokens and your AI clients' proposals at once.
REST API reference
Base address: https://app.holarch.app/api/v1. Answers are JSON. The machine-readable description is at /api/v1/openapi.json (OpenAPI 3.1).
| Method and path | What it does |
|---|---|
GET /me | The token's account, access, projects and expiry |
GET /projects | Your projects: id, name, role, item count, last change, whether API access is allowed, link |
GET /projects/<project> | Name, description, your role, item count and limit, items per class, number of documents |
GET /projects/<project>/schema | Classes with attributes (type, choices), allowed relations and labels; relations with their inverse |
GET /projects/<project>/entities | Search: class, label, q (text in name, number, description or class), limit (1–500, default 100), offset |
POST /projects/<project>/entities | Create: class, name, number, description, labels, attributes, relationships |
GET /projects/<project>/entities/<id> | One entity: attributes by name, labels, relationships with direction and the other entity |
PATCH /projects/<project>/entities/<id> | Change name, number, description, labels or attributes; fields not sent stay |
DELETE /projects/<project>/entities/<id> | Move the entity and its relationships to the project's Trash |
POST /projects/<project>/relationships | Relate: source, relation (named from the source), target, optional attributes |
DELETE /projects/<project>/relationships/<id> | Remove a relationship |
GET /projects/<project>/documents | Documents with type and number of sections |
GET /projects/<project>/documents/<id> | The document's sections in document order, with numbers and plain text |
GET /projects/<project>/model-checks | Model Checks with the project's rule settings; class, rule, limit, offset |
GET /projects/<project>/quality | Requirement quality check; ids (comma-separated) or every requirement |
GET /projects/<project>/versions | Saved versions the project's plan keeps |
Values
- Names: classes, labels, relations and attributes are given by name, case-insensitive (
Requirement,satisfied by,Status). Numeric ids also work. - Attributes: an object of attribute name → value, checked against the attribute's type: numbers for number and percentage attributes,
true/falsefor yes/no, one of the choices for lists, text otherwise.nullremoves a value. File attributes cannot be set through the API. - Descriptions: plain text, or rich text as HTML. Rich text is cleaned with the same rules as in the app. Answers give the plain text as
description; a single entity's answer also has the stored rich text asdescriptionHtml. - Relationships: only the pairs the schema allows (the class's
relationsin the schema). Relating two entities again returns the existing relationship with"created": false.
What a change also does
Changes run the same follow-ups as in the app:
- A new requirement starts with the status Draft.
- Setting a requirement's Status records who set it and when, as on the Quality and Approvals pages.
- Changing a requirement's name or description marks its downstream links suspect (decomposed by, derived by, refined by, satisfied by, verified by, traced to), marks stored quality results stale, and sends an Approved requirement back to In Review. Changing Priority, Criticality, a verification attribute or a number also marks the links suspect.
- Locked entities refuse changes (
409 locked); unlock them in the app.
MCP reference
The endpoint https://app.holarch.app/mcp speaks the Model Context Protocol over Streamable HTTP (protocol versions 2025-03-26 and 2025-06-18) with the same tokens. It answers each request with JSON; it has no event stream and no sessions.
| Tool | Access | What it does |
|---|---|---|
list_projects | Read | Your projects and roles |
get_project | Read | A project's summary |
get_schema | Read | Classes, attributes, relations and labels |
search_entities | Read | Search by class, label and text |
get_entity | Read | One entity with its relationships |
list_documents | Read | The project's documents |
get_document | Read | A document's sections in order |
run_model_checks | Read | Model Checks, optionally for one class or rule |
quality_check | Read | The requirement quality check |
get_proposal | Read | The open proposal, or one by id, with its status and changes |
list_proposals | Read | Your recent proposals and their status |
create_entity | Read and write | Propose an entity, optionally with relationships; returns a reference such as new:1 |
update_entity | Read and write | Propose a change of an entity |
relate | Read and write | Propose a relationship (ends can be new:<n>) |
unrelate | Read and write | Propose removing a relationship |
delete_entity | Read and write | Propose moving an entity to the Trash |
propose_changes | Read and write | Send the proposal for review, with a title and summary |
discard_proposal | Read and write | Drop the open proposal before it is sent |
A read-only token lists only the read tools. A refused change (no access, unknown class, a relationship the schema does not allow) comes back as a tool result with the app's message, so the AI tool can explain it.
Proposals from AI clients
AI clients never change a project directly. Their write tools collect changes in one open proposal per token and project; nothing in the project changes. propose_changes sends it for review with a title and summary.
- Who reviews: the token's owner and the project's owners. They get a notification (“Name's AI client proposes changes: title”), and the open project shows the proposal in the ✦ AI ▾ menu as Review “title”….
- The review dialog: every change with a checkbox: creations with editable Name, Number and Description, changes with the current and the proposed values (text as a word diff), relationships, deletions. A warning names the AI client's account and token. Deletions, removed relationships and changes to approved, baselined or locked items start unticked.
- Apply Selected applies the ticked changes as one undo step, with your name in the history, and the usual follow-ups (suspect links, approvals). Changes whose items were deleted since are skipped with a note. Reject discards the proposal; Later keeps it waiting.
- Permissions: applying needs the editor or owner role when you apply; viewers and reviewers can only reject. Plan limits and locks apply as for any edit.
- Expiry and retention: a proposal expires 7 days after it was started. Applied, rejected and expired proposals are deleted 30 days later. The AI client sees its status (open, ready, applied, rejected, expired) with
get_proposalandlist_proposals.
Organizations
Org admins turn API access on or off under Organization Settings (site admins: Admin → Organizations) with Allow API and MCP access to this organization's projects. Off refuses every API and MCP request for the organization's projects, also with members' own tokens. The change is recorded in the audit log. See Administration.
Limits
- 600 requests a minute and 120 changes a minute per token; over that, the answer is
429withRetry-After. - Request bodies up to 1 MB; up to 500 entities per page, 5,000 Model Checks findings per page.
- Plan limits apply as in the app: a change that adds items over the project's limit is refused with
403 plan-limit. - Not available yet: creating, renaming or sharing projects, diagrams, comments, attachments, baselines, webhooks and sign-in with OAuth for third-party apps. The desktop version has no API.
Messages
| Code | Status | Meaning |
|---|---|---|
token-required | 401 | No Authorization: Bearer header |
token-invalid | 401 | The token is wrong, revoked or expired, or its account cannot sign in |
read-only-token | 403 | A change with a read-only token |
forbidden | 403 | Your role in the project does not allow the change |
org-policy | 403 | The project's organization turned API access off |
plan-limit | 403 | The change would go over the project's item limit |
not-found | 404 | No such project (or not yours), entity, relationship or document |
locked | 409 | The entity is locked |
rate-limited | 429 | Too many requests; wait the seconds in Retry-After |
bad-request, unknown-class, unknown-attribute, bad-value, bad-relation | 400 | The request names something the project does not have, or a value of the wrong type |
Related pages
Last updated October 10, 2026