English
ResearchX API Skill
A copyable ResearchX API operation skill for external models and automation agents
ResearchX API Skill
This page provides a copyable SKILL.md for external LLMs, automation agents, Claude/Codex/OpenClaw-style tools, or custom orchestrators that call ResearchX HTTP APIs. It is not a built-in ResearchX global skill and will not automatically appear in the project Skills modal.
Recommended use:
- Create
researchx-api/SKILL.mdin the target model or agent skill directory. - Copy the full content below.
- Load the skill when the model needs to operate ResearchX through APIs for data analysis.
- Use /openapi.json or /swagger as the API reference.
SKILL.md
---
name: researchx-api
description: Use this skill when an external model, automation agent, or ResearchX assistant needs to operate ResearchX through its HTTP APIs for data analysis. It covers login, project selection, workspace file transfer, agent ticket creation, SSE progress, permission requests, user questions, and result retrieval.
---
# ResearchX API Operation
Use this skill when the task is to operate ResearchX itself through APIs, especially for external LLM or automation workflows that need to run data analysis on the platform.
## When To Use
- The user asks how an LLM should call ResearchX APIs.
- The user wants to upload data, start an analysis task, watch progress, and fetch results through ResearchX.
- The user wants a reusable API workflow, SDK wrapper, MCP server, or automation around ResearchX.
- The user is debugging an external agent that calls project workspace, agent ticket, permission, or MCP endpoints.
Do not use this skill for ordinary in-app chat analysis where the model can directly use the current ResearchX UI and project tools. Use it when the work is API-driven or when designing such an integration.
## Source References
Prefer these docs as the source of truth before inventing endpoint behavior:
- LLM API guide: `/docs/en/llm-api-guide`
- Data Analysis API Cookbook: `/docs/en/data-analysis-api-cookbook`
- Agent API Profile: `/docs/en/agent-api-profile`
- Frontend API docs: `/docs/en/frontend-api`
- Runtime API reference: `/swagger`
- Raw OpenAPI document: `/openapi.json`
If code and docs disagree in a local ResearchX checkout, verify against `apps/web/app/api/**/route.ts` and `apps/web/lib/workspace-client/**`.
## Core Objects
Operate ResearchX through these stable objects:
- `Project`: isolation boundary for users, files, conversations, agent tickets, containers, and MCP servers.
- `Workspace`: project-local files under `agent-workspace`; use workspace-relative paths such as `data/input.csv`.
- `Conversation`: optional chat context for result return and follow-up.
- `Agent Ticket`: asynchronous task with status, events, artifacts, and action executions.
- `Container`: execution environment; inside containers the project root is `/workspace`.
- `Tool Permission`: confirmation flow for writes, edits, commands, and protected MCP calls.
- `Conversation Question`: structured request for user choices or missing information.
## Minimal Data Analysis Flow
Use this order for the first successful integration:
1. Log in and keep the returned `token`.
2. Send later requests with `Authorization: Bearer <token>`.
3. List or create a project.
4. Upload input files to the project workspace.
5. List available project agents and choose a matching definition.
6. Create an agent ticket.
7. Watch the ticket SSE stream.
8. Handle pending tool permissions or conversation questions.
9. Fetch ticket detail in `mode=full`.
10. Read or download workspace result files.
## Endpoint Profile
Prefer this compact endpoint set for external model tools:
```text
POST /api/auth/login
GET /api/projects
GET /api/projects/{projectId}
GET /api/projects/{projectId}/agent-workspace
POST /api/projects/{projectId}/agent-workspace
GET /api/projects/{projectId}/agent-workspace/content
GET /api/projects/{projectId}/agent-workspace/download
GET /api/projects/{projectId}/agents
POST /api/projects/{projectId}/agent-tickets
GET /api/projects/{projectId}/agent-tickets/stream
GET /api/projects/{projectId}/agent-tickets/{ticketId}
GET /api/projects/{projectId}/tool-permission-requests
GET /api/projects/{projectId}/tool-permission-requests/{requestId}/diff-preview
POST /api/projects/{projectId}/tool-permission-requests/{requestId}/approve
POST /api/projects/{projectId}/tool-permission-requests/{requestId}/deny
GET /api/projects/{projectId}/conversation-question-requests
POST /api/projects/{projectId}/conversation-question-requests/{requestId}/answer
POST /api/projects/{projectId}/conversation-question-requests/{requestId}/reject
```
Do not expose admin routes, destructive workspace delete routes, user deletion, project archive, or broad model configuration writes to an external LLM by default.
## Login
Call:
```http
POST /api/auth/login
```
Body:
```json
{
"email": "user@example.com",
"password": "password"
}
```
Use `data.token` from the response:
```http
Authorization: Bearer sess_xxx
```
## Workspace Upload
For multipart upload, `path` is the destination parent directory. The final filename comes from the uploaded file.
```bash
curl -X POST "$BASE_URL/api/projects/$PROJECT_ID/agent-workspace" \
-H "Authorization: Bearer $TOKEN" \
-F "file=@./input.csv" \
-F "path=data" \
-F "conflict_policy=overwrite"
```
This stores the file as:
```text
data/input.csv
```
Recommended workspace layout:
- `data/` for raw inputs
- `scripts/` for analysis scripts
- `reports/` for reports and plots
- `results/` for tables and machine-readable outputs
Never write directly to `.agent/` unless the task is explicitly about project configuration.
## Agent Selection
Before creating a ticket, call:
```http
GET /api/projects/{projectId}/agents
```
Choose an agent by inspecting:
- `name`
- `title`
- `task_type`
- `description`
- input definitions
Do not assume `data_analysis` is always a valid fixed built-in task. Treat it as an example classification unless it appears in the available agent definitions.
## Create Analysis Ticket
Call:
```http
POST /api/projects/{projectId}/agent-tickets
```
Use a body like:
```json
{
"task_type": "data_analysis",
"title": "Analyze uploaded CSV",
"intent_summary": "Analyze data/input.csv, compute descriptive statistics, create charts, and write reports/summary.md.",
"priority": "normal",
"input": {
"source": "external_api",
"agent_definition_id": "selected_agent_name",
"files": ["data/input.csv"],
"expected_outputs": ["reports/summary.md", "reports/figures"]
}
}
```
If the task should return a task card and result to a conversation, first create or select a conversation and include both:
```json
{
"conversation_id": "conv_xxx",
"add_to_conversation": true
}
```
`add_to_conversation: true` without `conversation_id` is invalid.
## Watch Progress
Prefer SSE:
```http
GET /api/projects/{projectId}/agent-tickets/stream
```
The event name is `agent_ticket`. Track:
- `ticket_id`
- `status`
- `detail_changed`
- `conversation_changed`
- `should_continue_conversation`
If the stream disconnects, reconnect with the last received SSE id:
```http
last-event-id: <event-id>
```
Also fetch ticket detail after reconnecting to recover the current state.
## Ticket Status Handling
Treat these as active or waiting states:
```text
submitted
validating
queued
dispatching
running
awaiting_user_input
retry_waiting
cancelling
```
Treat these as terminal or review states:
```text
partial_succeeded
succeeded
failed
cancelled
```
When status is `awaiting_user_input`, check both permission requests and conversation question requests.
## Fetch Detail
Use full mode after completion or failure:
```http
GET /api/projects/{projectId}/agent-tickets/{ticketId}?mode=full
```
Inspect:
- `ticket.status`
- `latest_run.failure_code`
- `latest_run.failure_message`
- `events`
- `artifacts`
- `action_executions`
## Permission Requests
Find pending requests:
```http
GET /api/projects/{projectId}/tool-permission-requests?status=pending
```
For write or edit requests, preview first:
```http
GET /api/projects/{projectId}/tool-permission-requests/{requestId}/diff-preview
```
Approve only after the caller or policy has accepted the change:
```http
POST /api/projects/{projectId}/tool-permission-requests/{requestId}/approve
```
Deny unsafe or unclear changes:
```http
POST /api/projects/{projectId}/tool-permission-requests/{requestId}/deny
```
Never auto-approve destructive writes, shell commands, or MCP calls unless the integration policy explicitly allows it.
## Conversation Questions
Find pending questions:
```http
GET /api/projects/{projectId}/conversation-question-requests?status=pending
```
Answer with selected labels and optional custom text:
```json
{
"answers": [
{
"question_id": "q1",
"selected_labels": ["Use all samples"],
"custom_text": null
}
]
}
```
Submit:
```http
POST /api/projects/{projectId}/conversation-question-requests/{requestId}/answer
```
Reject:
```http
POST /api/projects/{projectId}/conversation-question-requests/{requestId}/reject
```
Do not invent user choices without explicit caller authorization.
## Result Retrieval
List reports:
```http
GET /api/projects/{projectId}/agent-workspace?path=reports
```
Search for likely results:
```http
GET /api/projects/{projectId}/agent-workspace?query=summary&limit=20
```
Read text or Markdown:
```http
GET /api/projects/{projectId}/agent-workspace/content?path=reports/summary.md
```
Download binary outputs:
```http
GET /api/projects/{projectId}/agent-workspace/download?path=reports/figures/plot.png
```
Prefer paths reported in `artifacts` and discovered workspace entries over guessed paths.
## Failure Recovery
On `failed`, fetch `mode=full` and summarize:
- what failed
- whether partial outputs exist
- whether the error is input-related, permission-related, environment-related, model-related, or platform-related
- the safest next action
Retry only when the problem is plausibly fixable, such as:
- missing or wrong file path
- denied permission that the caller now approves
- transient model or network failure
- container image or startup issue after it has been fixed
Do not loop retries blindly.
## Implementation Checklist
When building SDK, MCP, or automation tools around this skill:
1. Keep endpoint wrappers narrow and named by intent, not by raw route names.
2. Validate `projectId`, file paths, and ticket IDs before calling mutating routes.
3. Use workspace-relative paths only.
4. Preserve `request_id` from errors in logs.
5. Serialize permission approvals.
6. Use SSE when available and polling as fallback.
7. Require explicit caller policy for approvals and destructive actions.
8. Read `/openapi.json` in tests to detect drift.