Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 25 additions & 2 deletions api-reference/openapi/research.json
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,16 @@
"format": "uuid"
}
},
{
"name": "account_id",
"in": "query",
"required": false,
"description": "Act on a chat belonging to another account. Only honoured for a key that is authorised for that account — an organization key may pass a member account's id; a personal key passing anyone else's is rejected with `403 Access denied to specified account_id`. Omit it to act as the authenticated account.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The new account_id parameter documents the 403 override-authorization behavior, but the existing 403/400 error response descriptions aren't updated to mention malformed account_id or bearer-token limitations for account overrides. Consider cross-referencing these error responses so the contract fully reflects the new account_id semantics.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At api-reference/openapi/research.json, line 793:

<comment>The new account_id parameter documents the 403 override-authorization behavior, but the existing 403/400 error response descriptions aren't updated to mention malformed account_id or bearer-token limitations for account overrides. Consider cross-referencing these error responses so the contract fully reflects the new account_id semantics.</comment>

<file context>
@@ -786,6 +786,16 @@
+            "name": "account_id",
+            "in": "query",
+            "required": false,
+            "description": "Act on a chat belonging to another account. Only honoured for a key that is authorised for that account — an organization key may pass a member account's id; a personal key passing anyone else's is rejected with `403 Access denied to specified account_id`. Omit it to act as the authenticated account.",
+            "schema": {
+              "type": "string",
</file context>

"schema": {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3: The x-workflow-stream-tail-index header is documented as a zero-based index, but its schema only declares "type": "integer" without a "minimum": 0 constraint, so the OpenAPI contract technically allows negative values.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At api-reference/openapi/research.json, line 794:

<comment>The x-workflow-stream-tail-index header is documented as a zero-based index, but its schema only declares `"type": "integer"` without a `"minimum": 0` constraint, so the OpenAPI contract technically allows negative values.</comment>

<file context>
@@ -786,6 +786,16 @@
+            "in": "query",
+            "required": false,
+            "description": "Act on a chat belonging to another account. Only honoured for a key that is authorised for that account — an organization key may pass a member account's id; a personal key passing anyone else's is rejected with `403 Access denied to specified account_id`. Omit it to act as the authenticated account.",
+            "schema": {
+              "type": "string",
+              "format": "uuid"
</file context>

"type": "string",
"format": "uuid"
}
},
Comment on lines +789 to +798

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the referenced OpenAPI segment and nearby responses/descriptions.
sed -n '730,890p' api-reference/openapi/research.json

echo '--- search account_id occurrences ---'
rg -n '"account_id"|account_id|Access denied to specified account_id|Invalid startIndex|startIndex' api-reference/openapi/research.json

Repository: recoupable/docs

Length of output: 9336


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
import json
from pathlib import Path

path = Path("api-reference/openapi/research.json")
data = json.loads(path.read_text())
paths = data["paths"]

path = "/api/chat/{chatId}/stream"
op = paths[path]["get"]
params = {p["name"]: p for p in op.get("parameters", [])}
account_id_param = params.get("account_id", {})
startIndex_param = params.get("startIndex", {})
responses = op.get("responses", {})

print("operation_security_types:", [list(s.keys())[0] for s in op.get("security", [])])
print("has_account_id_param:", bool(account_id_param))
print("account_id_param_required:", account_id_param.get("required"))
print("account_id_param_description:", account_id_param.get("description").replace("\n", " ")[:240] if account_id_param.get("description") else "")
print("account_id_param_format:", account_id_param.get("schema", {}).get("format") if account_id_param.get("schema") else "")
print("startIndex_param_min:", startIndex_param.get("schema", {}).get("minimum") if startIndex_param.get("schema") else "")
print("operation_description_contains_account_id:", "account_id" in (op.get("description") or ""))
print("operation_description_contains_own:", bool(("own" in (op.get("description") or "").lower()) or ("ownership" in (op.get("description") or "").lower())))
for status in ["400", "401", "402", "403"]:
    resp = responses.get(status, {})
    print(status, "contains_account_id=", bool(resp.get("description") and "account_id" in resp.get("description", "")), "contains_account_or_others=", any(token in (resp.get("description") or "").lower() for token in ["authenticated account", "different account", "specified account_id", "owner"]))
PY

Repository: recoupable/docs

Length of output: 943


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- source references to account_id and stream chats ---'
rg -n "account_id|chatId|ChatStreamErrorResponse|Access denied to specified account_id|startIndex" --glob '!api-reference/openapi/research.json' .

echo '--- route files candidates ---'
fd -t f '.*' . | rg 'api|chat|stream|route' | head -200

Repository: recoupable/docs

Length of output: 29528


🌐 Web query:

mcp.mdx account_id stream supported endpoints org API keys only

💡 Result:

The phrase "mcp.mdx account_id stream supported endpoints org API keys only" appears to be a fragmented search query or a set of notes regarding technical documentation for Model Context Protocol (MCP) implementations. Various services use the.mdx file extension for their documentation [1][2][3][4][5][6][7][8]. Based on common patterns found in MCP server documentation: 1. MCP Transports and Endpoints: Modern MCP servers frequently use "Streamable HTTP" as a transport mechanism [1][2][9][3]. This is often a single, stateless HTTP endpoint [1][9][3]. 2. Authentication (API Keys/Org IDs): Many implementations require an API key passed in the request header (e.g., X-API-Key or Authorization: Bearer <key>) [1][2][9][3][10]. For services that manage multiple organizations, some require an additional header (e.g., Nash-Org-Id) to specify the target organization [11]. However, as noted in some documentation (e.g., ModuleX), certain implementations are designed to authenticate via the API key alone because the server identifies the organization from the endpoint URL or the key itself, explicitly advising against adding an X-Organization-ID header in those cases [9]. 3. Stream vs. Batch: While MCP is a protocol, the term "stream" in this context often refers to the Streamable HTTP transport [1][2][3] or specific streaming API capabilities [12][13][14]. 4. Supported Endpoints: These are typically defined by the server's capabilities (e.g., list_tools, tools/call, resources/read) as per the MCP specification, rather than standard REST endpoints [1][9][8]. If you are developing or configuring an MCP integration, you should refer to the specific documentation provided by your service provider (often found at /mcp.mdx or similar paths in their documentation repositories) to confirm if they require a specific Org ID header or if the API key is sufficient for authentication [1][9][11].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Focused source/content check without running repository code or building.
echo '--- mcp.mdx account_id context ---'
sed -n '60,90p' mcp.mdx 2>/dev/null || true

echo '--- authentication.mdx account_id context ---'
sed -n '68,105p' authentication.mdx 2>/dev/null || true

echo '--- workflow stream generated docs ---'
for f in api-reference/chat/workflow-stream.mdx api-reference/chat/workflow.mdx; do
  if [ -f "$f" ]; then
    echo "--- $f ---"
    sed -n '1,220p' "$f"
  fi
done

Repository: recoupable/docs

Length of output: 2683


Align the stream auth and account mismatch errors with account_id.

account_id can authorize another account, but the 403 response still says ownership failed and the 400 response only documents invalid startIndex. Update the operation/response text to include malformed account_id behavior and bearer-token limitations for account overrides.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api-reference/openapi/research.json` around lines 789 - 798, Update the
OpenAPI operation containing the account_id query parameter and its 400/403
response descriptions: document malformed account_id values in the 400 response
alongside invalid startIndex, and revise the 403 stream
authorization/account-mismatch text to describe bearer-token limitations and
denied account overrides rather than ownership failure.

{
"name": "startIndex",
"in": "query",
Expand All @@ -806,6 +816,12 @@
"schema": {
"type": "string"
}
},
"x-workflow-stream-tail-index": {
"description": "Zero-based index of the last chunk known to the stream **at the moment this read was opened**. Because headers are sent before the body, a read that stays open past that point will deliver chunks beyond it — so this is a base for computing absolute positions, not a record of where the response ended. A client resuming precisely should count the chunks it receives on top of this value. Omitted if the runtime cannot report it.",
"schema": {
"type": "integer"
}
Comment on lines +820 to +824

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Constrain the zero-based header value.

Line 821 defines a zero-based index. Add "minimum": 0 to the header schema. Without this constraint, the OpenAPI contract accepts negative tail indexes.

Proposed schema constraint
               "schema": {
-                "type": "integer"
+                "type": "integer",
+                "minimum": 0
               }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"x-workflow-stream-tail-index": {
"description": "Zero-based index of the last chunk known to the stream **at the moment this read was opened**. Because headers are sent before the body, a read that stays open past that point will deliver chunks beyond it — so this is a base for computing absolute positions, not a record of where the response ended. A client resuming precisely should count the chunks it receives on top of this value. Omitted if the runtime cannot report it.",
"schema": {
"type": "integer"
}
"x-workflow-stream-tail-index": {
"description": "Zero-based index of the last chunk known to the stream **at the moment this read was opened**. Because headers are sent before the body, a read that stays open past that point will deliver chunks beyond it — so this is a base for computing absolute positions, not a record of where the response ended. A client resuming precisely should count the chunks it receives on top of this value. Omitted if the runtime cannot report it.",
"schema": {
"type": "integer",
"minimum": 0
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@api-reference/openapi/research.json` around lines 820 - 824, Add a minimum
constraint of 0 to the schema for the x-workflow-stream-tail-index header,
preserving its integer type and existing description so negative zero-based
indexes are rejected.

}
},
"content": {
Expand Down Expand Up @@ -3221,7 +3237,7 @@
"type": "object",
"required": [
"status",
"message"
"error"
],
"properties": {
"status": {
Expand All @@ -3231,9 +3247,16 @@
],
"description": "Status of the request"
},
"message": {
"error": {
"type": "string",
"description": "Error message describing what went wrong"
},
"missing_fields": {
"type": "array",
"description": "Present on validation failures (400): the path of the field that failed. Empty for a malformed path parameter.",
"items": {
"type": "string"
}
}
}
},
Expand Down