Skip to main content

Base URL

Every request needs a credential. To get one, sign in with Google at eniac.floworks.ai/?panel=keys, create an API key, and copy it straight away: the key is shown once and never again. Send it as an Authorization: Bearer <credential> header on every call. A session token and an API key both work. An API key starts lf_live_ and a session token starts eyJ, which is the quickest way to tell which one you pasted when a call comes back 401. A request with no credential, or one that does not resolve, is refused and no search starts. Read the credential from configuration and never hardcode it.
On the /v1 routes the scheme is case-insensitive, and a bare credential with no Bearer in front of it is accepted too, so you do not have to know HTTP grammar to paste a key. The key-management routes below are stricter and need the Bearer scheme.

The endpoints

A run id is 32 lowercase hexadecimal characters. Every route is scoped to the account behind your credential: another account’s run, a run that does not exist and a malformed id all answer the same 404, so a run id is never a way to find out what another account has searched for.

API keys

A key looks like lf_live_ followed by 64 hexadecimal characters. Only a hash of it is stored, so the plaintext in the 201 response is the only copy that will ever exist. Create keys in the dashboard, or over HTTP:
These three take a session token, never an API key. It is deliberate, and it is the reason a 401 here can surprise you: a key that leaks cannot be used to mint more keys or to revoke the ones you would notice the leak with. Manage keys from a signed-in session; use keys to run searches.
Revoking a key takes effect on the next request made with it. GET /api/searches, the saved history behind the dashboard, is session-only for the same reason, so an API key cannot read somebody’s stored lead tables.

What was removed

The WebSocket at /api/runs/ws, the blocking GET /api/search, and POST /api/runs with its polling and stop routes have all been deleted. They are not deprecated; they do not answer. Each of the three ran the same engine with its own idea of billing, ownership and cancellation, and picking a different URL was a way to bypass one of them. There is one surface now, /v1/searches, and it is asynchronous: start a search with POST, then stream its events or poll the run.