Imperal Docs
API Reference

Developer API Map

Curated quickstart for the Imperal Cloud public API — services overview, the 15 key endpoints with curl examples, and gotchas every developer should know.

A practical entry point into the Imperal Cloud REST API. The table below locates each service; the endpoint catalogue below that covers the 15 routes you need to build on the platform.

Services

ServiceBase URLPublic pathsDownloadable spec
Auth Gatewayhttps://auth.imperal.io134/openapi/auth-gateway.json
Registryhttps://api-server (internal)15/openapi/registry.json

Gotcha — /v1/auth/register is service-gated. Programmatic user creation requires an X-Service-Token. The public self-registration path is POST /v1/auth/signup (email + verify-email flow). See Auth endpoints below.

POST /v1/automations is deprecated. Do not use it in new integrations. Automation lifecycle is managed through the automations extension via the POST /v1/extensions/automations/call route.

Kernel/service-only routes. Six paths in the public spec require an X-Service-Token even though they carry no /internal/ path segment: POST /v1/actions, GET /v1/actions/stats/marketplace/{app_id}, POST /v1/billing/topup/confirm, POST /v1/developer/apps/{app_id}/_sync_manifest, GET /v1/events/stats, GET /v1/extensions/access. These are labeled kernel/service-only in each section below and are not intended for developer use.


Auth

Endpoint 1 — Self-service signup

POST /v1/auth/signup

Self-service user registration (email flow). Returns a message; the user must verify their email before they can log in.

Request

{
  "email": "user@example.com",
  "password": "s3cure!",
  "tenant_id": "default",
  "first_name": "Ada",
  "last_name": "Lovelace"
}

Response 201

{
  "message": "Verification email sent. Check your inbox.",
  "user_id": "imp_u_abc123"
}

Complete registration with POST /v1/auth/verify-email passing {"token": "<email_token>"} — you receive a TokenResponse (same shape as login).

curl -s -X POST https://auth.imperal.io/v1/auth/signup \
  -H 'Content-Type: application/json' \
  -d '{"email":"user@example.com","password":"s3cure!","tenant_id":"default"}'

Endpoint 2 — Login

POST /v1/auth/login

Exchange credentials for a JWT. The access_token is a short-lived Bearer token; rotate it using the refresh_token.

Request

{
  "email": "user@example.com",
  "password": "s3cure!",
  "tenant_id": "default"
}

Response 200

{
  "access_token": "eyJ...",
  "refresh_token": "eyJ...",
  "token_type": "bearer",
  "expires_in": 3600
}
curl -s -X POST https://auth.imperal.io/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"user@example.com","password":"s3cure!","tenant_id":"default"}'

Endpoint 3 — Refresh token

POST /v1/auth/refresh

Rotate a JWT using a refresh token. Returns a fresh TokenResponse with the same shape as login.

Request

{ "refresh_token": "eyJ..." }
curl -s -X POST https://auth.imperal.io/v1/auth/refresh \
  -H 'Content-Type: application/json' \
  -d '{"refresh_token":"eyJ..."}'

Endpoint 4 — Current user profile

GET /v1/auth/me

Returns the authenticated user's profile.

Response 200

{
  "imperal_id": "imp_u_abc123",
  "email": "user@example.com",
  "role": "user",
  "tenant_id": "default",
  "is_active": true
}
curl -s https://auth.imperal.io/v1/auth/me \
  -H 'Authorization: Bearer <access_token>'

Extensions

Endpoint 5 — Extension call (canonical agent route)

POST /v1/extensions/{app_id}/call

The single route Webbee (and any external agent) uses to invoke extension logic. Every @chat.function registered in any extension is reachable here — no gateway changes needed when you add a new function.

Path param: app_id — the extension slug (e.g. developer, billing, automations).

Request body (CallRequest)

FieldTypeRequiredDescription
user_idstringyesThe imperal_id of the acting user
tenant_idstringnoDefaults to "default"
functionstringyesThe @chat.function name to invoke
paramsobjectnoFunction-specific parameters (defaults to {})

Response 200 (CallResponse)

FieldTypeDescription
statusstring"success" or "error"
dataanyFunction-specific return payload
summarystring or nullOne-line prose for display
errorstring or nullError message if status == "error"
uianyOptional UI node for panel rendering

The data field has no fixed schema — its shape is entirely determined by the function's return value. Use function-specific examples (see deploy_ir below).

Concrete example — deploy a declarative IR via the developer extension

curl -s -X POST https://auth.imperal.io/v1/extensions/developer/call \
  -H 'Authorization: Bearer <access_token>' \
  -H 'Content-Type: application/json' \
  -d '{
    "user_id": "imp_u_abc123",
    "tenant_id": "default",
    "function": "deploy_ir",
    "params": {
      "app_id": "my-extension",
      "ir_dict": {
        "app_id": "my-extension",
        "version": "1.0.0",
        "steps": [
          {"id": "step_1", "kind": "declarative", "action": "store.create", "params": {"collection": "tasks", "data": {"title": "{{title}}"}}}
        ]
      }
    }
  }'

Response 200

{
  "status": "success",
  "data": {
    "app_id": "my-extension",
    "deployed_at": "2026-06-21T10:00:00Z",
    "steps_registered": 1,
    "ir_version": "1.0.0"
  },
  "summary": "IR deployed",
  "error": null,
  "ui": null
}

The data payload is a DeployReceipt dict. The web-kernel registers the IR steps and they become immediately callable.


Endpoint 6 — Extension batch call

POST /v1/extensions/{app_id}/batch

Execute multiple functions in one round-trip — used by the Imperal Panel for left/right panel hydration on page load.

Request body (BatchCallRequest)

{
  "user_id": "imp_u_abc123",
  "tenant_id": "default",
  "calls": [
    {"function": "get_balance"},
    {"function": "list_recent", "params": {"limit": 5}}
  ]
}

Response 200 — array of CallResponse, one per call. Per-item errors do not abort the batch.

curl -s -X POST https://auth.imperal.io/v1/extensions/billing/batch \
  -H 'Authorization: Bearer <access_token>' \
  -H 'Content-Type: application/json' \
  -d '{"user_id":"imp_u_abc123","calls":[{"function":"get_balance"},{"function":"list_plans"}]}'

Registry / extension discovery

Endpoint 7 — List installed extensions

GET /v1/me/extensions

List all extensions installed for the current user, including the full function manifest. The Panel uses this to build the sidebar rail; the web-kernel uses it to populate the tool registry at session start.

Response 200

[
  {
    "app_id": "developer",
    "name": "Developer Portal",
    "description": "Publish and manage Imperal extensions.",
    "functions": [
      {"name": "deploy_ir", "description": "Deploy a declarative IR to the kernel.", "params_schema": {}}
    ],
    "is_installed": true,
    "is_disabled": false
  }
]
curl -s https://auth.imperal.io/v1/me/extensions \
  -H 'Authorization: Bearer <access_token>'

Marketplace

Endpoint 8 — Browse apps

GET /v1/marketplace/apps

Browse published extensions. Supports full-text search and category filtering.

Query params: ?search=&category=&limit=20&offset=0

Response 200

[
  {
    "app_id": "notes",
    "name": "Notes",
    "short_description": "Create and search personal notes through chat.",
    "category": "productivity",
    "install_count": 412,
    "rating": 4.7,
    "developer_id": "imp_dev_xyz",
    "icon_url": "https://...",
    "pricing_model": "free"
  }
]
curl -s 'https://auth.imperal.io/v1/marketplace/apps?search=notes&limit=10' \
  -H 'Authorization: Bearer <access_token>'

Endpoint 9 — Install an app

POST /v1/marketplace/apps/{app_id}/install

Install a marketplace extension for the current user. Delete with DELETE /v1/marketplace/apps/{app_id}/install to uninstall.

Request body: {} (empty)

Response 200

{
  "app_id": "notes",
  "installed_at": "2026-06-21T10:00:00Z",
  "status": "installed"
}
curl -s -X POST https://auth.imperal.io/v1/marketplace/apps/notes/install \
  -H 'Authorization: Bearer <access_token>' \
  -H 'Content-Type: application/json' \
  -d '{}'

Billing

Endpoint 10 — Wallet balance

GET /v1/billing/balance

Return the current credit-wallet balance for the authenticated user.

Response 200 (WalletResponse)

{
  "balance": 4200,
  "currency": "token",
  "updated_at": "2026-06-21T09:55:00Z"
}

balance is in credits (1 credit = 1 token = $0.001). Also useful: GET /v1/billing/usage returns a LimitsResponse with quota and consumed counts.

curl -s https://auth.imperal.io/v1/billing/balance \
  -H 'Authorization: Bearer <access_token>'

Developer Portal

Endpoint 11 — Register as developer

POST /v1/developer/register

Enroll the current user as an extension developer. Required before creating or submitting apps.

Request body (DeveloperRegisterRequest)

{
  "display_name": "Ada Lovelace",
  "website": "https://ada.io",
  "description": "Building productivity extensions for Imperal Cloud."
}

Response 200: {}

After registering, GET /v1/developer/profile to confirm tier.

curl -s -X POST https://auth.imperal.io/v1/developer/register \
  -H 'Authorization: Bearer <access_token>' \
  -H 'Content-Type: application/json' \
  -d '{"display_name":"Ada Lovelace"}'

Endpoint 12 — Create an app

POST /v1/developer/apps

Create a new extension app record. The app starts in draft status.

Request body (AppCreateRequest)

{
  "app_id": "my-extension",
  "name": "My Extension",
  "short_description": "Does something useful.",
  "category": "productivity"
}

Response 201 (AppResponse)

{
  "app_id": "my-extension",
  "name": "My Extension",
  "status": "draft",
  "created_at": "2026-06-21T10:00:00Z"
}
curl -s -X POST https://auth.imperal.io/v1/developer/apps \
  -H 'Authorization: Bearer <access_token>' \
  -H 'Content-Type: application/json' \
  -d '{"app_id":"my-extension","name":"My Extension","short_description":"Does something useful.","category":"productivity"}'

Endpoint 13 — Record a deploy

POST /v1/developer/apps/{app_id}/deploys

Record a new deploy for an app version. Triggers the worker rsync pipeline.

Request body

{
  "version": "1.0.0",
  "changelog": "Initial release."
}

Response 201

{
  "deploy_id": "dep_abc",
  "app_id": "my-extension",
  "version": "1.0.0",
  "status": "pending",
  "created_at": "2026-06-21T10:00:00Z"
}
curl -s -X POST https://auth.imperal.io/v1/developer/apps/my-extension/deploys \
  -H 'Authorization: Bearer <access_token>' \
  -H 'Content-Type: application/json' \
  -d '{"version":"1.0.0","changelog":"Initial release."}'

Endpoint 14 — Submit for review

POST /v1/developer/apps/{app_id}/submit

Submit an app for marketplace approval. The app must have at least one successful deploy.

Request body: {}

Response 200

{
  "app_id": "my-extension",
  "status": "pending_review",
  "submitted_at": "2026-06-21T10:00:00Z"
}
curl -s -X POST https://auth.imperal.io/v1/developer/apps/my-extension/submit \
  -H 'Authorization: Bearer <access_token>' \
  -H 'Content-Type: application/json' \
  -d '{}'

Real-time events

Endpoint 15 — SSE event stream

GET /v1/events/stream

Server-Sent Events stream of real-time kernel events for the authenticated user: chat messages, task updates, notifications, panel refresh triggers.

Headers: Authorization: Bearer <access_token>

Produces: text/event-stream

Each event:

data: {"type": "chat_message", "payload": {"message_id": "msg_abc", "text": "..."}, "ts": "2026-06-21T10:00:00Z"}

data: {"type": "task_update", "payload": {"task_id": "task_xyz", "status": "done"}, "ts": "2026-06-21T10:00:01Z"}
curl -s -N https://auth.imperal.io/v1/events/stream \
  -H 'Authorization: Bearer <access_token>'

New kernel event types are delivered here automatically without protocol changes — the SSE channel is the universal push surface for all real-time updates.

On this page