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
| Service | Base URL | Public paths | Downloadable spec |
|---|---|---|---|
| Auth Gateway | https://auth.imperal.io | 134 | /openapi/auth-gateway.json |
| Registry | https://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)
| Field | Type | Required | Description |
|---|---|---|---|
user_id | string | yes | The imperal_id of the acting user |
tenant_id | string | no | Defaults to "default" |
function | string | yes | The @chat.function name to invoke |
params | object | no | Function-specific parameters (defaults to {}) |
Response 200 (CallResponse)
| Field | Type | Description |
|---|---|---|
status | string | "success" or "error" |
data | any | Function-specific return payload |
summary | string or null | One-line prose for display |
error | string or null | Error message if status == "error" |
ui | any | Optional 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.
API Reference
The Imperal Cloud public REST API — auth, extensions, marketplace, billing, developer portal, and real-time events. Build on the platform without touching the web-kernel.
Auth Gateway
Reference for the Imperal Auth Gateway public API (auth.imperal.io) — identity, JWT auth, extensions, marketplace, billing, developer portal, secrets, tenants, and real-time events.