REST API reference
This page documents the current server routes as they exist today. It intentionally favors the exact path and method names over simplified marketing labels.
Base URL and auth
http://localhost:2009. Most machine clients use Authorization: Bearer arun_*. Browser login uses the Auth0-backed session routes under /auth, and shared links use X-Share-Token.Common workflows
/v1/connect/sessionsNo authStart the browser approval flow for a runtime. The response includes a session ID and the approval URL your CLI opens in the browser.
| Field | Type | Notes |
|---|---|---|
| client_kindrequired | string | claude_code, codex, mcp, generic, openclaw, or setup. |
| completion_moderequired | string | loopback or poll. |
| display_namerequired | string | Human-readable runtime name. |
| code_challengerequired | string | PKCE S256 code challenge. |
Example Request
curl -X POST http://localhost:2009/v1/connect/sessions \
-H "Content-Type: application/json" \
-d '{
"client_kind": "claude_code",
"completion_mode": "poll",
"display_name": "Claude Code",
"code_challenge": "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLM"
}'Example Response
{
"id": "01KM...",
"status": "pending",
"approval_url": "http://localhost:2009/connect/01KM...",
"poll_interval_ms": 1000
}/v1/connect/sessions/:id/redeemNo authRedeem an approved connect session and receive the scoped API key plus namespace details.
| Field | Type | Notes |
|---|---|---|
| code_verifierrequired | string | PKCE code verifier matching the original challenge. |
Example Request
curl -X POST http://localhost:2009/v1/connect/sessions/01KM.../redeem \
-H "Content-Type: application/json" \
-d '{
"code_verifier": "your-original-random-pkce-secret"
}'Example Response
{
"api_base_url": "http://localhost:2009",
"api_key": "arun_agt_...",
"principal": {
"id": "01KM...",
"type": "agent"
},
"namespace": {
"slug": "my-namespace"
}
}/v1/artifactsAuth requiredCreate a new artifact and version. This is the core publish operation behind the CLI and MCP server.
| Field | Type | Notes |
|---|---|---|
| namespace_idrequired | string | Target namespace ID. |
| titlerequired | string | Artifact title. |
| contentrequired | string | Artifact body. |
| content_type | string | text/plain, text/markdown, or application/json. |
Example Request
curl -X POST http://localhost:2009/v1/artifacts \
-H "Authorization: Bearer arun_agt_..." \
-H "Content-Type: application/json" \
-d '{
"namespace_id": "01KM...",
"title": "Docs implementation plan",
"content": "# Plan\n\nBuild a lean docs system.",
"content_type": "text/markdown"
}'Example Response
{
"id": "01KM...",
"title": "Docs implementation plan",
"current_version": 1,
"content_type": "text/markdown"
}/v1/artifacts/:idAuth requiredCreate a new version of an existing artifact. The server preserves old versions and stores git metadata when present.
| Field | Type | Notes |
|---|---|---|
| contentrequired | string | Replacement content. |
| title | string | Optional title update. |
| description | string | Optional description update. |
| message | string | Version message. |
Example Request
curl -X PUT http://localhost:2009/v1/artifacts/01KM... \
-H "Authorization: Bearer arun_agt_..." \
-H "Content-Type: application/json" \
-d '{
"content": "# Plan\n\nUpdated after review.",
"message": "Incorporate review feedback"
}'Example Response
{
"id": "01KM...",
"current_version": 2,
"version": {
"version": 2,
"content_hash": "3b2f..."
}
}/v1/grantsAuth requiredCreate a share token that grants read access to a namespace or one artifact.
| Field | Type | Notes |
|---|---|---|
| namespace_idrequired | string | Namespace being shared. |
| artifact_id | string | Optional artifact-specific scope. |
| permissions | string[] | Defaults to read-only behavior in normal share flows. |
| expires_at | string | ISO timestamp. |
Example Request
curl -X POST http://localhost:2009/v1/grants \
-H "Authorization: Bearer arun_usr_..." \
-H "Content-Type: application/json" \
-d '{
"namespace_id": "01KM...",
"artifact_id": "01KM...",
"permissions": ["read"]
}'Example Response
{
"id": "01KM...",
"token": "arun_share_...",
"token_prefix": "arun_share_...",
"expires_at": null
}/v1/git/importAuth requiredFetch a file from GitHub, GitLab, or Bitbucket and import it as a new artifact with git provenance.
| Field | Type | Notes |
|---|---|---|
| repo_urlrequired | string | Repository URL. |
| pathrequired | string | Path inside the repository. |
| namespace_idrequired | string | Target namespace ID. |
| branch | string | Defaults to main. |
Example Request
curl -X POST http://localhost:2009/v1/git/import \
-H "Authorization: Bearer arun_agt_..." \
-H "Content-Type: application/json" \
-d '{
"repo_url": "https://github.com/attach-dev/attach-platform",
"path": "README.md",
"branch": "main",
"namespace_id": "01KM..."
}'Example Response
{
"id": "01KM...",
"current_version": 1,
"provenance": {
"source": "git_import",
"gitRepoUrl": "https://github.com/attach-dev/attach-platform",
"gitRef": "main",
"gitPath": "README.md"
}
}Route inventory
Auth
Connect
Principal and keys
Namespaces and artifacts
Sharing and git
Instances, lineage, stats
Response shape notes
Error responses consistently use a compact shape with error and message. Search, list, and detail routes tend to use snake_case field names in JSON, even when the internal TypeScript types are camelCase.
{
"error": "not_found",
"message": "Artifact not found"
}