Build a UI on the catalog
The /v2 catalog routes are for building UIs that keep the whole catalog in memory, with ETag revalidation and an ids-only search. Agents and API users should use the /v1 routes.
The /v2/catalog routes are for building UIs: a web page or app that downloads the whole catalog
once, keeps it, and draws lists, filters and search results from its own copy. The looot dashboard
works this way.
Agents and API users should use the /v1 routes: GET /v1/catalog/search to find endpoints and
GET /v1/operations/{endpointId} to read one endpoint’s input and price before a run. The looot
CLI and the MCP server use them too. See GET /v1/catalog/search
in the API reference.
Which one to call
| You want to | Agent or script | UI that keeps the catalog |
|---|---|---|
| Find endpoints for a job | GET /v1/catalog/search |
GET /v2/catalog/search |
| Read one endpoint before running it | GET /v1/operations/{endpointId} |
GET /v2/catalog/inputs/{endpointId} |
| List the catalog | GET /v1/catalog/endpoints, one page at a time |
GET /v2/catalog, all of it |
Why an agent should not use /v2:
GET /v2/catalog/searchreturns ids and scores only. Without the catalog document in memory, an agent needs one more call per row to learn the price and whether it can run. EachGET /v1/catalog/searchrow already carries the price, whether you can run it now, and recent success rates.GET /v2/catalogis the whole catalog in one response, about 6 MB before compression, and it ignoreslimit.GET /v2/catalog/inputs/{endpointId}has the input schema but no price and no estimated maximum cost.GET /v1/operations/{endpointId}has both.
Sign in
Every /v2 route needs a token in the Authorization: Bearer header, like the /v1 routes. There
is no signed-out /v2; signed-out browsing uses GET /v1/public-catalog. Any customer token can read
/v2/catalog, /v2/catalog/version, /v2/catalog/search and /v2/catalog/inputs/{endpointId}.
GET /v2/catalog/inputs (every endpoint’s inputs in one call) also needs the
provider-registry:read scope. Without it you get 403 forbidden.
The catalog document
curl -si "https://api.looot.ai/v2/catalog" \
-H "Authorization: Bearer $LOOOT_TOKEN" \
-H "Accept-Encoding: gzip" --compressed
The body has schemaVersion (2), revision, builtAt, endpoints, providers, jobs,
platforms, categories and counts. Each endpoint row names its job by jobId (an entry of
jobs) and its provider by providerId (an entry of providers), so neither is repeated per row.
The document is the same for every caller. It leaves out everything that depends on your
workspace (connected, readyToRun, runnableNow, access, unavailableReason) and the live
stats and verified fields. For those, read the /v1 routes.
Keep it up to date: ETag and 304
looot rebuilds the document only when the catalog changes. There is no time expiry. Every
response carries an ETag and Cache-Control: private, no-cache, so keep the body with its ETag
and revalidate before you use it again:
curl -si "https://api.looot.ai/v2/catalog" \
-H "Authorization: Bearer $LOOOT_TOKEN" \
-H 'If-None-Match: "<the ETag you hold>"'
- 304 with an empty body: your copy is current.
- 200: a new document and a new ETag. Replace your copy.
GET /v2/catalog/version is a small check you can poll. It returns revision, builtAt and
etag. When its etag differs from the one you hold, fetch /v2/catalog again. builtAt and
etag are null while no document is built for the current revision yet.
GET /v2/catalog/inputs/{endpointId} works the same way, with its own ETag per endpoint. It
returns endpointId, inputSchema, requestBinding, examples, method, path, and
outputSchema when one is stored.
Search: ids that join onto the document
curl "https://api.looot.ai/v2/catalog/search?q=verify+an+email&limit=20" \
-H "Authorization: Bearer $LOOOT_TOKEN"
qis required, at most 500 characters.limitis 1 to 1000 (default 50).offsetis 0 to 100000 (default 0). A value out of range is a 400validation_error, not a shorter page.
The response has query, documentEtag, total, offset, nextOffset, expandedCapabilities
and items. Each item has four fields: endpointId, jobId, score, matchedBy. Look each
endpointId up in the document you hold to show its name and price.
documentEtag is the ETag of the document the search ran against. If it differs from the ETag
you hold, fetch /v2/catalog again first, or some ids may be missing from your copy.
score is 1 for the top row of the whole ranked list and falls toward 0 down the list
(1 - position/total), so a page after the first starts below 1. Sort by it descending, or keep the
order of items. It is not a relevance measure, so do not compare scores across queries. Search responses are not cached
(Cache-Control: no-store).
When no endpoint in the catalog does the job you searched for, items is empty and the response
adds unsuppliedJobs and a warnings entry with code no_supply_for_job.
While the catalog loads
Just after a deploy, a /v2 route can answer 503 with code catalog_loading (or
catalog_v2_unavailable if a build failed) and a Retry-After header in seconds. Wait that long and
retry. Errors use the same body as the rest of the REST API; see Errors.