On this page
Developer documentation
BIMRelay MCP server
Let compatible AI assistants read approved BIMRelay projects, search COBie 2.4 workbook rows, summarize Issues and Asset review recommendations, edit cells, and manage manual rows and individual exclusions with your permission through the Model Context Protocol (MCP).
Ask an assistant to find the pumps in a workbook, summarize its open Issues, or explain its Asset review recommendations, and it answers from your BIMRelay data. It sees only the projects you approve, within your current BIMRelay membership.
Start with the setup guide for Claude or OpenAI ChatGPT. For other clients that accept a bearer token, use Connect with a token.
- Server URL
https://api.bimrelay.com/mcp- Transport
- Streamable HTTP, stateless, JSON responses
- Authentication
- Bearer token: a personal MCP token or OAuth with PKCE
- Tools
- 21 tools, filtered by the permissions you grant
You stay in control. MCP connections are limited to approved projects and checked against your current membership on every call. Editing is off by default; separate permissions allow cell edits, manual rows and individual generated-row exclusions. They cannot change other settings, start an extraction or review, or create an export.
An AI assistant's provider receives the project data the assistant reads. Choose a provider whose privacy and retention terms suit your organization. For scripts and applications, use the BIMRelay REST API.
Set up Claude
Connect from Claude on the web or Claude Desktop, then sign in with your own BIMRelay account.
https://api.bimrelay.com/mcpc3MrC9gCAradPUVcf0FaZtAwpwadbKDcFMmlCSIcCOMLeave the Client secret field empty.
- Add BIMRelay in Claude. Open Customize → Connectors → Add custom connector. Enter BIMRelay as the name and the server URL above. On Team or Enterprise, ask an owner to add it in Organization settings → Connectors first.
- Choose sign-in. Select Sign in now and Use your own OAuth client. Paste the client ID above and leave the client secret empty. If the dialog has a single screen, these fields are under Advanced settings.
- Connect your account. Finish adding the connector and select Connect if prompted. Sign in to BIMRelay, review the requested permissions, select the projects Claude may access and approve the connection.
- Use it in a chat. Open a new conversation, select + → Connectors and enable BIMRelay. Try the prompt below.
Use BIMRelay to list up to 5 projects I can access.The client ID is public and shared by all BIMRelay users connecting through Claude. It grants no access by itself; your sign-in and approval determine which projects Claude can read. If Claude asks to register a client automatically, choose Use your own OAuth client instead.
Menu labels can vary by account. See Claude’s official custom-connector instructions.
Set up OpenAI ChatGPT
Use ChatGPT on the web with permission to add custom MCP plugins. Your workspace administrator may need to enable or add the plugin for you.
https://api.bimrelay.com/mcpdPawbcmQcQEmLdX5BW4ynDRSBa3NUA4Ep7p_WtjMQ-gLeave the Client secret field empty.
- Add BIMRelay in ChatGPT. Open ChatGPT Plugins, select +, then Add custom MCP server. Enter BIMRelay as the name and the server URL above.
- Choose OAuth. Paste the client ID above in the OAuth settings and leave the client secret empty. Use this client ID rather than automatic client registration. Do not paste a personal API token into either field.
- Create and connect. Review ChatGPT’s connection warning, then select Create as a plugin. Install BIMRelay from your personal plugins. When asked to connect, sign in to BIMRelay, review the requested permissions, select the projects ChatGPT may access and approve the connection.
- Use it in a chat. Start a new conversation, type @ and select BIMRelay. Try the prompt below.
Use BIMRelay to list up to 5 projects I can access.ChatGPT connects through OAuth, so this setup does not need a personal API token or an OpenAI API key. If you cannot add a custom MCP server, check your workspace permissions.
The client ID is public and shared by all BIMRelay users connecting through ChatGPT. It grants no access by itself; your sign-in and approval determine which projects ChatGPT can read.
Connect with a token
Use a personal MCP token with a client that accepts a custom bearer-token header. For Claude or ChatGPT, follow the sign-in setup guides above instead.
- In BIMRelay, open your profile menu and choose Integrations, or go to app.bimrelay.com/integrations. Select Create API token.
- Name the token and set Use with to MCP. Choose the permissions, the projects the assistant may access and an expiry, then select Create token.
- Copy the token. It is shown only once.
- In your client’s settings for remote MCP servers, add BIMRelay with these connection details:
Server URL: https://api.bimrelay.com/mcp
Transport: Streamable HTTP
Header: Authorization: Bearer <your MCP token>To confirm the connection, ask the assistant which BIMRelay projects it can access. It should list the projects you selected.
Client requirements
Your client must support remote MCP servers over Streamable HTTP and let you set a custom Authorization header, or support the OAuth flow. Configuration formats differ between clients, so follow your client’s instructions for adding a remote server. Store the token in the client’s secure settings or an environment variable, never in prompts, chat messages or shared configuration files.
Choose permissions
The assistant sees only the tools its permissions allow. To explore workbooks, select Workspace and project names and details (projects:read) and Workbook sheets and rows (workbooks:read). Add Issues and Asset review recommendations (reviews:read) or Existing exports and download links (exports:read) only when the assistant needs them.
MCP tokens follow the same rules as REST API tokens. They expire after 7, 30 or 90 days, include up to 100 selected projects and stop working as soon as you revoke them in Integrations. Projects created later are not added to an existing token. REST API tokens do not work with the MCP server.
Connect with OAuth
MCP clients that support OAuth can connect without a copied token. The user signs in to BIMRelay, chooses projects and approves the requested access, and the client receives short-lived tokens for the MCP server.
The Claude and ChatGPT guides above include their public client IDs. Other OAuth clients must be registered with BIMRelay; email support@bimrelay.com with the client name and exact callback URLs. BIMRelay does not support dynamic client registration.
| Item | Value |
|---|---|
| Protected resource metadata | https://api.bimrelay.com/.well-known/oauth-protected-resource/mcp |
| Authorization server metadata | https://api.bimrelay.com/.well-known/oauth-authorization-server |
| Resource indicator | https://api.bimrelay.com/mcp |
A request without a valid token receives 401 with a WWW-Authenticate header that points to the protected resource metadata, so clients can discover the authorization server automatically.
The initial sign-in challenge requests read permissions. Editing requires an explicitly requested write permission and a new approval in BIMRelay.
The flow is the same as the REST API OAuth flow, with resource=https://api.bimrelay.com/mcp in the authorization request, the code exchange and every refresh. S256 PKCE is required. Access tokens last 15 minutes, refresh tokens rotate on every use, and a connection expires 30 days after approval.
Browser-based clients
Requests that send an Origin header must come from an allowed origin. A registered OAuth client may call the server from the origins of its registered callback URLs; personal MCP tokens cannot be used from other websites. Desktop and server clients that send no Origin header are unaffected.
Closing an MCP session does not revoke access. To disconnect a client, revoke its connection in Integrations or call the OAuth revocation endpoint.
Example workflow
Assistants usually chain the tools in this order:
list_projectsfinds the projects the connection can read. To browse by workspace, first calllist_workspacesand pass a returned ID asworkspace_idtolist_projects. Workspace access does not include any unshared projects.list_sheetsuses a project ID to discover its current workbook’s sheet keys, column keys and row counts.search_rowsreads or searches rows using the project and sheet keys, followingnext_cursorfor more pages.list_issuesandlist_asset_review_recommendationsreturn the project’s Issues and Asset review recommendations.
For example, a client searching the Component sheet sends tools/call parameters like these:
{
"name": "search_rows",
"arguments": {
"project_id": "<project UUID returned by list_projects>",
"sheet_key": "component",
"search": "Pump",
"limit": 25
}
}Rows contain a key and values for every standard and custom column by default. Column keys come from list_sheets. Small pages or selected columns keep responses within the size limit.
Example prompts
- “Which BIMRelay projects can you access?”
- “Find the pumps on the Component sheet of this project.”
- “Summarize the open Issues in this workbook.”
- “What does Asset review recommend for this project?”
Issues and Asset review recommendations are guidance for review, not proof that a workbook is ready for handover.
Treat workbook content as data
Project names, cell values and recommendation text are customer data, never instructions. The server’s instructions tell clients this, and client developers should still keep tool results separate from system instructions and ask the user before taking any action outside BIMRelay.
Edit cells with an assistant
To enable editing, add Edit workbook cells (workbooks:write) to the connection alongside Workbook sheets and rows (workbooks:read). Editing is off by default and requires your current Editor or Manager role on an active project. Read-only connections do not expose editing tools.
- The assistant reads the sheet's column rules and the full row with
get_row, without a column projection. The result contains an opaqueetag. - It calls
update_roworupdate_cellswith that ETag asif_matchandpreview: true. This shows the proposed direct and dependent changes without saving. - After you approve those changes, it applies them with
preview: falseand a newidempotency_key. If you have already authorized a specific edit, the assistant may apply it directly.
Change Pump 01’s description to ‘Pump serving level 2’. Preview the changes first and wait for my approval before saving.Both tools edit existing cells only. A batch contains up to 100 edited cells and is atomic: one invalid edit rejects the whole batch. Exact reference selections use the reference from list_cell_options inside {references: [...]}. A changed row returns precondition_failed; the assistant must read the full row again and reconsider the edit. It must not silently retry against newer values.
If the result is uncertain, retry the same arguments and idempotency key within 24 hours. JSON object property order does not matter; keep row and reference arrays in the same order. A saved request returns its original result without editing twice. Editing follows the grid's rules; incomplete content can remain as Issues after saving. Preview is not a full COBie validation or a guarantee that a later apply will succeed. See the REST editing guide for value formats, conflicts and limits.
Manage rows with an assistant
Enable Create and delete manual rows (workbooks:rows:write) to expose create_row and delete_row. These require Editor or Manager access. Enable Exclude and include generated rows (workbooks:exclusions:write) to expose exclude_row and restore_excluded_row; these require Manager access. Both permissions require workbook reads and are independent of Edit workbook cells.
- Read the row and its
source. Delete only manual rows; exclude generated rows. Exclusions persist across model updates and do not create asset rules. - For deletion or exclusion, read the full row ETag and pass it as
if_match. Preview usingpreview: true. Explain the effect counts and dependency choices before applying unless the action is already authorized. - For Type or Space exclusions, explicitly choose what happens to their Components. For Contact deletion, choose whether references are cleared or reassigned. Never guess a destructive dependency choice.
- Apply with a fresh
idempotency_key. Retry uncertain results with the same key and arguments within 24 hours. A changed ETag requires reading again and reconsidering the action.
list_exclusions is available with workbook reads and finds exclusions from both the app and integrations. Use its exclusion ID and ETag with restore_excluded_row. After applying, wait until get_workbook reports updating: false, then read again. Including again removes the exclusion; it does not override other selection rules or recreate a missing model source.
create_row accepts standard and custom column values with the same cell formats as editing. A creation preview has a temporary row key, so later calls must use the actual saved result. All actions share atomicity, browser-lock checks, bounded cascades and durable retries. See Manage worksheet rows for the full behavior and limits.
Protocol details
BIMRelay implements the MCP Streamable HTTP transport in stateless mode. Most users can rely on their client; these details help when you build or debug one.
| Item | Value |
|---|---|
| Endpoint | POST https://api.bimrelay.com/mcp |
| Messages | JSON-RPC 2.0 with Content-Type: application/json |
| Accept header | application/json, text/event-stream |
| Responses | JSON. The server does not open event streams. |
| Sessions | Stateless. No session ID is required. |
| Capabilities | Tools only. No prompts, resources or subscriptions. |
| Request size | Up to 64 KiB |
| Response size | Up to 1 MiB, counting both text and structured content |
- Initialize, send
notifications/initialized, calltools/list, then call tools withtools/call. Send the negotiatedMCP-Protocol-Versionheader and the Bearer token with every request. GETreturns405 Method Not Allowedbecause the server does not stream events. Configure BIMRelay as a Streamable HTTP server, not a legacy HTTP+SSE server.DELETEis acknowledged, but it does not revoke the token.
Tools and results
Every tool declares input and output schemas. Read tools are annotated as read-only and non-destructive; editing tools are marked as writes and potentially destructive. All tools are idempotent: saved edits require an idempotency key. tools/list includes only the tools the connection’s permissions allow; calling a hidden tool returns an insufficient_scope tool error.
Successful results return the same JSON twice: as text content and as structuredContent. Prefer structuredContent when your client supports it. Its shape matches the REST API response for the same operation.
Errors
- Tool failures return a result with
isError: true. The text is usually a JSON object with the samecodeandmessagevalues as the REST API, such asinvalid_columnorread_busy. Unavailable or unauthorized resources return “The requested resource is unavailable”. - Authentication, rate-limit and origin failures are rejected before MCP processing, with an HTTP error status and the REST error body, such as
401 invalid_tokenor429 rate_limited. - A result that would exceed 1 MiB fails with a
response_too_largetool error or a JSON-RPC error. Request fewer rows or columns.
Limits and troubleshooting
The MCP server shares the REST API’s limits:
- Free workspaces share 20 API requests and MCP tool calls combined per calendar month (UTC) across all members and connections. Each authorized tool call counts, including pages, previews, failed operations and retries. Authentication, request-schema, scope and project/workspace-access failures do not count. Paid workspaces have no monthly request cap.
- A call with a project or workspace target counts only against that workspace. Calls without either target count once in every accessible workspace granted to the connection. OAuth, initialization and
tools/listdo not use the monthly allowance. Check usage in Integrations; it resets at 00:00 UTC on the first of each month. - Lists return 100 records by default and allow 1–200. Cell options use fixed 100-item pages. For assistants, 25–50 rows with selected columns usually work best. Responses are limited to 1 MiB including both text and structured content, so MCP pages may need to be smaller than REST pages.
- Row reads return all columns by default, including custom columns, with a limit of 20,000 cells (rows × columns). An explicit column selection allows up to 100 keys. Schema reads allow up to 200 sheets and 5,000 columns. Request bodies are limited to 64 KiB.
- Each user can make 120 requests per minute across all of their REST and MCP connections, and only one operation runs at a time. Call tools one after another, not in parallel.
- Saved edit results are retained for 24 hours, up to 10,000 requests or 32 MiB per user across all connections. At capacity, new edits return
idempotency_capacity_exceededuntil older results expire. Saved retries and previews remain available. - Each operation has five seconds of processing time. If a call times out, narrow the search or filters.
- Cursors expire after 15 minutes and are bound to the connection, tool, project, sheet, search, filters and columns. Keep those unchanged between pages.
- Tools read the current workbook only, and collaborators can change values between pages. If a rebuild causes a
workbook_changederror, restart the call without a cursor.
Troubleshooting
| Problem | What to check |
|---|---|
HTTP 401 or authentication failed | The token may be expired, revoked or created for the REST API. Create an MCP token or reconnect through OAuth. BIMRelay browser sessions cannot be used. |
HTTP 403 forbidden_origin | The request came from a browser origin that is not allowed. Browser-based clients must use a registered OAuth client’s callback origin. |
A tool is missing, or returns insufficient_scope | The connection lacks the matching permission. Create a token or approve a connection that includes it. |
| No projects, or “The requested resource is unavailable” | Check that the project was selected for the connection and that you are still a member. Asset review findings are unavailable when the workspace has turned off Asset review. |
response_too_large or query_timeout | Lower limit, select fewer columns, or narrow the search and filters. |
rate_limited or read_busy | Make one call at a time and wait before retrying. |
monthly_quota_exceeded | The free workspace has used its 20 monthly requests. Upgrade or wait until details.resets_at; do not keep retrying. The tool error also identifies workspace_id, limit and used in details. |
| The client cannot connect or asks for client registration | Use a client that supports Streamable HTTP with a custom Authorization header, or one that accepts a preconfigured OAuth client ID. |
Export download links expire after five minutes and remain valid until then even if the connection is revoked, so keep them private. When you contact support, include the error code and any request ID, never a token or private workbook content.
Tool reference
The server provides 21 tools. Their arguments and results come from the same contract as the REST API endpoints, and each result’s structuredContent matches the corresponding REST response. Project and export IDs are UUIDs returned by earlier calls. Workbook tools operate on the current workbook. Editing tools appear only with explicit write permission.
Check the token's user, permissions and expiry.
No arguments.
Example call
{
"name": "get_connection",
"arguments": {}
}Example result
{
"user": {
"id": "00000000-0000-4000-8000-000000000008",
"name": "Alex Example"
},
"scopes": [
"projects:read",
"workbooks:read"
],
"expires_at": "2026-11-06T12:00:00Z"
}Result schema
{
"type": "object",
"properties": {
"user": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"additionalProperties": false
},
"scopes": {
"type": "array",
"items": {
"type": "string"
}
},
"expires_at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"user",
"scopes",
"expires_at"
],
"additionalProperties": false
}List workspaces containing projects this connection can currently read.
Only workspace IDs and names are returned. Seeing a workspace does not grant access to its other projects.
| Name | Type | Description |
|---|---|---|
limit | integer | Page size. Defaults to 100; allowed range 1–200. |
cursor | string | Opaque next_cursor from the previous result. Keep the other arguments unchanged. |
Example call
{
"name": "list_workspaces",
"arguments": {
"limit": 20
}
}Example result
{
"data": [
{
"id": "00000000-0000-4000-8000-000000000002",
"name": "Example workspace"
}
],
"next_cursor": null
}Result schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"additionalProperties": false
}
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}Read the name of a workspace containing an accessible project.
| Name | Type | Description |
|---|---|---|
workspace_idRequired | UUID | Workspace ID returned by list_workspaces. On list_projects, restricts results to approved projects in that workspace. |
Example call
{
"name": "get_workspace",
"arguments": {
"workspace_id": "00000000-0000-4000-8000-000000000002"
}
}Example result
{
"id": "00000000-0000-4000-8000-000000000002",
"name": "Example workspace"
}Result schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"id",
"name"
],
"additionalProperties": false
}List the approved projects you can currently access.
Optionally pass workspace_id to list only approved projects in that workspace. An unavailable workspace returns 404; the filter never broadens project access.
| Name | Type | Description |
|---|---|---|
limit | integer | Page size. Defaults to 100; allowed range 1–200. |
cursor | string | Opaque next_cursor from the previous result. Keep the other arguments unchanged. |
workspace_id | UUID | Workspace ID returned by list_workspaces. On list_projects, restricts results to approved projects in that workspace. |
Example call
{
"name": "list_projects",
"arguments": {
"limit": 20
}
}Example result
{
"data": [
{
"id": "00000000-0000-4000-8000-000000000001",
"workspace_id": "00000000-0000-4000-8000-000000000002",
"name": "Example project",
"status": "active",
"description": "Facilities handover for the civic center.",
"classification_system": "omniclass"
}
],
"next_cursor": null
}Result schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": [
"string",
"null"
]
},
"classification_system": {
"type": "string",
"enum": [
"omniclass",
"uniclass"
]
},
"status": {
"type": "string"
}
},
"required": [
"id",
"workspace_id",
"name",
"description",
"classification_system",
"status"
],
"additionalProperties": false
}
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}Read the details of one approved project.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
Example call
{
"name": "get_project",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001"
}
}Example result
{
"id": "00000000-0000-4000-8000-000000000001",
"workspace_id": "00000000-0000-4000-8000-000000000002",
"name": "Example project",
"status": "active",
"description": "Facilities handover for the civic center.",
"classification_system": "omniclass"
}Result schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": [
"string",
"null"
]
},
"classification_system": {
"type": "string",
"enum": [
"omniclass",
"uniclass"
]
},
"status": {
"type": "string"
}
},
"required": [
"id",
"workspace_id",
"name",
"description",
"classification_system",
"status"
],
"additionalProperties": false
}Read the status of the current workbook for a project.
Check whether the project’s workbook is updating. Use project_id for all workbook reads.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
Example call
{
"name": "get_workbook",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001"
}
}Example result
{
"project_id": "00000000-0000-4000-8000-000000000001",
"updating": false,
"latest_version_number": 2
}Result schema
{
"type": "object",
"properties": {
"project_id": {
"type": "string"
},
"updating": {
"type": "boolean"
},
"latest_version_number": {
"type": [
"integer",
"null"
],
"minimum": 1
}
},
"required": [
"project_id",
"updating",
"latest_version_number"
],
"additionalProperties": false
}Discover current worksheet keys, column keys and row counts, including custom columns.
row_count is the full sheet count, not the count after a search. Use the returned keys in subsequent requests.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
Example call
{
"name": "list_sheets",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001"
}
}Example result
{
"sheets": [
{
"key": "component",
"name": "Component",
"row_count": 25,
"columns": [
{
"key": "name",
"name": "Name",
"data_type": "string",
"required": true,
"editing": {
"kind": "value",
"allow_custom_value": true
}
},
{
"key": "maintenance_priority",
"name": "Maintenance Priority",
"data_type": "string",
"required": false,
"editing": {
"kind": "value",
"allow_custom_value": true
}
}
]
}
]
}Result schema
{
"type": "object",
"properties": {
"sheets": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
},
"row_count": {
"type": "integer",
"minimum": 0
},
"columns": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
},
"data_type": {
"type": "string"
},
"required": {
"type": "boolean"
},
"editing": {
"type": "object",
"properties": {
"kind": {
"type": "string",
"enum": [
"value",
"choice",
"reference"
]
},
"allow_custom_value": {
"type": "boolean"
},
"multiple": {
"type": "boolean"
},
"target_sheet": {
"type": [
"string",
"null"
]
},
"target_column": {
"type": [
"string",
"null"
]
},
"depends_on": {
"type": "string"
}
},
"required": [
"kind",
"allow_custom_value"
],
"additionalProperties": false
}
},
"required": [
"key",
"name",
"data_type",
"required",
"editing"
],
"additionalProperties": false
}
}
},
"required": [
"key",
"name",
"row_count",
"columns"
],
"additionalProperties": false
}
}
},
"required": [
"sheets"
],
"additionalProperties": false
}Read current worksheet rows, with optional search, filters and selected columns.
Search matches cell values across the sheet, including columns omitted from the response. Multiple exact filters are combined with AND.
| Name | Type | Description |
|---|---|---|
limit | integer | Page size. Defaults to 100; allowed range 1–200. |
cursor | string | Opaque next_cursor from the previous result. Keep the other arguments unchanged. |
search | string | Case-insensitive substring search across cell values. Up to 200 characters. |
columns | array of strings | Column keys to return, up to 100 keys. Omit for all columns, including custom columns. Row reads are limited to 20,000 cells. An empty array is not allowed. |
filters | object | Exact, case-sensitive values keyed by column key, such as {"name": "Pump 01"}. Up to 20 filters, combined with AND. An empty string matches an empty value, not null. |
project_idRequired | UUID | Project ID returned by list_projects. |
sheet_keyRequired | string | Sheet key returned by list_sheets, such as component. |
Example call
{
"name": "search_rows",
"arguments": {
"sheet_key": "component",
"search": "Pump",
"limit": 25,
"project_id": "00000000-0000-4000-8000-000000000001"
}
}Example result
{
"data": [
{
"values": {
"name": "Pump 01",
"maintenance_priority": "High"
},
"key": "component:example",
"source": "generated"
}
],
"next_cursor": null
}Result schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"source": {
"type": "string",
"enum": [
"manual",
"generated"
]
},
"values": {
"type": "object",
"additionalProperties": {
"type": [
"string",
"null"
]
}
}
},
"required": [
"key",
"source",
"values"
],
"additionalProperties": false
}
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}Add a user-created row with standard or custom column values.
Requires workbooks:rows:write and workbooks:read, plus an Editor or Manager role. Pass initial column values in values and idempotency_key as a tool argument when saving. Set preview: true to inspect a temporary row without saving; no ETag is needed for creation. Read the new row before making another change.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
sheet_keyRequired | string | Sheet key returned by list_sheets, such as component. |
valuesRequired | object | Column keys mapped to strings, null to clear, or {references: [{sheet_key, row_key}]} for exact reference selections. |
preview | boolean | Set true to inspect direct and dependent changes without saving. Defaults to false. |
idempotency_key | string | Unique request key, up to 128 characters. Required to save. Reuse with identical arguments for retries within 24 hours. |
Example call
{
"name": "create_row",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001",
"sheet_key": "component",
"idempotency_key": "example-create-001",
"values": {
"name": "Additional pump",
"maintenance_priority": "High"
}
}
}Example result
{
"applied": true,
"row": {
"key": "manual:00000000-0000-4000-8000-000000000006",
"source": "manual",
"values": {
"name": "Additional pump",
"maintenance_priority": "High"
}
},
"etag": "\"br-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"",
"affected": {
"rows_created": 1,
"rows_removed": 0,
"cells_updated": 2
},
"validation_pending": true
}Result schema
{
"type": "object",
"properties": {
"applied": {
"type": "boolean"
},
"row": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"source": {
"type": "string",
"enum": [
"manual",
"generated"
]
},
"values": {
"type": "object",
"additionalProperties": {
"type": [
"string",
"null"
]
}
}
},
"required": [
"key",
"source",
"values"
],
"additionalProperties": false
},
"etag": {
"type": "string"
},
"affected": {
"type": "object",
"properties": {
"rows_created": {
"type": "integer",
"minimum": 0
},
"rows_removed": {
"type": "integer",
"minimum": 0
},
"cells_updated": {
"type": "integer",
"minimum": 0
}
},
"required": [
"rows_created",
"rows_removed",
"cells_updated"
],
"additionalProperties": false
},
"validation_pending": {
"type": "boolean"
}
},
"required": [
"applied",
"row",
"etag",
"affected",
"validation_pending"
],
"additionalProperties": false
}Read one current row using its key, not its displayed Name.
Pass the key returned by search_rows unchanged as row_key, together with the same project_id and sheet_key.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
sheet_keyRequired | string | Sheet key returned by list_sheets, such as component. |
row_keyRequired | string | The row’s key, exactly as returned by search_rows. |
columns | array of strings | Column keys to return, up to 100 keys. Omit for all columns, including custom columns. Row reads are limited to 20,000 cells. An empty array is not allowed. |
Example call
{
"name": "get_row",
"arguments": {
"sheet_key": "component",
"row_key": "component:example",
"project_id": "00000000-0000-4000-8000-000000000001"
}
}Example result
{
"row": {
"values": {
"name": "Pump 01",
"maintenance_priority": "High"
},
"key": "component:example",
"source": "generated"
},
"etag": "\"br-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""
}Result schema
{
"type": "object",
"properties": {
"row": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"source": {
"type": "string",
"enum": [
"manual",
"generated"
]
},
"values": {
"type": "object",
"additionalProperties": {
"type": [
"string",
"null"
]
}
}
},
"required": [
"key",
"source",
"values"
],
"additionalProperties": false
},
"etag": {
"type": "string"
}
},
"required": [
"row",
"etag"
],
"additionalProperties": false
}Update existing cells in one row atomically. Only supplied columns change; null clears a value.
Requires workbooks:write and workbooks:read, plus an Editor or Manager role on an active project. Pass if_match and idempotency_key as tool arguments. Set preview: true to evaluate the same changes without saving. Preview still needs if_match but no idempotency key. Validation runs after saving; validation_pending does not mean the edit failed.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
sheet_keyRequired | string | Sheet key returned by list_sheets, such as component. |
row_keyRequired | string | The row’s key, exactly as returned by search_rows. |
if_match | string | Exact etag from get_row without a column projection, or list_exclusions when including again. Required for destructive previews and application. |
valuesRequired | object | Column keys mapped to strings, null to clear, or {references: [{sheet_key, row_key}]} for exact reference selections. |
preview | boolean | Set true to inspect direct and dependent changes without saving. Defaults to false. |
idempotency_key | string | Unique request key, up to 128 characters. Required to save. Reuse with identical arguments for retries within 24 hours. |
Example call
{
"name": "update_row",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001",
"sheet_key": "component",
"row_key": "component:example",
"if_match": "\"br-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"",
"idempotency_key": "example-edit-001",
"values": {
"description": "Circulation pump serving level 2"
}
}
}Example result
{
"applied": true,
"changes": [
{
"sheet_key": "component",
"row_key": "component:example",
"column_key": "description",
"old_value": "Circulation pump",
"value": "Circulation pump serving level 2",
"requested": true
}
],
"rows": [
{
"sheet_key": "component",
"row_key": "component:example",
"etag": "\"br-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\""
}
],
"validation_pending": true
}Result schema
{
"type": "object",
"properties": {
"applied": {
"type": "boolean"
},
"changes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"sheet_key": {
"type": "string"
},
"row_key": {
"type": "string"
},
"column_key": {
"type": "string"
},
"old_value": {
"type": [
"string",
"null"
]
},
"value": {
"type": [
"string",
"null"
]
},
"requested": {
"type": "boolean"
}
},
"required": [
"sheet_key",
"row_key",
"column_key",
"old_value",
"value",
"requested"
],
"additionalProperties": false
}
},
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"sheet_key": {
"type": "string"
},
"row_key": {
"type": "string"
},
"etag": {
"type": "string"
}
},
"required": [
"sheet_key",
"row_key",
"etag"
],
"additionalProperties": false
}
},
"validation_pending": {
"type": "boolean"
}
},
"required": [
"applied",
"changes",
"rows",
"validation_pending"
],
"additionalProperties": false
}Delete a user-created row and settle references to it. Generated rows must be excluded instead.
Deletes manual rows only. Pass the full-row ETag as if_match and idempotency_key as tool arguments. Set preview: true without an idempotency key to inspect the impact first. For Contacts, explicitly choose reference_action: clear, or reassign with replacement_row_key. Generated rows must use exclude_row instead.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
sheet_keyRequired | string | Sheet key returned by list_sheets, such as component. |
row_keyRequired | string | The row’s key, exactly as returned by search_rows. |
if_match | string | Exact etag from get_row without a column projection, or list_exclusions when including again. Required for destructive previews and application. |
reference_action | string | For Contact deletion, explicitly choose clear or reassign.Allowed: clear, reassign |
replacement_row_key | string | Same-sheet replacement row key, required with reassign. Type and Space replacements must be generated rows. |
preview | boolean | Set true to inspect direct and dependent changes without saving. Defaults to false. |
idempotency_key | string | Unique request key, up to 128 characters. Required to save. Reuse with identical arguments for retries within 24 hours. |
Example call
{
"name": "delete_row",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001",
"sheet_key": "component",
"row_key": "manual:00000000-0000-4000-8000-000000000006",
"if_match": "\"br-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"",
"idempotency_key": "example-delete-001"
}
}Example result
{
"applied": true,
"affected": {
"rows_created": 0,
"rows_removed": 1,
"cells_updated": 0
},
"validation_pending": true
}Result schema
{
"type": "object",
"properties": {
"applied": {
"type": "boolean"
},
"affected": {
"type": "object",
"properties": {
"rows_created": {
"type": "integer",
"minimum": 0
},
"rows_removed": {
"type": "integer",
"minimum": 0
},
"cells_updated": {
"type": "integer",
"minimum": 0
}
},
"required": [
"rows_created",
"rows_removed",
"cells_updated"
],
"additionalProperties": false
},
"validation_pending": {
"type": "boolean"
}
},
"required": [
"applied",
"affected",
"validation_pending"
],
"additionalProperties": false
}Load choices or reference rows for one cell, in pages of 100.
Reference choices include stable row keys so duplicate or comma-containing names can be selected unambiguously. An empty list on a free-text column means there are no suggested choices, not that the cell is uneditable.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
sheet_keyRequired | string | Sheet key returned by list_sheets, such as component. |
row_keyRequired | string | The row’s key, exactly as returned by search_rows. |
column_keyRequired | string | Column key returned by list_sheets. |
search | string | Case-insensitive substring search across cell values. Up to 200 characters. |
cursor | string | Opaque next_cursor from the previous result. Keep the other arguments unchanged. |
Example call
{
"name": "list_cell_options",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001",
"sheet_key": "component",
"row_key": "component:example",
"column_key": "type_name",
"search": "Pump"
}
}Example result
{
"data": [
{
"value": "Circulation Pump",
"reference": {
"sheet_key": "type",
"row_key": "type:circulation-pump"
}
}
],
"next_cursor": null
}Result schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"value": {
"type": "string"
},
"reference": {
"type": "object",
"properties": {
"sheet_key": {
"type": "string"
},
"row_key": {
"type": "string"
}
},
"required": [
"sheet_key",
"row_key"
],
"additionalProperties": false
}
},
"required": [
"value"
],
"additionalProperties": false
}
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}Apply up to 100 cell edits across existing rows. Every edit succeeds or none is saved.
Include each row once with its full-row ETag as if_match and its values. Pass idempotency_key as a tool argument when saving. Set preview: true to inspect direct and dependent changes without saving. Retry an uncertain result with the exact same arguments and idempotency key within 24 hours; a different edit needs a new key.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
preview | boolean | Set true to inspect direct and dependent changes without saving. Defaults to false. |
idempotency_key | string | Unique request key, up to 128 characters. Required to save. Reuse with identical arguments for retries within 24 hours. |
rowsRequired | array of objects | Rows with sheet_key, row_key, if_match and values. Include each row once, up to 100 edited cells across the batch. |
Example call
{
"name": "update_cells",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001",
"idempotency_key": "example-batch-001",
"rows": [
{
"sheet_key": "component",
"row_key": "component:example",
"if_match": "\"br-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"",
"values": {
"description": "Circulation pump serving level 2"
}
}
]
}
}Example result
{
"applied": true,
"changes": [
{
"sheet_key": "component",
"row_key": "component:example",
"column_key": "description",
"old_value": "Circulation pump",
"value": "Circulation pump serving level 2",
"requested": true
}
],
"rows": [
{
"sheet_key": "component",
"row_key": "component:example",
"etag": "\"br-bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\""
}
],
"validation_pending": true
}Result schema
{
"type": "object",
"properties": {
"applied": {
"type": "boolean"
},
"changes": {
"type": "array",
"items": {
"type": "object",
"properties": {
"sheet_key": {
"type": "string"
},
"row_key": {
"type": "string"
},
"column_key": {
"type": "string"
},
"old_value": {
"type": [
"string",
"null"
]
},
"value": {
"type": [
"string",
"null"
]
},
"requested": {
"type": "boolean"
}
},
"required": [
"sheet_key",
"row_key",
"column_key",
"old_value",
"value",
"requested"
],
"additionalProperties": false
}
},
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"sheet_key": {
"type": "string"
},
"row_key": {
"type": "string"
},
"etag": {
"type": "string"
}
},
"required": [
"sheet_key",
"row_key",
"etag"
],
"additionalProperties": false
}
},
"validation_pending": {
"type": "boolean"
}
},
"required": [
"applied",
"changes",
"rows",
"validation_pending"
],
"additionalProperties": false
}Keep this individual model-derived row out of the workbook through future model updates.
Requires workbooks:exclusions:write and workbooks:read, plus a Manager role. Pass the full-row ETag as if_match and idempotency_key as tool arguments. Set preview: true to inspect the affected rows and cells without saving. For Types and Spaces, choose how dependent Components are handled. This creates an individual exclusion, not an asset rule.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
sheet_keyRequired | string | Sheet key returned by list_sheets, such as component. |
row_keyRequired | string | The row’s key, exactly as returned by search_rows. |
if_match | string | Exact etag from get_row without a column projection, or list_exclusions when including again. Required for destructive previews and application. |
component_action | string | Type: exclude, clear_type or reassign. Space: exclude, resolve_space or reassign. Required for Type and Space only.Allowed: exclude, clear_type, resolve_space, reassign |
replacement_row_key | string | Same-sheet replacement row key, required with reassign. Type and Space replacements must be generated rows. |
preview | boolean | Set true to inspect direct and dependent changes without saving. Defaults to false. |
idempotency_key | string | Unique request key, up to 128 characters. Required to save. Reuse with identical arguments for retries within 24 hours. |
Example call
{
"name": "exclude_row",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001",
"sheet_key": "component",
"row_key": "component:example",
"if_match": "\"br-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"",
"idempotency_key": "example-exclude-001"
}
}Example result
{
"applied": true,
"exclusion": {
"id": "00000000-0000-4000-8000-000000000005",
"name": "Pump 01",
"component_action": null,
"replacement_name": null,
"dependent_row_count": 0,
"etag": "\"br-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""
},
"affected": {
"rows_created": 0,
"rows_removed": 1,
"cells_updated": 0
},
"validation_pending": true
}Result schema
{
"type": "object",
"properties": {
"applied": {
"type": "boolean"
},
"exclusion": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"component_action": {
"type": [
"string",
"null"
]
},
"replacement_name": {
"type": [
"string",
"null"
]
},
"dependent_row_count": {
"type": "integer",
"minimum": 0
},
"etag": {
"type": "string"
}
},
"required": [
"id",
"name",
"component_action",
"replacement_name",
"dependent_row_count",
"etag"
],
"additionalProperties": false
},
"affected": {
"type": "object",
"properties": {
"rows_created": {
"type": "integer",
"minimum": 0
},
"rows_removed": {
"type": "integer",
"minimum": 0
},
"cells_updated": {
"type": "integer",
"minimum": 0
}
},
"required": [
"rows_created",
"rows_removed",
"cells_updated"
],
"additionalProperties": false
},
"validation_pending": {
"type": "boolean"
}
},
"required": [
"applied",
"exclusion",
"affected",
"validation_pending"
],
"additionalProperties": false
}Read the individual exclusions shown in the sheet’s Settings, including validators for Include again.
Requires workbooks:read. Exclusion IDs remain usable while an exclusion is active, even after model updates. The list does not include broad asset or parameter selection rules, Floor settings or removed Contact mappings.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
sheet_keyRequired | string | Sheet key returned by list_sheets, such as component. |
limit | integer | Page size. Defaults to 100; allowed range 1–200. |
cursor | string | Opaque next_cursor from the previous result. Keep the other arguments unchanged. |
Example call
{
"name": "list_exclusions",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001",
"sheet_key": "component",
"limit": 25
}
}Example result
{
"data": [
{
"id": "00000000-0000-4000-8000-000000000005",
"name": "Pump 01",
"component_action": null,
"replacement_name": null,
"dependent_row_count": 0,
"etag": "\"br-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\""
}
],
"next_cursor": null
}Result schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"component_action": {
"type": [
"string",
"null"
]
},
"replacement_name": {
"type": [
"string",
"null"
]
},
"dependent_row_count": {
"type": "integer",
"minimum": 0
},
"etag": {
"type": "string"
}
},
"required": [
"id",
"name",
"component_action",
"replacement_name",
"dependent_row_count",
"etag"
],
"additionalProperties": false
}
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}Remove an individual exclusion and schedule the workbook update that can bring its row back.
Use an ID and ETag returned by list_exclusions; pass the ETag as if_match and idempotency_key as tool arguments. Set preview: true to check whether the exclusion can be removed without saving. Applying schedules a workbook update; poll get_workbook until updating is false, then search_rows for the current row. Current model and settings may still prevent the row from appearing.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
sheet_keyRequired | string | Sheet key returned by list_sheets, such as component. |
exclusion_idRequired | UUID | Exclusion ID returned by list_exclusions or exclude_row. |
if_match | string | Exact etag from get_row without a column projection, or list_exclusions when including again. Required for destructive previews and application. |
preview | boolean | Set true to inspect direct and dependent changes without saving. Defaults to false. |
idempotency_key | string | Unique request key, up to 128 characters. Required to save. Reuse with identical arguments for retries within 24 hours. |
Example call
{
"name": "restore_excluded_row",
"arguments": {
"project_id": "00000000-0000-4000-8000-000000000001",
"sheet_key": "component",
"exclusion_id": "00000000-0000-4000-8000-000000000005",
"if_match": "\"br-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"",
"idempotency_key": "example-include-001"
}
}Example result
{
"applied": true,
"exclusion_id": "00000000-0000-4000-8000-000000000005",
"updating": true
}Result schema
{
"type": "object",
"properties": {
"applied": {
"type": "boolean"
},
"exclusion_id": {
"type": "string"
},
"updating": {
"type": "boolean"
}
},
"required": [
"applied",
"exclusion_id",
"updating"
],
"additionalProperties": false
}Read existing validation findings for a workbook.
This endpoint reads existing findings; it does not run validation.
| Name | Type | Description |
|---|---|---|
limit | integer | Page size. Defaults to 100; allowed range 1–200. |
cursor | string | Opaque next_cursor from the previous result. Keep the other arguments unchanged. |
project_idRequired | UUID | Project ID returned by list_projects. |
status | string | Return only findings with this status. Omit for all statuses.Allowed: open, ignored, resolved |
severity | string | Return only findings with this severity. Omit for all severities.Allowed: error, warning |
sheet_key | string | Return findings for one sheet key. |
Example call
{
"name": "list_issues",
"arguments": {
"status": "open",
"limit": 20,
"project_id": "00000000-0000-4000-8000-000000000001"
}
}Example result
{
"data": [
{
"id": "00000000-0000-4000-8000-000000000009",
"code": "missing_value",
"severity": "warning",
"status": "open",
"message": "A value needs review.",
"location": {
"sheet_key": "component",
"row_key": "component:example",
"column_key": "description"
}
}
],
"next_cursor": null
}Result schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"code": {
"type": "string"
},
"severity": {
"type": "string"
},
"status": {
"type": "string"
},
"message": {
"type": "string"
},
"location": {
"type": "object",
"properties": {
"sheet_key": {
"type": [
"string",
"null"
]
},
"row_key": {
"type": [
"string",
"null"
]
},
"column_key": {
"type": [
"string",
"null"
]
}
},
"required": [
"sheet_key",
"row_key",
"column_key"
],
"additionalProperties": false
}
},
"required": [
"id",
"code",
"severity",
"status",
"message",
"location"
],
"additionalProperties": false
}
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}Read existing Asset review recommendations and their affected assets or attributes.
Available only when the workspace allows Asset review. Reading findings does not start a review or change selections.
| Name | Type | Description |
|---|---|---|
limit | integer | Page size. Defaults to 100; allowed range 1–200. |
cursor | string | Opaque next_cursor from the previous result. Keep the other arguments unchanged. |
project_idRequired | UUID | Project ID returned by list_projects. |
status | string | Return only findings with this status. Omit for all statuses.Allowed: open, addressed, ignored, no_longer_flagged |
Example call
{
"name": "list_asset_review_recommendations",
"arguments": {
"status": "open",
"limit": 20,
"project_id": "00000000-0000-4000-8000-000000000001"
}
}Example result
{
"data": [
{
"id": "00000000-0000-4000-8000-000000000010",
"status": "open",
"title": "Consider excluding reference geometry",
"explanation": "Review whether these objects belong in the handover.",
"recommendation": {
"action": "exclude",
"target": "asset"
},
"affected": [
{
"category": "Generic Models",
"family": "Reference Geometry",
"type": "Coordination",
"included_count": 3,
"total_count": 3
}
],
"last_reviewed_at": "2026-10-07T12:00:00Z"
}
],
"next_cursor": null
}Result schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"status": {
"type": "string"
},
"title": {
"type": "string"
},
"explanation": {
"type": "string"
},
"recommendation": {
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"include",
"exclude"
]
},
"target": {
"type": "string",
"enum": [
"asset",
"attribute"
]
}
},
"required": [
"action",
"target"
],
"additionalProperties": false
},
"affected": {
"type": "array",
"items": {
"type": "object",
"properties": {
"category": {
"type": "string"
},
"family": {
"type": "string"
},
"type": {
"type": "string"
},
"parameter": {
"type": "string"
},
"unit": {
"type": "string"
},
"included_count": {
"type": "integer",
"minimum": 0
},
"total_count": {
"type": "integer",
"minimum": 0
}
},
"required": [],
"additionalProperties": false
}
},
"last_reviewed_at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"id",
"status",
"title",
"explanation",
"recommendation",
"affected",
"last_reviewed_at"
],
"additionalProperties": false
}
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}List exports that have already been requested in BIMRelay.
This endpoint lists existing exports; it does not create them.
| Name | Type | Description |
|---|---|---|
limit | integer | Page size. Defaults to 100; allowed range 1–200. |
cursor | string | Opaque next_cursor from the previous result. Keep the other arguments unchanged. |
project_idRequired | UUID | Project ID returned by list_projects. |
Example call
{
"name": "list_exports",
"arguments": {
"limit": 20,
"project_id": "00000000-0000-4000-8000-000000000001"
}
}Example result
{
"data": [
{
"id": "00000000-0000-4000-8000-000000000012",
"status": "completed",
"format": "xlsx",
"created_at": "2026-10-07T12:00:00Z",
"completed_at": "2026-10-07T12:00:00Z"
}
],
"next_cursor": null
}Result schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"status": {
"type": "string"
},
"format": {
"type": "string"
},
"created_at": {
"type": "string",
"format": "date-time"
},
"completed_at": {
"type": [
"string",
"null"
],
"format": "date-time"
}
},
"required": [
"id",
"status",
"format",
"created_at",
"completed_at"
],
"additionalProperties": false
}
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"next_cursor"
],
"additionalProperties": false
}Get a temporary URL for an existing completed Excel export.
Download from the returned URL within five minutes. Treat it as a secret; it remains usable until expiry even if the connection is revoked. An incomplete or failed export returns an export_not_ready error.
| Name | Type | Description |
|---|---|---|
project_idRequired | UUID | Project ID returned by list_projects. |
export_idRequired | UUID | Export ID returned by list_exports. |
Example call
{
"name": "get_export_download",
"arguments": {
"export_id": "00000000-0000-4000-8000-000000000012",
"project_id": "00000000-0000-4000-8000-000000000001"
}
}Example result
{
"url": "https://storage.example.com/example.xlsx?temporary=example",
"expires_at": "2026-10-07T12:05:00Z"
}Result schema
{
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri"
},
"expires_at": {
"type": "string",
"format": "date-time"
}
},
"required": [
"url",
"expires_at"
],
"additionalProperties": false
}