Skip to content
looot docs
Esc
↑↓navigate↵open⌘Jpreview
On this page

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/search returns 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. Each GET /v1/catalog/search row already carries the price, whether you can run it now, and recent success rates.
  • GET /v2/catalog is the whole catalog in one response, about 6 MB before compression, and it ignores limit.
  • 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"
  • q is required, at most 500 characters.
  • limit is 1 to 1000 (default 50). offset is 0 to 100000 (default 0). A value out of range is a 400 validation_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.

Was this page helpful?