Overview
The/startup API lets AI agents (Claude, GPT, Cursor, etc.) drive Ekso’s first-run setup wizard — the same outcome as a human filling out the wizard form, but via two anonymous JSON endpoints. After the wizard succeeds the install has its first tenant, an admin user, the auth config, and (optionally) an AI provider — ready to log into.
Self-host means the agent is operating against the customer’s own install, not a hosted ekso.app endpoint. The customer has already:
- Acquired a license — ekso.app/get-started emails a Free-tier JWT (3 users, no credit card); paid tiers with unlimited users come from ekso.app/pricing via Stripe checkout. This is its own one-shot flow today; future agent automation for this step is on the roadmap.
- Stood up the install — Docker, behind whatever DNS the customer chose (e.g.
https://ekso.acme.com). See Install.
/startup wizard with the operator’s details (name, email, password, organization, public URL) plus the license JWT. The install bootstraps the tenant and the wizard URL closes (410 Gone) on success.
Endpoints
Both endpoints are anonymous (no auth header), live on the customer’s install URL, and are gated byStartupGuard middleware — they return 410 Gone once the install has at least one tenant. There is no email-verification step: the operator running the agent has direct host access to the freshly-bootstrapped install already, so abuse-prevention is solved by network reachability rather than email round-trips.
Step 1 (optional): Validate the public URL
Before posting the wizard, the agent can sanity-check the URL the customer plans to use. Permissive — format check only:{ "error": "Invalid URL format" } / "URL must be http:// or https://" / "URL must include a host".
Step 2: Run the wizard
/api/startup/* flips to 410 Gone — the install is configured. The agent should hand the operator the install URL and the email it was bootstrapped with so they can log in.
Request fields
Error responses
All failures return a structured error body:Example agent conversation
What the wizard actually does
POST /api/startup/go delegates to the IInstallSetup workhorse, which atomically:
- Creates the install-default
DataTenantwith the supplied organization name + public URL. - Creates the admin
DataUser(super admin, hashed password). - Seeds default groups, permissions, and the forms-auth config.
- Stores the license JWT in
DataTenant.Activation(verified later byLicenseProvider). - If
aiProvideris set, writesConfigAIso the next request sees AI enabled. - Enqueues a background sample-data onboarding job to populate the tenant with example items, fields, and processes.
IInstallConfigured.MarkConfigured() flips an in-process flag that StartupGuard reads to refuse subsequent wizard calls — making the bootstrap genuinely one-shot.
Discovery
For self-host, agents can discover the install’s onboarding API through the install itself once it’s reachable:/api/startup/urland/api/startup/go— the canonical paths, documented here. Both return 410 once configured, so an agent that pings these can also detect “this install is already set up” before prompting the operator for credentials.- OpenAPI —
https://ekso.acme.com/api/openapi/v1.json(the Backend serves the same spec the public docs render). - This page —
https://ekso.dev/guide/agent-onboardingis the public-facing reference.
llms.txt and agent-card.json discovery for the SaaS-era hosted onboarding endpoints (/api/bo/on/agent/*) are gone — those endpoints were removed when the BackOfficeService deleted in Lane G of the self-host pivot. A self-host install can publish its own /.well-known/agent-card.json advertising the /api/startup/* endpoints; this is on the roadmap.