Use this file to discover all available pages before exploring further.
@ghostly-io/client is the official TypeScript and JavaScript SDK for the Ghostly REST API. It wraps every API endpoint in a typed method, handles authentication headers automatically, and provides both a polling-based and an SSE-based path for consuming run results. Use it in Node.js scripts, CI pipelines, or any browser environment that can reach your Ghostly instance.
startRun(options: RunFlowOptions): Promise<RunStartResponse>Starts a run asynchronously. The API accepts the request and executes the flow in the background. Returns the run id immediately so you can poll or stream results.
waitForRun(id: string, opts?: { pollIntervalMs?: number; timeoutMs?: number }): Promise<RunRecord>Polls GET /v1/runs/:id until the run exits the "running" state. The default poll interval is 1 000 ms and the default timeout is 10 minutes.
runFlow(options: RunFlowOptions, opts?: { pollIntervalMs?: number; timeoutMs?: number }): Promise<RunRecord> — deprecatedCombines startRun + waitForRun in a single call. Preserved for backwards compatibility.
runFlow is deprecated. Prefer startRun + waitForRun for polling scenarios, or use the SSE stream for real-time progress.
planAssist(payload: PlanAssistRequest): Promise<PlanAssistResponse>Sends a natural-language goal to POST /v1/plan (v1 mode) and receives a fully structured RunFlowOptions draft ready to pass into startRun.
const plan = await client.planAssist({ project: 'my-project-id', baseUrl: 'http://localhost:3000', goal: 'Log in with user@example.com and verify the dashboard is visible',});const { id } = await client.startRun(plan.draft);
planAssistV2(payload: Omit<PlanAssistRequest, 'mode'>): Promise<PlanAssistResponse>Assisted v2 planning. Performs a live accessibility-tree recon of the baseUrl before generating the plan, producing a higher-quality initial step sequence. The response includes an observer snapshot alongside the plan draft.
const plan = await client.planAssistV2({ project: 'my-project-id', baseUrl: 'http://localhost:3000', goal: 'Complete the checkout flow and verify the order confirmation page',});console.log(plan.observer?.treeMarkdown); // accessibility tree at recon time
listRuns(project?: string): Promise<RunRecord[]>Returns all runs for the authenticated user. Pass a project ID to filter.
runEventsUrl(id: string, token: string): stringReturns the Server-Sent Events stream URL for a given run. Because EventSource does not support custom headers, the JWT token is passed as a query parameter instead.
The event type field is typed as AssistEventType — one of: recon, plan_chunk, loop_state, horizon_start, horizon_end, victory_check, memory_hit, memory_miss, step_start, step_success, step_failure, heal_start, heal_action, heal_success, heal_failure, or run_end.
The SDK exports all types needed to build fully-typed integrations.
GhostlyClientOptions
type GhostlyClientOptions = { /** Base URL of the Ghostly server (e.g. http://localhost:4000) */ baseUrl: string; /** API key generated from the Settings dashboard */ apiKey: string;};
The client sets the X-Api-Key header automatically on every request using the apiKey value you provide to the constructor. You do not need to manage headers manually.
If you need to use a JWT token instead of an API key, you can pass it as apiKey. The MCP server’s authHeader helper detects the token format automatically (JWT tokens receive an Authorization: Bearer header; plain keys receive X-Api-Key). The GhostlyClient always uses X-Api-Key regardless of format.