Romulus documentation
Local API reference
Implemented JavaScript client and HTTP endpoints for the Romulus local developer preview.
Connection and authentication
Default base URL: http://127.0.0.1:4100. Configure ROMULUS_API_TOKEN (at least 16 characters), then use npm start. ROMULUS_DB_PATH selects the SQLite file; PORT changes the local port. The package README includes exact setup commands.
All endpoints, including GET /health, require Authorization: Bearer <token>. JSON writes require application/json and are limited to 64 KiB. The API binds to 127.0.0.1 and is intended for a trusted local development environment.
JavaScript client
Import createClient from the downloaded sdk.js and supply { baseUrl, token }. client.run({ id, workflowVersion, input, leaseMs? }, async run => ...) creates or resumes a run and returns its saved final result. client.getRun(id) reads its status and step history.
Call await run.step(name, async () => output) for each sequential step. Step names must be unique and ordered consistently on restart. Inputs, outputs and final results must be JSON values. Keep effects inside step callbacks; the workflow function itself runs again during recovery.
The default run lease is 5000 ms. The client renews it while running. After a worker crash, wait for the lease to expire before restarting the same run. A live competing claim returns 409 run_busy; the SDK does not silently retry or schedule another worker.
Create or inspect a run
POST /runs accepts exactly id, workflowVersion and input. A run ID is 1–128 characters, beginning with a letter or number and using letters, numbers, dots, underscores or hyphens. workflowVersion is a 1–128 character string or nonnegative integer.
Reusing the same ID with the same input and workflow version resumes the existing record. A different input or version returns 409 run_identity_conflict. GET /runs/:id returns status, input, step names, attempts and the final result when complete.
curl --fail http://127.0.0.1:4100/runs \
-H "Authorization: Bearer $ROMULUS_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{"id":"example-1","workflowVersion":"v1","input":{"ticketId":"1042"}}'Claim and renew ownership
POST /runs/:id/claim accepts { leaseMs }, an integer between 500 and 60000. It returns claimToken and leaseExpiresAt. An unexpired claim blocks another worker.
POST /runs/:id/renew accepts { claimToken, leaseMs }. POST /runs/:id/release accepts { claimToken }. Expired or replaced claims cannot mutate progress. The SDK manages these calls for you.
Save a step
POST /runs/:id/step-start accepts { claimToken, name, position }. Positions are zero-based and sequential. A completed step returns { cached: true, output }; an unfinished step returns { cached: false }.
POST /runs/:id/step-complete accepts { claimToken, name, output }. The server validates the current owner and persists the JSON output transactionally. A completed output cannot be changed.
Complete a run
POST /runs/:id/complete accepts { claimToken, result, stepCount }. All recorded steps must be completed and the count must match. The SDK returns the stored result immediately on later calls to client.run with the same identity.
Ownership tokens fence database updates, not external services. A worker whose lease expired may still finish an external request. Give writes stable provider idempotency keys or reconcile their result before retrying.
Errors and preview limits
API errors use { error: { code, message } }. SDK API failures throw RomulusError with code and status. Invalid input returns 400, bad credentials 401, unknown runs 404, lease/identity/step conflicts 409, oversized bodies 413, and incorrect content type 415.
This preview supports sequential steps, one trusted token, local SQLite persistence and worker restart recovery. It does not provide a distributed scheduler, durable event delivery, workflow migrations, tenant isolation or external-effect guarantees. The architecture guides cover design requirements beyond this implementation.