HydraCore
API by router

Instances

List Instances

GET
/v1/instances
AuthorizationBearer <token>

In: header

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X GET "https://loading/v1/instances" \  -H "X-Api-Key: string"
{
  "instances": [
    {
      "agent_name": "string",
      "created_at": "2019-08-24T14:15:22Z",
      "customer_email": "string",
      "hostname": "string",
      "id": "string",
      "ip_address": "string",
      "preset_id": "string",
      "product_tier_name": "string",
      "provider": "string",
      "region_id": "string",
      "runtime_type": "expressclaw",
      "status": "string",
      "workload_type": "agent"
    }
  ]
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Create Instance

POST
/v1/instances
AuthorizationBearer <token>

In: header

Header Parameters

X-Api-Key?X-Api-Key
agent_name?Agent Name
customer_id?Customer Id
idempotency_key?Idempotency Key
manifest_id?Manifest Id
preset_id?Preset Id
Default"personal_assistant"
recipe_id?Recipe Id
region_idRegion Id
tier_idTier Id
user_display_name?User Display Name
website_template_slug?Website Template Slug
workflow_slugs?Workflow Slugs

Response Body

curl -X POST "https://loading/v1/instances" \  -H "X-Api-Key: string" \  -H "Content-Type: application/json" \  -d '{    "region_id": "string",    "tier_id": "string"  }'
{
  "idempotency_key": "string",
  "instance_id": "string",
  "message": "string",
  "task_id": "string"
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Rotate Agent Key

Nullify existing API key hash, allowing /secrets to issue a fresh key.

Admin-only. Recovery path for transient /secrets failures where hash was set but VPS never received the key.

POST
/v1/instances/admin/{instance_id}/rotate-key
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X POST "https://loading/v1/instances/admin/497f6eca-6276-4993-bfeb-53cbbbba6f08/rotate-key" \  -H "X-Api-Key: string"
{
  "instance_id": "string",
  "status": "string"
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Poll By Idempotency Key

Poll provisioning status by idempotency key.

The frontend fires POST /v1/instances and gets back a task_id + idempotency_key but no instance_id (the Celery task creates the row asynchronously). This endpoint lets the deploy page poll until the instance appears, then track its status.

"Patience, young grasshopper." — Kung Fu (about waiting for Celery tasks)

GET
/v1/instances/by-key/{idempotency_key}
AuthorizationBearer <token>

In: header

Path Parameters

idempotency_keyIdempotency Key

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X GET "https://loading/v1/instances/by-key/string" \  -H "X-Api-Key: string"
{
  "bootstrap_seq": 0,
  "bootstrap_stage": "string",
  "error_message": "string",
  "found": true,
  "hostname": "string",
  "instance_id": "string",
  "logs": [
    {}
  ],
  "provisioning_stage": "string",
  "status": "string"
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Cleanup Dead Instances

Bulk-delete all error/failed instances for the current tenant.

Admin-only. Tears down any lingering provider resources, then soft-deletes each instance exactly like the single-delete endpoint does (frees unique fields, removes child records, keeps ProvisionSnapshot for audit).

"Bring out your dead!" — Monty Python and the Holy Grail

POST
/v1/instances/cleanup
AuthorizationBearer <token>

In: header

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X POST "https://loading/v1/instances/cleanup" \  -H "X-Api-Key: string"
{
  "cleaned": 0,
  "errors": 0,
  "message": "string"
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Get Instance

GET
/v1/instances/{instance_id}
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X GET "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08" \  -H "X-Api-Key: string"
{
  "agent_name": "string",
  "callback_seq": 0,
  "callback_stage": "string",
  "capabilities": {
    "property1": true,
    "property2": true
  },
  "created_at": "2019-08-24T14:15:22Z",
  "error_message": "string",
  "health_status": "string",
  "hostname": "string",
  "id": "string",
  "ip_address": "string",
  "preset_id": "string",
  "provider": "string",
  "provisioning_stage": "string",
  "region_id": "string",
  "runtime_type": "expressclaw",
  "server_type_plan": "string",
  "status": "string",
  "updated_at": "2019-08-24T14:15:22Z",
  "vpn_ip": "string",
  "workload_type": "agent"
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Delete Instance

Delete instance with graceful teardown.

Production-ready implementation with:

  • Authorization: customer ownership or admin role
  • Idempotency: repeated deletes return 200 with already_deleted flag
  • Async: non-blocking external calls (provider VPS + R2 artifact)
  • Race-safe: atomic state transition with FOR UPDATE lock
  • Soft-delete: preserve instance + snapshot as immutable audit trail

Steps:

  1. Verify instance exists and authorize access
  2. Check idempotency (already deleted/deleting)
  3. Atomic state transition (running|failed|provisioning → deleting)
  4. Capture metadata for external cleanup (outside lock)
  5. External cleanup (provider VPS + R2 artifact) - non-blocking
  6. Database cleanup (delete related records, soft-delete instance)
  7. Free unique fields (vpn_ip, provider_instance_id, hostname)

Args: instance_id: Instance UUID current_user: Authenticated user from get_current_user dependency db: Async database session

Returns: DeleteInstanceResponse with status and cleanup summary

Errors: 401: Unauthenticated (missing/invalid X-User-Id header) 403: Unauthorized (instance belongs to different customer, non-admin) 404: Instance not found 500: Critical failure (partial cleanup may have occurred)

DELETE
/v1/instances/{instance_id}
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X DELETE "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08" \  -H "X-Api-Key: string"
{
  "already_deleted": false,
  "instance_id": "string",
  "message": "string",
  "status": "string"
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Proxy Chat

POST
/v1/instances/{instance_id}/chat
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key
conversation_id?Conversation Id
messageMessage
Length1 <= length <= 8000

Response Body

curl -X POST "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/chat" \  -H "X-Api-Key: string" \  -H "Content-Type: application/json" \  -d '{    "message": "string"  }'
null
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Proxy Get Config

GET
/v1/instances/{instance_id}/config
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X GET "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/config" \  -H "X-Api-Key: string"
null
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Proxy Update Config

POST
/v1/instances/{instance_id}/config
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key
agent_name?Agent Name
customer_facing_prompt?Customer Facing Prompt
model_temperature?Model Temperature
recipe_id?Recipe Id
system_prompt?System Prompt
telegram_bot_token?Telegram Bot Token
workflow_slugs?Workflow Slugs

Response Body

curl -X POST "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/config" \  -H "X-Api-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
null
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Toggle conversation debug access for an instance.

The instance owner or any tenant admin can grant or revoke debug consent. This controls whether the platform can read conversation content via the /conversations proxy endpoints.

DESIGN DECISION: Admin bypass is intentional. Platform admins need consent management for support, compliance, and incident response. If a future product requirement mandates end-customer-only consent (no admin override), replace _authorize_instance here with an owner-only check: if instance.customer_id != current_user.customer_id: raise HTTPException(403, "Only the instance owner can manage consent")

"With great power comes great responsibility." — Uncle Ben, Spider-Man

PATCH
/v1/instances/{instance_id}/consent
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key
consent_debug_accessConsent Debug Access

Response Body

curl -X PATCH "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/consent" \  -H "X-Api-Key: string" \  -H "Content-Type: application/json" \  -d '{    "consent_debug_access": true  }'
{
  "consent_debug_access": true,
  "instance_id": "string",
  "message": "string"
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Proxy Conversations

GET
/v1/instances/{instance_id}/conversations
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Query Parameters

limit?Limit
Default20
Range1 <= value <= 100

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X GET "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/conversations?limit=20" \  -H "X-Api-Key: string"
null
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Proxy Conversation Detail

GET
/v1/instances/{instance_id}/conversations/{conversation_id}
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid
conversation_idConversation Id
Match^[A-Za-z0-9:_-]{1,128}$
Lengthlength <= 128

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X GET "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/conversations/string" \  -H "X-Api-Key: string"
null
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Get Instance Logs

Return provision logs for an instance, ordered by sequence.

"Game over, man! Game over!" — Hudson, Aliens (about reading every step of the provisioning process)

GET
/v1/instances/{instance_id}/logs
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X GET "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/logs" \  -H "X-Api-Key: string"
{
  "instance_id": "string",
  "logs": [
    {
      "created_at": "2019-08-24T14:15:22Z",
      "level": "string",
      "message": "string",
      "seq": 0,
      "stage": "string"
    }
  ],
  "total": 0
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Update Model Policy

Update the model policy for an instance.

Updates the agent_config.model_policy in the database and optionally pushes the change to the running VPS.

"I love the smell of napalm in the morning." — Lt. Col. Kilgore, Apocalypse Now (about hot-reloading model configs)

PATCH
/v1/instances/{instance_id}/model-policy
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key
budget_daily_usd?Budget Daily Usd
budget_monthly_usd?Budget Monthly Usd
embedding_model?Embedding Model
fallbacks?Fallbacks
max_tokens?Max Tokens
primary?Primary
temperature?Temperature

Response Body

curl -X PATCH "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/model-policy" \  -H "X-Api-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "instance_id": "string",
  "message": "string",
  "model_policy": {}
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Get Platform Config

Read platform-level config from the instances table.

"You want answers?" "I want the config!" — A Few Good Men (about JSONB)

GET
/v1/instances/{instance_id}/platform-config
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X GET "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/platform-config" \  -H "X-Api-Key: string"
{
  "advanced": {},
  "channels": {},
  "instance_id": "string",
  "integrations": [],
  "recipe_id": "string",
  "skills": [],
  "workflow_slugs": []
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Patch Platform Config

Merge-update platform config into agent_config JSONB.

Only fields present in the request body are updated; others are left alone. This is the backend for Skills install/remove, Integrations connect/disconnect, Channels enable/config, and Advanced toggles.

"It's not a bug, it's a feature." — Every developer who just shipped a PATCH endpoint

PATCH
/v1/instances/{instance_id}/platform-config
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key
advanced?Advanced
channels?Channels
integrations?Integrations
recipe_id?Recipe Id
skills?Skills
workflow_slugs?Workflow Slugs

Response Body

curl -X PATCH "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/platform-config" \  -H "X-Api-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "advanced": {},
  "channels": {},
  "instance_id": "string",
  "integrations": [],
  "recipe_id": "string",
  "skills": [],
  "workflow_slugs": []
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Get Runtime Status

Get runtime status from the VPS agent.

Proxies to the agent's /api/status endpoint over WireGuard. Returns enriched context in ALL states so the UI can show meaningful progress and diagnostics — not just "unreachable".

"Fly, you fools!" — Gandalf, LOTR (when the VPS is down)

GET
/v1/instances/{instance_id}/runtime
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X GET "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/runtime" \  -H "X-Api-Key: string"
{
  "active_connections": 0,
  "bootstrap_seq": 0,
  "bootstrap_stage": "string",
  "error_code": "string",
  "error_message": "string",
  "health_failures": 0,
  "health_status": "string",
  "instance_id": "string",
  "last_heartbeat": "2019-08-24T14:15:22Z",
  "node_version": "string",
  "openclaw_version": "string",
  "provision_logs": [
    {}
  ],
  "provisioning_stage": "string",
  "skills_loaded": [],
  "status": "string",
  "uptime_seconds": 0
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Apply Updates

Apply pending config/skill updates to a running instance.

Proxies to the agent's /api/updates/apply endpoint.

"Get to the chopper!" — Dutch, Predator (about deploying updates)

POST
/v1/instances/{instance_id}/updates/apply
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Header Parameters

X-Api-Key?X-Api-Key
force?Force
Defaultfalse
restart_agent?Restart Agent
Defaultfalse

Response Body

curl -X POST "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/updates/apply" \  -H "X-Api-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "instance_id": "string",
  "message": "string",
  "status": "string"
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}

Get Instance Usage

Usage breakdown for a single instance with daily time series.

"Every time a bell rings, an angel gets its wings." — Clarence, It's a Wonderful Life (about every token getting counted)

GET
/v1/instances/{instance_id}/usage
AuthorizationBearer <token>

In: header

Path Parameters

instance_idInstance Id
Formatuuid

Query Parameters

days?Days
Default30

Header Parameters

X-Api-Key?X-Api-Key

Response Body

curl -X GET "https://loading/v1/instances/497f6eca-6276-4993-bfeb-53cbbbba6f08/usage?days=30" \  -H "X-Api-Key: string"
{
  "daily": [
    {}
  ],
  "hostname": "string",
  "instance_id": "string",
  "total_cost_usd": "string",
  "total_requests": 0,
  "total_tokens": 0,
  "unique_end_users": 0
}
{
  "detail": [
    {
      "loc": [
        "string"
      ],
      "msg": "string",
      "type": "string"
    }
  ]
}